mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 12:20:41 +00:00
merge servicecache branch
This commit is contained in:
@@ -1,68 +1,178 @@
|
||||
local skynet = require "skynet"
|
||||
local snax = require "snax"
|
||||
|
||||
local cmd = {}
|
||||
local service = {}
|
||||
|
||||
function cmd.LAUNCH(service_name, ...)
|
||||
local s = service[service_name]
|
||||
if type(s) == "number" then
|
||||
return s
|
||||
local function request(name, func, ...)
|
||||
local ok, handle = pcall(func, ...)
|
||||
local s = service[name]
|
||||
assert(type(s) == "table")
|
||||
if ok then
|
||||
service[name] = handle
|
||||
else
|
||||
service[name] = tostring(handle)
|
||||
end
|
||||
|
||||
if s == nil then
|
||||
s = { launch = true }
|
||||
service[service_name] = s
|
||||
elseif s.launch then
|
||||
assert(type(s) == "table")
|
||||
local co = coroutine.running()
|
||||
table.insert(s, co)
|
||||
skynet.wait()
|
||||
s = service[service_name]
|
||||
assert(type(s) == "number")
|
||||
return s
|
||||
end
|
||||
|
||||
local handle = skynet.newservice(service_name, ...)
|
||||
for _,v in ipairs(s) do
|
||||
skynet.wakeup(v)
|
||||
end
|
||||
|
||||
service[service_name] = handle
|
||||
|
||||
return handle
|
||||
if ok then
|
||||
return handle
|
||||
else
|
||||
error(tostring(handle))
|
||||
end
|
||||
end
|
||||
|
||||
function cmd.QUERY(service_name)
|
||||
local s = service[service_name]
|
||||
local function waitfor(name , func, ...)
|
||||
local s = service[name]
|
||||
if type(s) == "number" then
|
||||
return s
|
||||
end
|
||||
local co = coroutine.running()
|
||||
|
||||
if s == nil then
|
||||
s = {}
|
||||
service[service_name] = s
|
||||
service[name] = s
|
||||
elseif type(s) == "string" then
|
||||
error(s)
|
||||
end
|
||||
|
||||
assert(type(s) == "table")
|
||||
local co = coroutine.running()
|
||||
|
||||
if not s.launch and func then
|
||||
s.launch = true
|
||||
return request(name, func, ...)
|
||||
end
|
||||
|
||||
table.insert(s, co)
|
||||
skynet.wait()
|
||||
s = service[service_name]
|
||||
s = service[name]
|
||||
if type(s) == "string" then
|
||||
error(s)
|
||||
end
|
||||
assert(type(s) == "number")
|
||||
return s
|
||||
end
|
||||
|
||||
local function read_name(service_name)
|
||||
if string.byte(service_name) == 64 then -- '@'
|
||||
return string.sub(service_name , 2)
|
||||
else
|
||||
return service_name
|
||||
end
|
||||
end
|
||||
|
||||
function cmd.LAUNCH(service_name, subname, ...)
|
||||
local realname = read_name(service_name)
|
||||
|
||||
if realname == "snaxd" then
|
||||
return waitfor(service_name.."."..subname, snax.rawnewservice, subname, ...)
|
||||
else
|
||||
return waitfor(service_name, skynet.newservice, realname, subname, ...)
|
||||
end
|
||||
end
|
||||
|
||||
function cmd.QUERY(service_name, subname)
|
||||
local realname = read_name(service_name)
|
||||
|
||||
if realname == "snaxd" then
|
||||
return waitfor(service_name.."."..subname)
|
||||
else
|
||||
return waitfor(service_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function list_service()
|
||||
local result = {}
|
||||
for k,v in pairs(service) do
|
||||
if type(v) == "string" then
|
||||
v = "Error: " .. v
|
||||
elseif type(v) == "table" then
|
||||
v = "Querying"
|
||||
else
|
||||
v = skynet.address(v)
|
||||
end
|
||||
|
||||
result[k] = v
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
local function register_global()
|
||||
function cmd.GLAUNCH(name, ...)
|
||||
local global_name = "@" .. name
|
||||
return cmd.LAUNCH(global_name, ...)
|
||||
end
|
||||
|
||||
function cmd.GQUERY(name, ...)
|
||||
local global_name = "@" .. name
|
||||
return cmd.QUERY(global_name, ...)
|
||||
end
|
||||
|
||||
local mgr = {}
|
||||
|
||||
function cmd.REPORT(m)
|
||||
mgr[m] = true
|
||||
skynet.watch(m)
|
||||
end
|
||||
|
||||
local function add_list(all, m)
|
||||
local harbor = "@" .. skynet.harbor(m)
|
||||
local result = skynet.call(m, "lua", "LIST")
|
||||
for k,v in pairs(result) do
|
||||
all[k .. harbor] = v
|
||||
end
|
||||
end
|
||||
|
||||
function cmd.LIST()
|
||||
local result = {}
|
||||
for k in pairs(mgr) do
|
||||
pcall(add_list, result, k)
|
||||
end
|
||||
local l = list_service()
|
||||
for k, v in pairs(l) do
|
||||
result[k] = v
|
||||
end
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
local function register_local()
|
||||
function cmd.GLAUNCH(name, ...)
|
||||
local global_name = "@" .. name
|
||||
return waitfor(global_name, skynet.call, "SERVICE", "lua", "LAUNCH", global_name, ...)
|
||||
end
|
||||
|
||||
function cmd.GQUERY(name, ...)
|
||||
local global_name = "@" .. name
|
||||
return waitfor(global_name, skynet.call, "SERVICE", "lua", "QUERY", global_name, ...)
|
||||
end
|
||||
|
||||
function cmd.LIST()
|
||||
return list_service()
|
||||
end
|
||||
|
||||
skynet.call("SERVICE", "lua", "REPORT", skynet.self())
|
||||
end
|
||||
|
||||
skynet.start(function()
|
||||
skynet.dispatch("lua", function(session, address, command, service_name , ...)
|
||||
skynet.dispatch("lua", function(session, address, command, ...)
|
||||
local f = cmd[command]
|
||||
if f == nil then
|
||||
skynet.ret(skynet.pack(nil))
|
||||
skynet.ret(skynet.pack(nil, "Invalid command " .. command))
|
||||
return
|
||||
end
|
||||
|
||||
local ok, r = pcall(f, service_name, ...)
|
||||
local ok, r = pcall(f, ...)
|
||||
|
||||
if ok then
|
||||
skynet.ret(skynet.pack(r))
|
||||
else
|
||||
skynet.ret(skynet.pack(nil))
|
||||
skynet.ret(skynet.pack(nil, r))
|
||||
end
|
||||
end)
|
||||
local handle = skynet.localname ".service"
|
||||
@@ -72,4 +182,10 @@ skynet.start(function()
|
||||
else
|
||||
skynet.register(".service")
|
||||
end
|
||||
if skynet.getenv "standalone" then
|
||||
skynet.register("SERVICE")
|
||||
register_global()
|
||||
else
|
||||
register_local()
|
||||
end
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user