skynet.init rework, See #1322 (#1323)

* skynet.init rework, See #1322

* restore init_list #1322

* xpcall init_all, See #1322
This commit is contained in:
云风
2021-01-14 10:23:58 +08:00
committed by GitHub
parent 53a74ca029
commit 4cb84ac881
4 changed files with 63 additions and 42 deletions

View File

@@ -45,4 +45,6 @@ if LUA_PRELOAD then
LUA_PRELOAD = nil
end
_G.require = (require "skynet.require").require
main(select(2, table.unpack(args)))

View File

@@ -1,5 +1,6 @@
-- read https://github.com/cloudwu/skynet/wiki/FAQ for the module "skynet.core"
local c = require "skynet.core"
local skynet_require = require "skynet.require"
local tostring = tostring
local coroutine = coroutine
local assert = assert
@@ -925,49 +926,16 @@ do
}
end
local init_func = {}
function skynet.init(f, name)
assert(type(f) == "function")
if init_func == nil then
f()
else
tinsert(init_func, f)
if name then
assert(type(name) == "string")
assert(init_func[name] == nil)
init_func[name] = f
end
end
end
local function init_all()
local funcs = init_func
init_func = nil
if funcs then
for _,f in ipairs(funcs) do
f()
end
end
end
local function ret(f, ...)
f()
return ...
end
local function init_template(start, ...)
init_all()
init_func = {}
return ret(init_all, start(...))
end
function skynet.pcall(start, ...)
return xpcall(init_template, traceback, start, ...)
end
skynet.init = skynet_require.init
-- skynet.pcall is deprecated, use pcall directly
skynet.pcall = pcall
function skynet.init_service(start)
local ok, err = skynet.pcall(start)
local function main()
skynet_require.init_all()
start()
end
local ok, err = xpcall(main, traceback)
if not ok then
skynet.error("init service failed: " .. tostring(err))
skynet.send(".launcher","lua", "ERROR")

View File

@@ -95,6 +95,6 @@ local function init()
}
end
skynet.init(init, "multicast")
skynet.init(init)
return multicast

51
lualib/skynet/require.lua Normal file
View File

@@ -0,0 +1,51 @@
-- skynet module two-step initialize . When you require a skynet module :
-- 1. Run module main function as official lua module behavior.
-- 2. Run the functions register by skynet.init() during the step 1,
-- unless calling `require` in main thread .
-- If you call `require` in main thread ( service main function ), the functions
-- registered by skynet.init() do not execute immediately, they will be executed
-- by skynet.start() before start function.
local M = {}
local mainthread, ismain = coroutine.running()
assert(ismain, "skynet.require must initialize in main thread")
local context = {
[mainthread] = {},
}
do
local require = _G.require
function M.require(...)
local co, main = coroutine.running()
if main then
return require(...)
else
local old_init_list = context[co]
local init_list = {}
context[co] = init_list
local ret = require(...)
for _, f in ipairs(init_list) do
f()
end
context[co] = old_init_list
return ret
end
end
end
function M.init_all()
for _, f in ipairs(context[mainthread]) do
f()
end
context[mainthread] = nil
end
function M.init(f)
assert(type(f) == "function")
local co = coroutine.running()
table.insert(context[co], f)
end
return M