123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- 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)
|