mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
add skynet.response for delay response
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
Dev version
|
||||||
|
-----------
|
||||||
|
* add sharedata
|
||||||
|
* bugfix: service exit before init would not report back
|
||||||
|
* add skynet.response and check multicall skynet.ret
|
||||||
|
* skynet.newservice throw error when lanuch faild
|
||||||
|
|
||||||
v0.5.0 (2014-7-28)
|
v0.5.0 (2014-7-28)
|
||||||
-----------
|
-----------
|
||||||
* skynet.exit will quit service immediately.
|
* skynet.exit will quit service immediately.
|
||||||
|
|||||||
@@ -299,6 +299,26 @@ lpackstring(lua_State *L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ltrash(lua_State *L) {
|
||||||
|
int t = lua_type(L,1);
|
||||||
|
switch (t) {
|
||||||
|
case LUA_TSTRING: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LUA_TLIGHTUSERDATA: {
|
||||||
|
void * msg = lua_touserdata(L,1);
|
||||||
|
luaL_checkinteger(L,2);
|
||||||
|
skynet_free(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
luaL_error(L, "skynet.trash invalid param %s", lua_typename(L,t));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
luaopen_skynet_c(lua_State *L) {
|
luaopen_skynet_c(lua_State *L) {
|
||||||
luaL_checkversion(L);
|
luaL_checkversion(L);
|
||||||
@@ -314,6 +334,7 @@ luaopen_skynet_c(lua_State *L) {
|
|||||||
{ "pack", _luaseri_pack },
|
{ "pack", _luaseri_pack },
|
||||||
{ "unpack", _luaseri_unpack },
|
{ "unpack", _luaseri_unpack },
|
||||||
{ "packstring", lpackstring },
|
{ "packstring", lpackstring },
|
||||||
|
{ "trash" , ltrash },
|
||||||
{ "callback", _callback },
|
{ "callback", _callback },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ local function monitor(name, obj, cobj)
|
|||||||
while true do
|
while true do
|
||||||
newobj = skynet.call(service, "lua", "monitor", name, newobj)
|
newobj = skynet.call(service, "lua", "monitor", name, newobj)
|
||||||
if newobj == nil then
|
if newobj == nil then
|
||||||
return
|
break
|
||||||
end
|
end
|
||||||
sd.update(obj, newobj)
|
sd.update(obj, newobj)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -43,12 +43,14 @@ end
|
|||||||
local session_id_coroutine = {}
|
local session_id_coroutine = {}
|
||||||
local session_coroutine_id = {}
|
local session_coroutine_id = {}
|
||||||
local session_coroutine_address = {}
|
local session_coroutine_address = {}
|
||||||
|
local session_response = {}
|
||||||
|
|
||||||
local wakeup_session = {}
|
local wakeup_session = {}
|
||||||
local sleep_session = {}
|
local sleep_session = {}
|
||||||
|
|
||||||
local watching_service = {}
|
local watching_service = {}
|
||||||
local watching_session = {}
|
local watching_session = {}
|
||||||
|
local dead_service = {}
|
||||||
local error_queue = {}
|
local error_queue = {}
|
||||||
|
|
||||||
-- suspend is function
|
-- suspend is function
|
||||||
@@ -73,7 +75,9 @@ local function _error_dispatch(error_session, error_source)
|
|||||||
if error_session == 0 then
|
if error_session == 0 then
|
||||||
-- service is down
|
-- service is down
|
||||||
-- Don't remove from watching_service , because user may call dead service
|
-- Don't remove from watching_service , because user may call dead service
|
||||||
watching_service[error_source] = false
|
if watching_service[error_source] then
|
||||||
|
dead_service[error_source] = true
|
||||||
|
end
|
||||||
for session, srv in pairs(watching_session) do
|
for session, srv in pairs(watching_session) do
|
||||||
if srv == error_source then
|
if srv == error_source then
|
||||||
table.insert(error_queue, session)
|
table.insert(error_queue, session)
|
||||||
@@ -122,6 +126,18 @@ local function dispatch_wakeup()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function release_watching(address)
|
||||||
|
local ref = watching_service[address]
|
||||||
|
if ref then
|
||||||
|
ref = ref - 1
|
||||||
|
if ref > 0 then
|
||||||
|
watching_service[address] = ref
|
||||||
|
else
|
||||||
|
watching_service[address] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- suspend is local function
|
-- suspend is local function
|
||||||
function suspend(co, result, command, param, size)
|
function suspend(co, result, command, param, size)
|
||||||
if not result then
|
if not result then
|
||||||
@@ -142,15 +158,50 @@ function suspend(co, result, command, param, size)
|
|||||||
elseif command == "RETURN" then
|
elseif command == "RETURN" then
|
||||||
local co_session = session_coroutine_id[co]
|
local co_session = session_coroutine_id[co]
|
||||||
local co_address = session_coroutine_address[co]
|
local co_address = session_coroutine_address[co]
|
||||||
if param == nil then
|
if param == nil or session_response[co] then
|
||||||
error(debug.traceback(co))
|
error(debug.traceback(co))
|
||||||
end
|
end
|
||||||
c.send(co_address, skynet.PTYPE_RESPONSE, co_session, param, size)
|
session_response[co] = true
|
||||||
return suspend(co, coroutine.resume(co))
|
local ret
|
||||||
|
if not dead_service[co_address] then
|
||||||
|
ret = c.send(co_address, skynet.PTYPE_RESPONSE, co_session, param, size) >= 0
|
||||||
|
elseif size == nil then
|
||||||
|
c.trash(param, size)
|
||||||
|
ret = false
|
||||||
|
end
|
||||||
|
return suspend(co, coroutine.resume(co, ret))
|
||||||
|
elseif command == "RESPONSE" then
|
||||||
|
local co_session = session_coroutine_id[co]
|
||||||
|
local co_address = session_coroutine_address[co]
|
||||||
|
if session_response[co] then
|
||||||
|
error(debug.traceback(co))
|
||||||
|
end
|
||||||
|
local f = param
|
||||||
|
local function response(ok, ...)
|
||||||
|
local ret
|
||||||
|
if not dead_service[co_address] then
|
||||||
|
if ok then
|
||||||
|
ret = c.send(co_address, skynet.PTYPE_RESPONSE, co_session, f(...)) >=0
|
||||||
|
else
|
||||||
|
ret = c.send(co_address, skynet.PTYPE_ERROR, co_session, "") >=0
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ret = false
|
||||||
|
end
|
||||||
|
release_watching(co_address)
|
||||||
|
f = nil
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
watching_service[co_address] = watching_service[co_address] + 1
|
||||||
|
session_response[co] = response
|
||||||
|
return suspend(co, coroutine.resume(co, response))
|
||||||
elseif command == "EXIT" then
|
elseif command == "EXIT" then
|
||||||
-- coroutine exit
|
-- coroutine exit
|
||||||
|
local address = session_coroutine_address[co]
|
||||||
|
release_watching(address)
|
||||||
session_coroutine_id[co] = nil
|
session_coroutine_id[co] = nil
|
||||||
session_coroutine_address[co] = nil
|
session_coroutine_address[co] = nil
|
||||||
|
session_response[co] = nil
|
||||||
elseif command == "QUIT" then
|
elseif command == "QUIT" then
|
||||||
-- service exit
|
-- service exit
|
||||||
return
|
return
|
||||||
@@ -259,13 +310,21 @@ end
|
|||||||
|
|
||||||
function skynet.exit()
|
function skynet.exit()
|
||||||
skynet.send(".launcher","lua","REMOVE",skynet.self())
|
skynet.send(".launcher","lua","REMOVE",skynet.self())
|
||||||
|
-- report the sources that call me
|
||||||
for co, session in pairs(session_coroutine_id) do
|
for co, session in pairs(session_coroutine_id) do
|
||||||
local address = session_coroutine_address[co]
|
local address = session_coroutine_address[co]
|
||||||
local self = skynet.self()
|
|
||||||
if session~=0 and address then
|
if session~=0 and address then
|
||||||
skynet.redirect(address, self, "error", session, "")
|
c.redirect(address, 0, skynet.PTYPE_ERROR, session, "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- report the sources I call but haven't return
|
||||||
|
local tmp = {}
|
||||||
|
for session, address in pairs(watching_session) do
|
||||||
|
tmp[address] = true
|
||||||
|
end
|
||||||
|
for address in pairs(tmp) do
|
||||||
|
c.redirect(address, 0, skynet.PTYPE_ERROR, 0, "")
|
||||||
|
end
|
||||||
c.command("EXIT")
|
c.command("EXIT")
|
||||||
-- quit service
|
-- quit service
|
||||||
coroutine_yield "QUIT"
|
coroutine_yield "QUIT"
|
||||||
@@ -294,9 +353,6 @@ end
|
|||||||
|
|
||||||
function skynet.send(addr, typename, ...)
|
function skynet.send(addr, typename, ...)
|
||||||
local p = proto[typename]
|
local p = proto[typename]
|
||||||
if watching_service[addr] == false then
|
|
||||||
error("Service is dead")
|
|
||||||
end
|
|
||||||
return c.send(addr, p.id, 0 , p.pack(...))
|
return c.send(addr, p.id, 0 , p.pack(...))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -321,9 +377,6 @@ end
|
|||||||
|
|
||||||
function skynet.call(addr, typename, ...)
|
function skynet.call(addr, typename, ...)
|
||||||
local p = proto[typename]
|
local p = proto[typename]
|
||||||
if watching_service[addr] == false then
|
|
||||||
error("Service is dead")
|
|
||||||
end
|
|
||||||
local session = c.send(addr, p.id , nil , p.pack(...))
|
local session = c.send(addr, p.id , nil , p.pack(...))
|
||||||
if session == nil then
|
if session == nil then
|
||||||
error("call to invalid address " .. skynet.address(addr))
|
error("call to invalid address " .. skynet.address(addr))
|
||||||
@@ -333,16 +386,18 @@ end
|
|||||||
|
|
||||||
function skynet.rawcall(addr, typename, msg, sz)
|
function skynet.rawcall(addr, typename, msg, sz)
|
||||||
local p = proto[typename]
|
local p = proto[typename]
|
||||||
if watching_service[addr] == false then
|
|
||||||
error("Service is dead")
|
|
||||||
end
|
|
||||||
local session = assert(c.send(addr, p.id , nil , msg, sz), "call to invalid address")
|
local session = assert(c.send(addr, p.id , nil , msg, sz), "call to invalid address")
|
||||||
return yield_call(addr, session)
|
return yield_call(addr, session)
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.ret(msg, sz)
|
function skynet.ret(msg, sz)
|
||||||
msg = msg or ""
|
msg = msg or ""
|
||||||
coroutine_yield("RETURN", msg, sz)
|
return coroutine_yield("RETURN", msg, sz)
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.response(pack)
|
||||||
|
pack = pack or skynet.pack
|
||||||
|
return coroutine_yield("RESPONSE", pack)
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.retpack(...)
|
function skynet.retpack(...)
|
||||||
@@ -412,6 +467,12 @@ local function raw_dispatch_message(prototype, msg, sz, session, source, ...)
|
|||||||
local p = assert(proto[prototype], prototype)
|
local p = assert(proto[prototype], prototype)
|
||||||
local f = p.dispatch
|
local f = p.dispatch
|
||||||
if f then
|
if f then
|
||||||
|
local ref = watching_service[source]
|
||||||
|
if ref then
|
||||||
|
watching_service[source] = ref + 1
|
||||||
|
else
|
||||||
|
watching_service[source] = 1
|
||||||
|
end
|
||||||
local co = co_create(f)
|
local co = co_create(f)
|
||||||
session_coroutine_id[co] = session
|
session_coroutine_id[co] = session
|
||||||
session_coroutine_address[co] = source
|
session_coroutine_address[co] = source
|
||||||
|
|||||||
@@ -13,31 +13,31 @@ skynet.start(function()
|
|||||||
standalone = true
|
standalone = true
|
||||||
skynet.setenv("standalone", "true")
|
skynet.setenv("standalone", "true")
|
||||||
|
|
||||||
local slave = skynet.newservice "cdummy"
|
local ok, slave = pcall(skynet.newservice, "cdummy")
|
||||||
if slave == nil then
|
if not ok then
|
||||||
skynet.abort()
|
skynet.abort()
|
||||||
end
|
end
|
||||||
skynet.name(".slave", slave)
|
skynet.name(".slave", slave)
|
||||||
|
|
||||||
else
|
else
|
||||||
if standalone then
|
if standalone then
|
||||||
if not skynet.newservice "cmaster" then
|
if not pcall(skynet.newservice,"cmaster") then
|
||||||
skynet.abort()
|
skynet.abort()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local slave = skynet.newservice "cslave"
|
local ok, slave = pcall(skynet.newservice, "cslave")
|
||||||
if slave == nil then
|
if not ok then
|
||||||
skynet.abort()
|
skynet.abort()
|
||||||
end
|
end
|
||||||
skynet.name(".slave", slave)
|
skynet.name(".slave", slave)
|
||||||
end
|
end
|
||||||
|
|
||||||
if standalone then
|
if standalone then
|
||||||
local datacenter = assert(skynet.newservice "datacenterd")
|
local datacenter = skynet.newservice "datacenterd"
|
||||||
skynet.name("DATACENTER", datacenter)
|
skynet.name("DATACENTER", datacenter)
|
||||||
end
|
end
|
||||||
assert(skynet.newservice "service_mgr")
|
skynet.newservice "service_mgr"
|
||||||
assert(skynet.newservice(skynet.getenv "start" or "main"))
|
pcall(skynet.newservice,skynet.getenv "start" or "main")
|
||||||
skynet.exit()
|
skynet.exit()
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ local function console_main_loop()
|
|||||||
while true do
|
while true do
|
||||||
local cmdline = socket.readline(stdin, "\n")
|
local cmdline = socket.readline(stdin, "\n")
|
||||||
if cmdline ~= "" then
|
if cmdline ~= "" then
|
||||||
local handle = skynet.newservice(cmdline)
|
pcall(skynet.newservice,cmdline)
|
||||||
if handle == nil then
|
|
||||||
print("Launch error:",cmdline)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
socket.unlock(stdin)
|
socket.unlock(stdin)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ local function monitor_clear(id)
|
|||||||
if v then
|
if v then
|
||||||
monitor[id] = nil
|
monitor[id] = nil
|
||||||
for _, v in ipairs(v) do
|
for _, v in ipairs(v) do
|
||||||
skynet.redirect(v.address, 0, "response", v.session, "")
|
v()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -149,30 +149,30 @@ local function monitor_harbor(master_fd)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function harbor.REGISTER(_,_, fd, name, handle)
|
function harbor.REGISTER(fd, name, handle)
|
||||||
assert(globalname[name] == nil)
|
assert(globalname[name] == nil)
|
||||||
globalname[name] = handle
|
globalname[name] = handle
|
||||||
socket.write(fd, pack_package("R", name, handle))
|
socket.write(fd, pack_package("R", name, handle))
|
||||||
skynet.redirect(harbor_service, handle, "harbor", 0, "N " .. name)
|
skynet.redirect(harbor_service, handle, "harbor", 0, "N " .. name)
|
||||||
end
|
end
|
||||||
|
|
||||||
function harbor.LINK(session, source, fd, id)
|
function harbor.LINK(fd, id)
|
||||||
if slaves[id] then
|
if slaves[id] then
|
||||||
if monitor[id] == nil then
|
if monitor[id] == nil then
|
||||||
monitor[id] = {}
|
monitor[id] = {}
|
||||||
end
|
end
|
||||||
table.insert(monitor[id], { address = source, session = session })
|
table.insert(monitor[id], skynet.response(true))
|
||||||
else
|
else
|
||||||
skynet.ret()
|
skynet.ret()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function harbor.CONNECT(session, source, fd, id)
|
function harbor.CONNECT(fd, id)
|
||||||
if not slaves[id] then
|
if not slaves[id] then
|
||||||
if monitor[id] == nil then
|
if monitor[id] == nil then
|
||||||
monitor[id] = {}
|
monitor[id] = {}
|
||||||
end
|
end
|
||||||
table.insert(monitor[id], { address = source, session = session })
|
table.insert(monitor[id], skynet.response(true))
|
||||||
else
|
else
|
||||||
skynet.ret()
|
skynet.ret()
|
||||||
end
|
end
|
||||||
@@ -186,9 +186,9 @@ skynet.start(function()
|
|||||||
skynet.error("slave connect to master " .. tostring(master_addr))
|
skynet.error("slave connect to master " .. tostring(master_addr))
|
||||||
local master_fd = socket.open(master_addr)
|
local master_fd = socket.open(master_addr)
|
||||||
|
|
||||||
skynet.dispatch("lua", function (session,source,command,...)
|
skynet.dispatch("lua", function (_,_,command,...)
|
||||||
local f = assert(harbor[command])
|
local f = assert(harbor[command])
|
||||||
f(session, source, master_fd, ...)
|
f(master_fd, ...)
|
||||||
end)
|
end)
|
||||||
skynet.dispatch("text", monitor_harbor(master_fd))
|
skynet.dispatch("text", monitor_harbor(master_fd))
|
||||||
|
|
||||||
|
|||||||
@@ -45,10 +45,8 @@ local function wakeup(db, key1, key2, value, ...)
|
|||||||
db[key1] = nil
|
db[key1] = nil
|
||||||
if value then
|
if value then
|
||||||
-- throw error because can't wake up a branch
|
-- throw error because can't wake up a branch
|
||||||
for _,v in ipairs(q) do
|
for _,response in ipairs(q) do
|
||||||
local session = v[1]
|
response(false)
|
||||||
local source = v[2]
|
|
||||||
skynet.redirect(source, 0, "error", session, "")
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return q
|
return q
|
||||||
@@ -66,15 +64,13 @@ function command.UPDATE(...)
|
|||||||
end
|
end
|
||||||
local q = wakeup(wait_queue, ...)
|
local q = wakeup(wait_queue, ...)
|
||||||
if q then
|
if q then
|
||||||
for _, v in ipairs(q) do
|
for _, response in ipairs(q) do
|
||||||
local session = v[1]
|
response(true,value)
|
||||||
local source = v[2]
|
|
||||||
skynet.redirect(source, 0, "response", session, skynet.pack(value))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function waitfor(session, source, db, key1, key2, ...)
|
local function waitfor(db, key1, key2, ...)
|
||||||
if key2 == nil then
|
if key2 == nil then
|
||||||
-- push queue
|
-- push queue
|
||||||
local q = db[key1]
|
local q = db[key1]
|
||||||
@@ -84,7 +80,7 @@ local function waitfor(session, source, db, key1, key2, ...)
|
|||||||
else
|
else
|
||||||
assert(q[mode] == "queue")
|
assert(q[mode] == "queue")
|
||||||
end
|
end
|
||||||
table.insert(q, { session, source })
|
table.insert(q, skynet.response())
|
||||||
else
|
else
|
||||||
local q = db[key1]
|
local q = db[key1]
|
||||||
if q == nil then
|
if q == nil then
|
||||||
@@ -93,18 +89,18 @@ local function waitfor(session, source, db, key1, key2, ...)
|
|||||||
else
|
else
|
||||||
assert(q[mode] == "branch")
|
assert(q[mode] == "branch")
|
||||||
end
|
end
|
||||||
return waitfor(session, source, q, key2, ...)
|
return waitfor(q, key2, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
skynet.dispatch("lua", function (session, source, cmd, ...)
|
skynet.dispatch("lua", function (_, _, cmd, ...)
|
||||||
if cmd == "WAIT" then
|
if cmd == "WAIT" then
|
||||||
local ret = command.QUERY(...)
|
local ret = command.QUERY(...)
|
||||||
if ret then
|
if ret then
|
||||||
skynet.ret(skynet.pack(ret))
|
skynet.ret(skynet.pack(ret))
|
||||||
else
|
else
|
||||||
waitfor(session, source, wait_queue, ...)
|
waitfor(wait_queue, ...)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local f = assert(command[cmd])
|
local f = assert(command[cmd])
|
||||||
|
|||||||
@@ -122,8 +122,8 @@ function COMMAND.clearcache()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.start(...)
|
function COMMAND.start(...)
|
||||||
local addr = skynet.newservice(...)
|
local ok, addr = pcall(skynet.newservice, ...)
|
||||||
if addr then
|
if ok then
|
||||||
return { [skynet.address(addr)] = ... }
|
return { [skynet.address(addr)] = ... }
|
||||||
else
|
else
|
||||||
return "Failed"
|
return "Failed"
|
||||||
@@ -131,8 +131,8 @@ function COMMAND.start(...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function COMMAND.snax(...)
|
function COMMAND.snax(...)
|
||||||
local s = snax.newservice(...)
|
local ok, s = pcall(snax.newservice, ...)
|
||||||
if s then
|
if ok then
|
||||||
local addr = s.handle
|
local addr = s.handle
|
||||||
return { [skynet.address(addr)] = ... }
|
return { [skynet.address(addr)] = ... }
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ function command.STAT()
|
|||||||
return list
|
return list
|
||||||
end
|
end
|
||||||
|
|
||||||
function command.INFO(_, _, handle)
|
function command.INFO(_, handle)
|
||||||
handle = handle_to_address(handle)
|
handle = handle_to_address(handle)
|
||||||
if services[handle] == nil then
|
if services[handle] == nil then
|
||||||
return
|
return
|
||||||
@@ -38,7 +38,7 @@ function command.INFO(_, _, handle)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function command.TASK(_, _, handle)
|
function command.TASK(_, handle)
|
||||||
handle = handle_to_address(handle)
|
handle = handle_to_address(handle)
|
||||||
if services[handle] == nil then
|
if services[handle] == nil then
|
||||||
return
|
return
|
||||||
@@ -48,7 +48,7 @@ function command.TASK(_, _, handle)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function command.KILL(_, _, handle)
|
function command.KILL(_, handle)
|
||||||
handle = handle_to_address(handle)
|
handle = handle_to_address(handle)
|
||||||
skynet.kill(handle)
|
skynet.kill(handle)
|
||||||
local ret = { [skynet.address(handle)] = tostring(services[handle]) }
|
local ret = { [skynet.address(handle)] = tostring(services[handle]) }
|
||||||
@@ -72,18 +72,29 @@ function command.GC()
|
|||||||
return command.MEM()
|
return command.MEM()
|
||||||
end
|
end
|
||||||
|
|
||||||
function command.REMOVE(_,_, handle)
|
function command.REMOVE(_, handle)
|
||||||
services[handle] = nil
|
services[handle] = nil
|
||||||
|
local response = instance[handle]
|
||||||
|
if response then
|
||||||
|
-- instance is dead
|
||||||
|
response(false)
|
||||||
|
instance[handle] = nil
|
||||||
|
end
|
||||||
|
|
||||||
-- don't return (skynet.ret) because the handle may exit
|
-- don't return (skynet.ret) because the handle may exit
|
||||||
return NORET
|
return NORET
|
||||||
end
|
end
|
||||||
|
|
||||||
function command.LAUNCH(address, session, service, ...)
|
local function return_string(str)
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
function command.LAUNCH(_, service, ...)
|
||||||
local param = table.concat({...}, " ")
|
local param = table.concat({...}, " ")
|
||||||
local inst = skynet.launch(service, param)
|
local inst = skynet.launch(service, param)
|
||||||
if inst then
|
if inst then
|
||||||
services[inst] = service .. " " .. param
|
services[inst] = service .. " " .. param
|
||||||
instance[inst] = { session = session, address = address }
|
instance[inst] = skynet.response(return_string)
|
||||||
else
|
else
|
||||||
skynet.ret("") -- launch failed
|
skynet.ret("") -- launch failed
|
||||||
end
|
end
|
||||||
@@ -93,9 +104,9 @@ end
|
|||||||
function command.ERROR(address)
|
function command.ERROR(address)
|
||||||
-- see serivce-src/service_lua.c
|
-- see serivce-src/service_lua.c
|
||||||
-- init failed
|
-- init failed
|
||||||
local reply = instance[address]
|
local response = instance[address]
|
||||||
if reply then
|
if response then
|
||||||
skynet.redirect(reply.address , 0, "response", reply.session, "")
|
response(false)
|
||||||
instance[address] = nil
|
instance[address] = nil
|
||||||
end
|
end
|
||||||
services[address] = nil
|
services[address] = nil
|
||||||
@@ -104,9 +115,9 @@ end
|
|||||||
|
|
||||||
function command.LAUNCHOK(address)
|
function command.LAUNCHOK(address)
|
||||||
-- init notice
|
-- init notice
|
||||||
local reply = instance[address]
|
local response = instance[address]
|
||||||
if reply then
|
if response then
|
||||||
skynet.redirect(reply.address , 0, "response", reply.session, skynet.address(address))
|
response(true, skynet.address(address))
|
||||||
instance[address] = nil
|
instance[address] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -127,7 +138,7 @@ skynet.register_protocol {
|
|||||||
else
|
else
|
||||||
-- launch request
|
-- launch request
|
||||||
local service, param = string.match(cmd,"([^ ]+) (.*)")
|
local service, param = string.match(cmd,"([^ ]+) (.*)")
|
||||||
command.LAUNCH(address, session, service, param)
|
command.LAUNCH(_, service, param)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
@@ -136,7 +147,7 @@ skynet.dispatch("lua", function(session, address, cmd , ...)
|
|||||||
cmd = string.upper(cmd)
|
cmd = string.upper(cmd)
|
||||||
local f = command[cmd]
|
local f = command[cmd]
|
||||||
if f then
|
if f then
|
||||||
local ret = f(address, session, ...)
|
local ret = f(address, ...)
|
||||||
if ret ~= NORET then
|
if ret ~= NORET then
|
||||||
skynet.ret(skynet.pack(ret))
|
skynet.ret(skynet.pack(ret))
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -55,10 +55,8 @@ function CMD.delete(name)
|
|||||||
assert(objmap[v.obj])
|
assert(objmap[v.obj])
|
||||||
objmap[v.obj] = true
|
objmap[v.obj] = true
|
||||||
sharedata.host.decref(v.obj)
|
sharedata.host.decref(v.obj)
|
||||||
for _,v in ipairs(v.watch) do
|
for _,response in ipairs(v.watch) do
|
||||||
local session = v[1]
|
response(true)
|
||||||
local address = v[2]
|
|
||||||
skynet.redirect(address, 0, "response", session, skynet.pack(nil))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -90,21 +88,19 @@ function CMD.update(name, t)
|
|||||||
local newobj = pool[name].obj
|
local newobj = pool[name].obj
|
||||||
if watch then
|
if watch then
|
||||||
sharedata.host.markdirty(oldcobj)
|
sharedata.host.markdirty(oldcobj)
|
||||||
for _,v in ipairs(watch) do
|
for _,response in ipairs(watch) do
|
||||||
local session = v[1]
|
response(true, newobj)
|
||||||
local address = v[2]
|
|
||||||
skynet.redirect(address, 0, "response", session, skynet.pack(newobj))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function CMD.monitor(session, address, name, obj)
|
function CMD.monitor(name, obj)
|
||||||
local v = assert(pool[name])
|
local v = assert(pool[name])
|
||||||
if obj ~= v.obj then
|
if obj ~= v.obj then
|
||||||
return v.obj
|
return v.obj
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(v.watch, { session, address })
|
table.insert(v.watch, skynet.response())
|
||||||
|
|
||||||
return NORET
|
return NORET
|
||||||
end
|
end
|
||||||
@@ -113,12 +109,7 @@ skynet.start(function()
|
|||||||
skynet.fork(collectobj)
|
skynet.fork(collectobj)
|
||||||
skynet.dispatch("lua", function (session, source ,cmd, ...)
|
skynet.dispatch("lua", function (session, source ,cmd, ...)
|
||||||
local f = assert(CMD[cmd])
|
local f = assert(CMD[cmd])
|
||||||
local r
|
local r = f(...)
|
||||||
if cmd == "monitor" then
|
|
||||||
r = f(session, source, ...)
|
|
||||||
else
|
|
||||||
r = f(...)
|
|
||||||
end
|
|
||||||
if r ~= NORET then
|
if r ~= NORET then
|
||||||
skynet.ret(skynet.pack(r))
|
skynet.ret(skynet.pack(r))
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
local skynet = require "skynet"
|
|
||||||
|
|
||||||
skynet.start(function()
|
|
||||||
local ping = skynet.newservice("pingserver")
|
|
||||||
skynet.timeout(0,function()
|
|
||||||
print(skynet.call(ping,"lua","PING","ping"))
|
|
||||||
end)
|
|
||||||
|
|
||||||
print(skynet.blockcall(ping,"lua","HELLO"))
|
|
||||||
end)
|
|
||||||
@@ -11,6 +11,15 @@ skynet.start(function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
elseif mode == "dead" then
|
||||||
|
|
||||||
|
skynet.start(function()
|
||||||
|
skynet.dispatch("lua", function (...)
|
||||||
|
skynet.sleep(100)
|
||||||
|
print("return", skynet.ret "")
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
@@ -20,6 +29,9 @@ else
|
|||||||
skynet.call(test,"lua", "dead call")
|
skynet.call(test,"lua", "dead call")
|
||||||
end))
|
end))
|
||||||
|
|
||||||
skynet.exit()
|
local dead = skynet.newservice(SERVICE_NAME, "dead") -- launch self in dead mode
|
||||||
|
|
||||||
|
skynet.timeout(0, skynet.exit) -- exit after a while, so the call never return
|
||||||
|
skynet.call(dead, "lua", "whould not return")
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
Reference in New Issue
Block a user