mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
add skynet.service
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
root = "./"
|
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"
|
lualoader = root .. "lualib/loader.lua"
|
||||||
lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"
|
lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"
|
||||||
lua_cpath = root .. "luaclib/?.so"
|
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