optimize global unique service query

This commit is contained in:
Cloud Wu
2014-04-19 16:47:52 +08:00
parent c577a4f07d
commit 2d56a2215a
2 changed files with 70 additions and 45 deletions

View File

@@ -410,26 +410,12 @@ function skynet.newservice(name, ...)
end
end
function skynet.uniqueservice(global, ...)
local handle
if global == true then
handle = skynet.call("SERVICE", "lua", "LAUNCH", ...)
else
handle = skynet.call(".service", "lua", "LAUNCH", global, ...)
end
assert(handle , "Unique service launch failed")
return handle
function skynet.uniqueservice(...)
return assert(skynet.call(".service", "lua", "LAUNCH", ...))
end
function skynet.queryservice(global, ...)
local handle
if global == true then
handle = skynet.call("SERVICE", "lua", "QUERY", ...)
else
handle = skynet.call(".service", "lua", "QUERY", global, ...)
end
assert(handle , "Unique service query failed")
return handle
function skynet.queryservice(global, name)
return assert(skynet.call(".service", "lua", "QUERY", global, name))
end
local function group_command(cmd, handle, address)

View File

@@ -3,53 +3,91 @@ local skynet = require "skynet"
local cmd = {}
local service = {}
function cmd.LAUNCH(service_name, ...)
local s = service[service_name]
if type(s) == "number" then
return s
end
local GLOBAL = false
if s == nil then
s = { launch = true }
service[service_name] = s
elseif s.launch then
local function request(name, func, ...)
local ok, handle = pcall(func, ...)
local s = service[name]
assert(type(s) == "table")
local co = coroutine.running()
table.insert(s, co)
skynet.wait()
s = service[service_name]
assert(type(s) == "number")
return s
if ok then
service[name] = handle
else
service[name] = tostring(handle)
end
local handle = skynet.newservice(service_name, ...)
for _,v in ipairs(s) do
skynet.wakeup(v)
end
service[service_name] = 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 GQUERY(service_name)
if GLOBAL then
return cmd.QUERY(service_name)
else
return waitfor(service_name, skynet.call, "SERVICE", "lua", "QUERY", service_name)
end
end
local function GLAUNCH(service_name, ...)
if GLOBAL then
return cmd.LAUNCH(service_name, ...)
else
return waitfor(service_name, skynet.call, "SERVICE", "lua", "LAUNCH", service_name, ...)
end
end
function cmd.LAUNCH(global, service_name, ...)
if global == true then
return GLAUNCH(service_name, ...)
else
return waitfor(global, skynet.newservice, global, service_name, ...)
end
end
function cmd.QUERY(global, service_name)
if global == true then
return GQUERY(service_name)
end
return waitfor(global)
end
skynet.start(function()
skynet.dispatch("lua", function(session, address, command, service_name , ...)
local f = cmd[command]
@@ -62,11 +100,12 @@ skynet.start(function()
if ok then
skynet.ret(skynet.pack(r))
else
skynet.ret(skynet.pack(nil))
skynet.ret(skynet.pack(nil, r))
end
end)
skynet.register(".service")
if skynet.getenv "standalone" then
GLOBAL = true
skynet.register("SERVICE")
end
end)