From 2d56a2215a102330771e75bd31d4eb1b5794d608 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Sat, 19 Apr 2014 16:47:52 +0800 Subject: [PATCH] optimize global unique service query --- lualib/skynet.lua | 22 ++-------- service/service_mgr.lua | 93 +++++++++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 45 deletions(-) diff --git a/lualib/skynet.lua b/lualib/skynet.lua index 139a5b29..77d9ab12 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -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) diff --git a/service/service_mgr.lua b/service/service_mgr.lua index 7f771f3f..44d85d5b 100644 --- a/service/service_mgr.lua +++ b/service/service_mgr.lua @@ -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 +local GLOBAL = false + +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 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)