You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
2.4 KiB
Lua
127 lines
2.4 KiB
Lua
local skynet = require "skynet"
|
|
|
|
local provider = {}
|
|
|
|
local function new_service(svr, name)
|
|
local s = {}
|
|
svr[name] = s
|
|
s.queue = {}
|
|
return s
|
|
end
|
|
|
|
local svr = setmetatable({}, { __index = new_service })
|
|
|
|
|
|
function provider.query(name)
|
|
local s = svr[name]
|
|
if s.queue then
|
|
table.insert(s.queue, skynet.response())
|
|
else
|
|
if s.address then
|
|
return skynet.ret(skynet.pack(s.address))
|
|
else
|
|
error(s.error)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function boot(addr, name, code, ...)
|
|
local s = svr[name]
|
|
skynet.call(addr, "lua", "init", code, ...)
|
|
local tmp = table.pack( ... )
|
|
for i=1,tmp.n do
|
|
tmp[i] = tostring(tmp[i])
|
|
end
|
|
|
|
if tmp.n > 0 then
|
|
s.init = table.concat(tmp, ",")
|
|
end
|
|
s.time = skynet.time()
|
|
end
|
|
|
|
function provider.launch(name, code, ...)
|
|
local s = svr[name]
|
|
if s.address then
|
|
return skynet.ret(skynet.pack(s.address))
|
|
end
|
|
if s.booting then
|
|
table.insert(s.queue, skynet.response())
|
|
else
|
|
s.booting = true
|
|
local err
|
|
local ok, addr = pcall(skynet.newservice,"service_cell", name)
|
|
if ok then
|
|
ok, err = xpcall(boot, debug.traceback, addr, name, code, ...)
|
|
else
|
|
err = addr
|
|
addr = nil
|
|
end
|
|
s.booting = nil
|
|
if ok then
|
|
s.address = addr
|
|
for _, resp in ipairs(s.queue) do
|
|
resp(true, addr)
|
|
end
|
|
s.queue = nil
|
|
skynet.ret(skynet.pack(addr))
|
|
else
|
|
if addr then
|
|
skynet.send(addr, "debug", "EXIT")
|
|
end
|
|
s.error = err
|
|
for _, resp in ipairs(s.queue) do
|
|
resp(false)
|
|
end
|
|
s.queue = nil
|
|
error(err)
|
|
end
|
|
end
|
|
end
|
|
|
|
function provider.test(name)
|
|
local s = svr[name]
|
|
if s.booting then
|
|
skynet.ret(skynet.pack(nil, true)) -- booting
|
|
elseif s.address then
|
|
skynet.ret(skynet.pack(s.address))
|
|
elseif s.error then
|
|
error(s.error)
|
|
else
|
|
skynet.ret() -- nil
|
|
end
|
|
end
|
|
|
|
function provider.close(name)
|
|
local s = svr[name]
|
|
if not s or s.booting then
|
|
return skynet.ret(skynet.pack(nil))
|
|
end
|
|
|
|
svr[name] = nil
|
|
skynet.ret(skynet.pack(s.address))
|
|
end
|
|
|
|
skynet.start(function()
|
|
skynet.dispatch("lua", function(session, address, cmd, ...)
|
|
provider[cmd](...)
|
|
end)
|
|
skynet.info_func(function()
|
|
local info = {}
|
|
for k,v in pairs(svr) do
|
|
local status
|
|
if v.booting then
|
|
status = "booting"
|
|
elseif v.queue then
|
|
status = "waiting(" .. #v.queue .. ")"
|
|
end
|
|
info[skynet.address(v.address)] = {
|
|
init = v.init,
|
|
name = k,
|
|
time = os.date("%Y %b %d %T %z",math.floor(v.time)),
|
|
status = status,
|
|
}
|
|
end
|
|
return info
|
|
end)
|
|
end)
|