mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 12:20:41 +00:00
add skynet.service
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
root = "./"
|
||||
luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua"
|
||||
luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua;"..root.."test/?/init.lua"
|
||||
lualoader = root .. "lualib/loader.lua"
|
||||
lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"
|
||||
lua_cpath = root .. "luaclib/?.so"
|
||||
|
||||
43
lualib/skynet/service.lua
Normal file
43
lualib/skynet/service.lua
Normal file
@@ -0,0 +1,43 @@
|
||||
local skynet = require "skynet"
|
||||
|
||||
local service = {}
|
||||
local cache = {}
|
||||
local provider
|
||||
|
||||
local function get_provider()
|
||||
provider = provider or skynet.uniqueservice "service_provider"
|
||||
return provider
|
||||
end
|
||||
|
||||
local function check(func)
|
||||
local info = debug.getinfo(func, "u")
|
||||
assert(info.nups == 1)
|
||||
assert(debug.getupvalue(func,1) == "_ENV")
|
||||
end
|
||||
|
||||
function service.new(name, mainfunc, ...)
|
||||
local p = get_provider()
|
||||
local addr, booting = skynet.call(p, "lua", "test", name)
|
||||
if addr then
|
||||
service.address = addr
|
||||
else
|
||||
if booting then
|
||||
service.address = skynet.call(p, "lua", "query", name)
|
||||
else
|
||||
check(mainfunc)
|
||||
local code = string.dump(mainfunc)
|
||||
service.address = skynet.call(p, "lua", "launch", name, code, ...)
|
||||
end
|
||||
end
|
||||
cache[name] = service.address
|
||||
return service.address
|
||||
end
|
||||
|
||||
function service.query(name)
|
||||
if not cache[name] then
|
||||
cache[name] = skynet.call(get_provider(), "lua", "query", name)
|
||||
end
|
||||
return cache[name]
|
||||
end
|
||||
|
||||
return service
|
||||
113
service/service_provider.lua
Normal file
113
service/service_provider.lua
Normal file
@@ -0,0 +1,113 @@
|
||||
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.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
|
||||
|
||||
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)
|
||||
7
test/testservice/init.lua
Normal file
7
test/testservice/init.lua
Normal file
@@ -0,0 +1,7 @@
|
||||
local skynet = require "skynet"
|
||||
local kvdb = require "kvdb"
|
||||
|
||||
skynet.start(function()
|
||||
kvdb.set("A", 1)
|
||||
print(kvdb.get "A")
|
||||
end)
|
||||
43
test/testservice/kvdb.lua
Normal file
43
test/testservice/kvdb.lua
Normal file
@@ -0,0 +1,43 @@
|
||||
local skynet = require "skynet"
|
||||
local service = require "skynet.service"
|
||||
|
||||
local kvdb = {}
|
||||
|
||||
-- service.address is the default address registered by itself.
|
||||
function kvdb.get(key)
|
||||
return skynet.call(service.address, "lua", "get", key)
|
||||
end
|
||||
|
||||
function kvdb.set(key, value)
|
||||
skynet.call(service.address, "lua", "set", key , value)
|
||||
end
|
||||
|
||||
-- this function will be injected into an unique service, so don't refer any upvalues
|
||||
local function service_mainfunc(...)
|
||||
local skynet = require "skynet"
|
||||
|
||||
skynet.error(...) -- (...) passed from service.new
|
||||
|
||||
local db = {}
|
||||
|
||||
local command = {}
|
||||
|
||||
function command.get(key)
|
||||
return db[key]
|
||||
end
|
||||
|
||||
function command.set(key, value)
|
||||
db[key] = value
|
||||
end
|
||||
|
||||
-- skynet.start is compatible
|
||||
skynet.dispatch("lua", function(session, address, cmd, ...)
|
||||
skynet.ret(skynet.pack(command[cmd](...)))
|
||||
end)
|
||||
end
|
||||
|
||||
skynet.init(function()
|
||||
service.new("kvdb", service_mainfunc, "Service Init")
|
||||
end)
|
||||
|
||||
return kvdb
|
||||
Reference in New Issue
Block a user