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

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)