From bd52c5fece258e2ee444e7c99101fd0e9e1068e2 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Thu, 14 Aug 2014 17:03:09 +0800 Subject: [PATCH] bugfix: socketchannel connect once --- HISTORY.md | 1 + lualib/socketchannel.lua | 40 +++++++++++++++++++++++++--------------- service/clusterd.lua | 15 +++++++++++++-- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index af2d93c9..60609957 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -12,6 +12,7 @@ Dev version * add cluster.proxy * add DEBUG command exit (send a message to lua service by DEBUG) * add DEBUG command run (debug_console command inject) +* bugfix : socketchannel connect once v0.5.2 (2014-8-11) ----------- diff --git a/lualib/socketchannel.lua b/lualib/socketchannel.lua index 89f1f1ec..1086cd79 100644 --- a/lualib/socketchannel.lua +++ b/lualib/socketchannel.lua @@ -218,9 +218,9 @@ local function try_connect(self , once) if not once then skynet.error("socket: connect to", self.__host, self.__port) end - return + return true elseif once then - error(string.format("Connect to %s:%d failed", self.__host, self.__port)) + return false end if t > 1000 then skynet.error("socket: try to reconnect", self.__host, self.__port) @@ -233,7 +233,7 @@ local function try_connect(self , once) end end -local function block_connect(self, once) +local function check_connection(self) if self.__sock then local authco = self.__authcoroutine if not authco then @@ -247,26 +247,36 @@ local function block_connect(self, once) if self.__closed then return false end +end + +local function block_connect(self, once) + local r = check_connection(self) + if r ~= nil then + return r + end if #self.__connecting > 0 then -- connecting in other coroutine local co = coroutine.running() table.insert(self.__connecting, co) skynet.wait() - -- check connection again - return block_connect(self, once) - end - self.__connecting[1] = true - try_connect(self, once) - self.__connecting[1] = nil - for i=2, #self.__connecting do - local co = self.__connecting[i] - self.__connecting[i] = nil - skynet.wakeup(co) + else + self.__connecting[1] = true + try_connect(self, once) + self.__connecting[1] = nil + for i=2, #self.__connecting do + local co = self.__connecting[i] + self.__connecting[i] = nil + skynet.wakeup(co) + end end - -- check again - return block_connect(self, once) + r = check_connection(self) + if r == nil then + error(string.format("Connect to %s:%d failed", self.__host, self.__port)) + else + return r + end end function channel:connect(once) diff --git a/service/clusterd.lua b/service/clusterd.lua index 23fa5b0f..677f84fa 100644 --- a/service/clusterd.lua +++ b/service/clusterd.lua @@ -51,13 +51,24 @@ function command.listen(source, addr, port) skynet.ret(skynet.pack(nil)) end -function command.req(source, node, addr, msg, sz) +local function send_request(source, node, addr, msg, sz) local request local c = node_channel[node] local session = node_session[node] -- msg is a local pointer, cluster.packrequest will free it request, node_session[node] = cluster.packrequest(addr, session , msg, sz) - skynet.ret(c:request(request, session)) + + return c:request(request, session) +end + +function command.req(...) + local ok, msg, sz = pcall(send_request, ...) + if ok then + skynet.ret(msg, sz) + else + skynet.error(msg) + skynet.response()(false) + end end local proxy = {}