From 1e0189962be9d40afae7299d880b2f7247183217 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Mon, 30 Jun 2014 11:31:24 +0800 Subject: [PATCH 1/7] bugfix: dead lock when service_harbor exit --- service-src/service_harbor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/service-src/service_harbor.c b/service-src/service_harbor.c index f7a88f2b..36b2789c 100644 --- a/service-src/service_harbor.c +++ b/service-src/service_harbor.c @@ -262,7 +262,8 @@ harbor_release(struct harbor *h) { struct slave *s = &h->s[i]; if (s->fd && s->status != STATUS_DOWN) { close_harbor(h,i); - report_harbor_down(h,i); + // don't call report_harbor_down. + // never call skynet_send during module exit, because of dead lock } } hash_delete(h->map); From 711c04e6a94ce599fbb4afca55010c9621e694a9 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Thu, 3 Jul 2014 17:13:47 +0800 Subject: [PATCH 2/7] bugfix: redirect should pass session (0) --- examples/simplemonitor.lua | 2 +- lualib/skynet.lua | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/simplemonitor.lua b/examples/simplemonitor.lua index 1528bb50..ec294d21 100644 --- a/examples/simplemonitor.lua +++ b/examples/simplemonitor.lua @@ -12,7 +12,7 @@ skynet.register_protocol { local w = service_map[address] if w then for watcher in pairs(w) do - skynet.redirect(watcher, address, "error", "") + skynet.redirect(watcher, address, "error", 0, "") end service_map[address] = false end diff --git a/lualib/skynet.lua b/lualib/skynet.lua index 2019f530..e2e274af 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -569,6 +569,7 @@ function skynet.monitor(service, query) end assert(monitor, "Monitor launch failed") c.command("MONITOR", string.format(":%08x", monitor)) + return monitor end function skynet.mqlen() From f874fdc61877869919225b615f5d761dcce72bff Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Thu, 3 Jul 2014 17:40:07 +0800 Subject: [PATCH 3/7] throw error when skynet.exit --- HISTORY.md | 5 +++++ lualib/loader.lua | 4 +++- lualib/skynet.lua | 7 +++++++ test/testdeadcall.lua | 2 +- test/testmulticast.lua | 2 +- 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 3f4d5d9d..650cee24 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +Dev version +----------- +* add SERVICE_NAME in loader +* throw error back when skynet.error + v0.4.0 (2014-6-30) ----------- * Optimize redis driver `compose_message`. diff --git a/lualib/loader.lua b/lualib/loader.lua index 05224b92..1c4ee58a 100644 --- a/lualib/loader.lua +++ b/lualib/loader.lua @@ -3,11 +3,13 @@ for word in string.gmatch(..., "%S+") do table.insert(args, word) end +SERVICE_NAME = args[1] + local main, pattern local err = {} for pat in string.gmatch(LUA_SERVICE, "([^;]+);*") do - local filename = string.gsub(pat, "?", args[1]) + local filename = string.gsub(pat, "?", SERVICE_NAME) local f, msg = loadfile(filename) if not f then table.insert(err, msg) diff --git a/lualib/skynet.lua b/lualib/skynet.lua index e2e274af..7719d2ae 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -253,6 +253,13 @@ end function skynet.exit() skynet.send(".launcher","lua","REMOVE",skynet.self()) + for co, session in pairs(session_coroutine_id) do + local address = session_coroutine_address[co] + local self = skynet.self() + if session~=0 and address then + skynet.redirect(self, address, "error", session, "") + end + end c.command("EXIT") end diff --git a/test/testdeadcall.lua b/test/testdeadcall.lua index d348a411..c5d67b8c 100644 --- a/test/testdeadcall.lua +++ b/test/testdeadcall.lua @@ -14,7 +14,7 @@ end) else skynet.start(function() - local test = skynet.newservice("testdeadcall", "test") -- launch self in test mode + local test = skynet.newservice(SERVICE_NAME, "test") -- launch self in test mode print(pcall(function() skynet.send(test,"lua", "hello world") diff --git a/test/testmulticast.lua b/test/testmulticast.lua index 88f79ccb..8f084abf 100644 --- a/test/testmulticast.lua +++ b/test/testmulticast.lua @@ -27,7 +27,7 @@ skynet.start(function() local channel = mc.new() print("New channel", channel) for i=1,10 do - local sub = skynet.newservice("testmulticast", "sub") + local sub = skynet.newservice(SERVICE_NAME, "sub") skynet.call(sub, "lua", "init", channel.channel) end From ece89a1b4965114fab75d6d7ab070a5d2fed679b Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Mon, 7 Jul 2014 18:29:27 +0800 Subject: [PATCH 4/7] add new api skynet.task() --- lualib/skynet.lua | 11 +++++++++++ lualib/skynet/debug.lua | 7 +++++++ service/debug_console.lua | 1 + service/launcher.lua | 10 ++++++++++ 4 files changed, 29 insertions(+) diff --git a/lualib/skynet.lua b/lualib/skynet.lua index 7719d2ae..7e5115cb 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -583,6 +583,17 @@ function skynet.mqlen() return tonumber(c.command "MQLEN") end +function skynet.task(f) + local t = 0 + for _,co in pairs(session_id_coroutine) do + if f then + f(debug.traceback(co)) + end + t = t + 1 + end + return t +end + -- Inject internal debug framework local debug = require "skynet.debug" debug(skynet) diff --git a/lualib/skynet/debug.lua b/lualib/skynet/debug.lua index 807ee2ae..bb5877fe 100644 --- a/lualib/skynet/debug.lua +++ b/lualib/skynet/debug.lua @@ -21,9 +21,16 @@ end function dbgcmd.STAT() local stat = {} stat.mqlen = skynet.mqlen() + stat.task = skynet.task() skynet.ret(skynet.pack(stat)) end +function dbgcmd.TASK() + local task = {} + skynet.task(function(info) table.insert(task, info) end) + skynet.ret(skynet.pack(task)) +end + function dbgcmd.INFO() if internal_info_func then skynet.ret(skynet.pack(internal_info_func())) diff --git a/service/debug_console.lua b/service/debug_console.lua index b15c3889..a587f69d 100644 --- a/service/debug_console.lua +++ b/service/debug_console.lua @@ -113,6 +113,7 @@ function COMMAND.help() snax = "lanuch a new snax service", clearcache = "clear lua code cache", service = "List unique service", + task = "task address : show service task detail", } end diff --git a/service/launcher.lua b/service/launcher.lua index b80eadc9..5c1c1a8b 100644 --- a/service/launcher.lua +++ b/service/launcher.lua @@ -38,6 +38,16 @@ function command.INFO(_, _, handle) end end +function command.TASK(_, _, handle) + handle = handle_to_address(handle) + if services[handle] == nil then + return + else + local result = skynet.call(handle,"debug","TASK") + return result + end +end + function command.KILL(_, _, handle) handle = handle_to_address(handle) skynet.kill(handle) From 4967dc2fce7ee3f7b0dac14ab6231f975924e2a8 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Mon, 7 Jul 2014 19:00:22 +0800 Subject: [PATCH 5/7] skynet.task return session:traceback --- lualib/skynet.lua | 8 ++++---- lualib/skynet/debug.lua | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lualib/skynet.lua b/lualib/skynet.lua index 7e5115cb..f9d934c3 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -583,11 +583,11 @@ function skynet.mqlen() return tonumber(c.command "MQLEN") end -function skynet.task(f) +function skynet.task(ret) local t = 0 - for _,co in pairs(session_id_coroutine) do - if f then - f(debug.traceback(co)) + for session,co in pairs(session_id_coroutine) do + if ret then + ret[session] = debug.traceback(co) end t = t + 1 end diff --git a/lualib/skynet/debug.lua b/lualib/skynet/debug.lua index bb5877fe..c8f51f0b 100644 --- a/lualib/skynet/debug.lua +++ b/lualib/skynet/debug.lua @@ -27,7 +27,7 @@ end function dbgcmd.TASK() local task = {} - skynet.task(function(info) table.insert(task, info) end) + skynet.task(task) skynet.ret(skynet.pack(task)) end From 54f4d94ba2187fdf58244bce43c69c4f0f1dc049 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Mon, 7 Jul 2014 19:50:31 +0800 Subject: [PATCH 6/7] bugfix: create queue first --- service-src/service_harbor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/service-src/service_harbor.c b/service-src/service_harbor.c index 36b2789c..fbb6406d 100644 --- a/service-src/service_harbor.c +++ b/service-src/service_harbor.c @@ -510,6 +510,9 @@ remote_send_handle(struct harbor *h, uint32_t source, uint32_t destination, int skynet_send(context, destination, source, PTYPE_ERROR, 0 , NULL, 0); skynet_error(context, "Drop message to harbor %d from %x to %x (session = %d, msgsz = %d)",harbor_id, source, destination,session,(int)sz); } else { + if (s->queue == NULL) { + s->queue = new_queue(); + } struct remote_message_header header; header.source = source; header.destination = type << HANDLE_REMOTE_SHIFT; From 8f8b844bdec65abf996dd780399084f16ca1a1d6 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Mon, 7 Jul 2014 20:52:34 +0800 Subject: [PATCH 7/7] ready for release --- HISTORY.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 650cee24..0ca75332 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,9 @@ -Dev version +v0.4.1 (2014-7-7) ----------- -* add SERVICE_NAME in loader -* throw error back when skynet.error +* Add SERVICE_NAME in loader +* Throw error back when skynet.error +* Add skynet.task +* Bugfix for last version (harbor service bugs) v0.4.0 (2014-6-30) -----------