-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
According to the documentation here: https://github.com/openresty/lua-nginx-module#coroutinecreate
coroutine.create
can be used in init_by_lua*, header_filter_by_lua*, body_filter_by_lua*,
because OpenResty would replace OpenResty's coroutine with the Lua native coroutine in these phases, which can not yield.
code:
lua-nginx-module/src/ngx_http_lua_coroutine.c
Lines 336 to 375 in d34d3c5
{ | |
const char buf[] = | |
"local keys = {'create', 'yield', 'resume', 'status', 'wrap'}\n" | |
#ifdef OPENRESTY_LUAJIT | |
"local get_req = require 'thread.exdata'\n" | |
#else | |
"local getfenv = getfenv\n" | |
#endif | |
"for _, key in ipairs(keys) do\n" | |
"local std = coroutine['_' .. key]\n" | |
"local ours = coroutine['__' .. key]\n" | |
"local raw_ctx = ngx._phase_ctx\n" | |
"coroutine[key] = function (...)\n" | |
#ifdef OPENRESTY_LUAJIT | |
"local r = get_req()\n" | |
#else | |
"local r = getfenv(0).__ngx_req\n" | |
#endif | |
"if r ~= nil then\n" | |
#ifdef OPENRESTY_LUAJIT | |
"local ctx = raw_ctx()\n" | |
#else | |
"local ctx = raw_ctx(r)\n" | |
#endif | |
/* ignore header and body filters */ | |
"if ctx ~= 0x020 and ctx ~= 0x040 then\n" | |
"return ours(...)\n" | |
"end\n" | |
"end\n" | |
"return std(...)\n" | |
"end\n" | |
"end\n" | |
"package.loaded.coroutine = coroutine" | |
#if 0 | |
"debug.sethook(function () collectgarbage() end, 'rl', 1)" | |
#endif | |
; | |
rc = luaL_loadbuffer(L, buf, sizeof(buf) - 1, "=coroutine_api"); | |
} |
And also here: https://github.com/openresty/lua-resty-core/blob/master/lib/resty/core/coroutine.lua#L4-L24
Now the problem is: If I call coroutine.create
in init_worker
phase, match the
if ctx ~= 0x020 and ctx ~= 0x040 then
return ours(...)
end
And then return the OpenResty's coroutine. (ctx
of init_worker
is 0x0100
)
This would cause ean rror API disabled in the context of init_worker_by_lua*
because check here:
lua-nginx-module/src/ngx_http_lua_coroutine.c
Line 117 in d34d3c5
ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_YIELDABLE); |
So I suggest returning the Lua native coroutine in the init_worker
phase, change like
if ctx ~= 0x020 and ctx ~= 0x040 and ctx ~= 0x0100 then
return ours(...)
end
This may allow users to use native Lua coroutine in init_worker
phase.