mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
Improve socketchannel, try the next host in backup list when auth failed. See issue #1145
This commit is contained in:
@@ -112,38 +112,15 @@ local function mongo_auth(mongoc)
|
|||||||
mongoc.__sock:changebackup(backup)
|
mongoc.__sock:changebackup(backup)
|
||||||
end
|
end
|
||||||
if rs_data.ismaster then
|
if rs_data.ismaster then
|
||||||
if rawget(mongoc, "__pickserver") then
|
|
||||||
rawset(mongoc, "__pickserver", nil)
|
|
||||||
end
|
|
||||||
return
|
return
|
||||||
else
|
elseif rs_data.primary then
|
||||||
if rs_data.primary then
|
|
||||||
local host, port = __parse_addr(rs_data.primary)
|
local host, port = __parse_addr(rs_data.primary)
|
||||||
mongoc.host = host
|
mongoc.host = host
|
||||||
mongoc.port = port
|
mongoc.port = port
|
||||||
mongoc.__sock:changehost(host, port)
|
mongoc.__sock:changehost(host, port)
|
||||||
else
|
else
|
||||||
skynet.error("WARNING: NO PRIMARY RETURN " .. rs_data.me)
|
-- socketchannel would try the next host in backup list
|
||||||
-- determine the primary db using hosts
|
error ("No primary return : " .. tostring(rs_data.me))
|
||||||
local pickserver = {}
|
|
||||||
if rawget(mongoc, "__pickserver") == nil then
|
|
||||||
for _, v in ipairs(rs_data.hosts) do
|
|
||||||
if v ~= rs_data.me then
|
|
||||||
table.insert(pickserver, v)
|
|
||||||
end
|
|
||||||
rawset(mongoc, "__pickserver", pickserver)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if #mongoc.__pickserver <= 0 then
|
|
||||||
error("CAN NOT DETERMINE THE PRIMARY DB")
|
|
||||||
end
|
|
||||||
skynet.error("INFO: TRY TO CONNECT " .. mongoc.__pickserver[1])
|
|
||||||
local host, port = __parse_addr(mongoc.__pickserver[1])
|
|
||||||
table.remove(mongoc.__pickserver, 1)
|
|
||||||
mongoc.host = host
|
|
||||||
mongoc.port = port
|
|
||||||
mongoc.__sock:changehost(host, port)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -201,27 +201,6 @@ local function dispatch_function(self)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function connect_backup(self)
|
|
||||||
if self.__backup then
|
|
||||||
for _, addr in ipairs(self.__backup) do
|
|
||||||
local host, port
|
|
||||||
if type(addr) == "table" then
|
|
||||||
host, port = addr.host, addr.port
|
|
||||||
else
|
|
||||||
host = addr
|
|
||||||
port = self.__port
|
|
||||||
end
|
|
||||||
skynet.error("socket: connect to backup host", host, port)
|
|
||||||
local fd = socket.open(host, port)
|
|
||||||
if fd then
|
|
||||||
self.__host = host
|
|
||||||
self.__port = port
|
|
||||||
return fd
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function term_dispatch_thread(self)
|
local function term_dispatch_thread(self)
|
||||||
if not self.__response and self.__dispatch_thread then
|
if not self.__response and self.__dispatch_thread then
|
||||||
-- dispatch by order, send close signal to dispatch thread
|
-- dispatch by order, send close signal to dispatch thread
|
||||||
@@ -233,17 +212,57 @@ local function connect_once(self)
|
|||||||
if self.__closed then
|
if self.__closed then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local addr_list = {}
|
||||||
|
local addr_set = {}
|
||||||
|
|
||||||
|
local function _add_backup()
|
||||||
|
if self.__backup then
|
||||||
|
for _, addr in ipairs(self.__backup) do
|
||||||
|
local host, port
|
||||||
|
if type(addr) == "table" then
|
||||||
|
host,port = addr.host, addr.port
|
||||||
|
else
|
||||||
|
host = addr
|
||||||
|
port = self.__port
|
||||||
|
end
|
||||||
|
|
||||||
|
-- don't add the same host
|
||||||
|
local hostkey = host..":"..port
|
||||||
|
if not addr_set[hostkey] then
|
||||||
|
addr_set[hostkey] = true
|
||||||
|
table.insert(addr_list, { host = host, port = port })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _next_addr()
|
||||||
|
local addr = table.remove(addr_list,1)
|
||||||
|
if addr then
|
||||||
|
skynet.error("socket: connect to backup host", addr.host, addr.port)
|
||||||
|
end
|
||||||
|
return addr
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _connect_once(self, addr)
|
||||||
|
local fd,err = socket.open(addr.host, addr.port)
|
||||||
|
if not fd then
|
||||||
|
-- try next one
|
||||||
|
addr = _next_addr()
|
||||||
|
if addr == nil then
|
||||||
|
return false, err
|
||||||
|
end
|
||||||
|
return _connect_once(self, addr)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.__host = addr.host
|
||||||
|
self.__port = addr.port
|
||||||
|
|
||||||
assert(not self.__sock and not self.__authcoroutine)
|
assert(not self.__sock and not self.__authcoroutine)
|
||||||
-- term current dispatch thread (send a signal)
|
-- term current dispatch thread (send a signal)
|
||||||
term_dispatch_thread(self)
|
term_dispatch_thread(self)
|
||||||
|
|
||||||
local fd,err = socket.open(self.__host, self.__port)
|
|
||||||
if not fd then
|
|
||||||
fd = connect_backup(self)
|
|
||||||
if not fd then
|
|
||||||
return false, err
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if self.__nodelay then
|
if self.__nodelay then
|
||||||
socketdriver.nodelay(fd)
|
socketdriver.nodelay(fd)
|
||||||
end
|
end
|
||||||
@@ -297,14 +316,28 @@ local function connect_once(self)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.__authcoroutine = false
|
self.__authcoroutine = false
|
||||||
if ok and not self.__sock then
|
if ok then
|
||||||
|
if not self.__sock then
|
||||||
-- auth may change host, so connect again
|
-- auth may change host, so connect again
|
||||||
return connect_once(self)
|
return connect_once(self)
|
||||||
end
|
end
|
||||||
return ok
|
-- auth succ, go through
|
||||||
|
else
|
||||||
|
-- auth failed, try next addr
|
||||||
|
_add_backup() -- auth may add new backup hosts
|
||||||
|
addr = _next_addr()
|
||||||
|
if addr == nil then
|
||||||
|
return false, "no more backup host"
|
||||||
|
end
|
||||||
|
return _connect_once(self, addr)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
_add_backup()
|
||||||
|
return _connect_once(self, { host = self.__host, port = self.__port })
|
||||||
end
|
end
|
||||||
|
|
||||||
local function try_connect(self , once)
|
local function try_connect(self , once)
|
||||||
|
|||||||
Reference in New Issue
Block a user