add skynet.response for delay response

This commit is contained in:
Cloud Wu
2014-07-30 12:10:30 +08:00
parent c78466b486
commit ce5adba5b2
13 changed files with 182 additions and 96 deletions

View File

@@ -13,31 +13,31 @@ skynet.start(function()
standalone = true
skynet.setenv("standalone", "true")
local slave = skynet.newservice "cdummy"
if slave == nil then
local ok, slave = pcall(skynet.newservice, "cdummy")
if not ok then
skynet.abort()
end
skynet.name(".slave", slave)
else
if standalone then
if not skynet.newservice "cmaster" then
if not pcall(skynet.newservice,"cmaster") then
skynet.abort()
end
end
local slave = skynet.newservice "cslave"
if slave == nil then
local ok, slave = pcall(skynet.newservice, "cslave")
if not ok then
skynet.abort()
end
skynet.name(".slave", slave)
end
if standalone then
local datacenter = assert(skynet.newservice "datacenterd")
local datacenter = skynet.newservice "datacenterd"
skynet.name("DATACENTER", datacenter)
end
assert(skynet.newservice "service_mgr")
assert(skynet.newservice(skynet.getenv "start" or "main"))
skynet.newservice "service_mgr"
pcall(skynet.newservice,skynet.getenv "start" or "main")
skynet.exit()
end)

View File

@@ -7,10 +7,7 @@ local function console_main_loop()
while true do
local cmdline = socket.readline(stdin, "\n")
if cmdline ~= "" then
local handle = skynet.newservice(cmdline)
if handle == nil then
print("Launch error:",cmdline)
end
pcall(skynet.newservice,cmdline)
end
end
socket.unlock(stdin)

View File

@@ -28,7 +28,7 @@ local function monitor_clear(id)
if v then
monitor[id] = nil
for _, v in ipairs(v) do
skynet.redirect(v.address, 0, "response", v.session, "")
v()
end
end
end
@@ -149,30 +149,30 @@ local function monitor_harbor(master_fd)
end
end
function harbor.REGISTER(_,_, fd, name, handle)
function harbor.REGISTER(fd, name, handle)
assert(globalname[name] == nil)
globalname[name] = handle
socket.write(fd, pack_package("R", name, handle))
skynet.redirect(harbor_service, handle, "harbor", 0, "N " .. name)
end
function harbor.LINK(session, source, fd, id)
function harbor.LINK(fd, id)
if slaves[id] then
if monitor[id] == nil then
monitor[id] = {}
end
table.insert(monitor[id], { address = source, session = session })
table.insert(monitor[id], skynet.response(true))
else
skynet.ret()
end
end
function harbor.CONNECT(session, source, fd, id)
function harbor.CONNECT(fd, id)
if not slaves[id] then
if monitor[id] == nil then
monitor[id] = {}
end
table.insert(monitor[id], { address = source, session = session })
table.insert(monitor[id], skynet.response(true))
else
skynet.ret()
end
@@ -186,9 +186,9 @@ skynet.start(function()
skynet.error("slave connect to master " .. tostring(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])
f(session, source, master_fd, ...)
f(master_fd, ...)
end)
skynet.dispatch("text", monitor_harbor(master_fd))

View File

@@ -45,10 +45,8 @@ local function wakeup(db, key1, key2, value, ...)
db[key1] = nil
if value then
-- throw error because can't wake up a branch
for _,v in ipairs(q) do
local session = v[1]
local source = v[2]
skynet.redirect(source, 0, "error", session, "")
for _,response in ipairs(q) do
response(false)
end
else
return q
@@ -66,15 +64,13 @@ function command.UPDATE(...)
end
local q = wakeup(wait_queue, ...)
if q then
for _, v in ipairs(q) do
local session = v[1]
local source = v[2]
skynet.redirect(source, 0, "response", session, skynet.pack(value))
for _, response in ipairs(q) do
response(true,value)
end
end
end
local function waitfor(session, source, db, key1, key2, ...)
local function waitfor(db, key1, key2, ...)
if key2 == nil then
-- push queue
local q = db[key1]
@@ -84,7 +80,7 @@ local function waitfor(session, source, db, key1, key2, ...)
else
assert(q[mode] == "queue")
end
table.insert(q, { session, source })
table.insert(q, skynet.response())
else
local q = db[key1]
if q == nil then
@@ -93,18 +89,18 @@ local function waitfor(session, source, db, key1, key2, ...)
else
assert(q[mode] == "branch")
end
return waitfor(session, source, q, key2, ...)
return waitfor(q, key2, ...)
end
end
skynet.start(function()
skynet.dispatch("lua", function (session, source, cmd, ...)
skynet.dispatch("lua", function (_, _, cmd, ...)
if cmd == "WAIT" then
local ret = command.QUERY(...)
if ret then
skynet.ret(skynet.pack(ret))
else
waitfor(session, source, wait_queue, ...)
waitfor(wait_queue, ...)
end
else
local f = assert(command[cmd])

View File

@@ -122,8 +122,8 @@ function COMMAND.clearcache()
end
function COMMAND.start(...)
local addr = skynet.newservice(...)
if addr then
local ok, addr = pcall(skynet.newservice, ...)
if ok then
return { [skynet.address(addr)] = ... }
else
return "Failed"
@@ -131,8 +131,8 @@ function COMMAND.start(...)
end
function COMMAND.snax(...)
local s = snax.newservice(...)
if s then
local ok, s = pcall(snax.newservice, ...)
if ok then
local addr = s.handle
return { [skynet.address(addr)] = ... }
else

View File

@@ -28,7 +28,7 @@ function command.STAT()
return list
end
function command.INFO(_, _, handle)
function command.INFO(_, handle)
handle = handle_to_address(handle)
if services[handle] == nil then
return
@@ -38,7 +38,7 @@ function command.INFO(_, _, handle)
end
end
function command.TASK(_, _, handle)
function command.TASK(_, handle)
handle = handle_to_address(handle)
if services[handle] == nil then
return
@@ -48,7 +48,7 @@ function command.TASK(_, _, handle)
end
end
function command.KILL(_, _, handle)
function command.KILL(_, handle)
handle = handle_to_address(handle)
skynet.kill(handle)
local ret = { [skynet.address(handle)] = tostring(services[handle]) }
@@ -72,18 +72,29 @@ function command.GC()
return command.MEM()
end
function command.REMOVE(_,_, handle)
function command.REMOVE(_, handle)
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
return NORET
end
function command.LAUNCH(address, session, service, ...)
local function return_string(str)
return str
end
function command.LAUNCH(_, service, ...)
local param = table.concat({...}, " ")
local inst = skynet.launch(service, param)
if inst then
services[inst] = service .. " " .. param
instance[inst] = { session = session, address = address }
instance[inst] = skynet.response(return_string)
else
skynet.ret("") -- launch failed
end
@@ -93,9 +104,9 @@ end
function command.ERROR(address)
-- see serivce-src/service_lua.c
-- init failed
local reply = instance[address]
if reply then
skynet.redirect(reply.address , 0, "response", reply.session, "")
local response = instance[address]
if response then
response(false)
instance[address] = nil
end
services[address] = nil
@@ -104,9 +115,9 @@ end
function command.LAUNCHOK(address)
-- init notice
local reply = instance[address]
if reply then
skynet.redirect(reply.address , 0, "response", reply.session, skynet.address(address))
local response = instance[address]
if response then
response(true, skynet.address(address))
instance[address] = nil
end
@@ -127,7 +138,7 @@ skynet.register_protocol {
else
-- launch request
local service, param = string.match(cmd,"([^ ]+) (.*)")
command.LAUNCH(address, session, service, param)
command.LAUNCH(_, service, param)
end
end,
}
@@ -136,7 +147,7 @@ skynet.dispatch("lua", function(session, address, cmd , ...)
cmd = string.upper(cmd)
local f = command[cmd]
if f then
local ret = f(address, session, ...)
local ret = f(address, ...)
if ret ~= NORET then
skynet.ret(skynet.pack(ret))
end

View File

@@ -55,10 +55,8 @@ function CMD.delete(name)
assert(objmap[v.obj])
objmap[v.obj] = true
sharedata.host.decref(v.obj)
for _,v in ipairs(v.watch) do
local session = v[1]
local address = v[2]
skynet.redirect(address, 0, "response", session, skynet.pack(nil))
for _,response in ipairs(v.watch) do
response(true)
end
end
@@ -90,21 +88,19 @@ function CMD.update(name, t)
local newobj = pool[name].obj
if watch then
sharedata.host.markdirty(oldcobj)
for _,v in ipairs(watch) do
local session = v[1]
local address = v[2]
skynet.redirect(address, 0, "response", session, skynet.pack(newobj))
for _,response in ipairs(watch) do
response(true, newobj)
end
end
end
function CMD.monitor(session, address, name, obj)
function CMD.monitor(name, obj)
local v = assert(pool[name])
if obj ~= v.obj then
return v.obj
end
table.insert(v.watch, { session, address })
table.insert(v.watch, skynet.response())
return NORET
end
@@ -113,12 +109,7 @@ skynet.start(function()
skynet.fork(collectobj)
skynet.dispatch("lua", function (session, source ,cmd, ...)
local f = assert(CMD[cmd])
local r
if cmd == "monitor" then
r = f(session, source, ...)
else
r = f(...)
end
local r = f(...)
if r ~= NORET then
skynet.ret(skynet.pack(r))
end