mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
Merge branch 'mongors' into dev
This commit is contained in:
@@ -75,22 +75,51 @@ local function dispatch_reply(so)
|
|||||||
return reply_id, succ, result
|
return reply_id, succ, result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function __parse_addr(addr)
|
||||||
|
local host, port = string.match(addr, "([^:]+):(.+)")
|
||||||
|
return host, tonumber(port)
|
||||||
|
end
|
||||||
|
|
||||||
local function mongo_auth(mongoc)
|
local function mongo_auth(mongoc)
|
||||||
local user = rawget(mongoc, "username")
|
local user = rawget(mongoc, "username")
|
||||||
local pass = rawget(mongoc, "password")
|
local pass = rawget(mongoc, "password")
|
||||||
|
|
||||||
if user == nil or pass == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
return function()
|
return function()
|
||||||
|
if user ~= nil and pass ~= nil then
|
||||||
assert(mongoc:auth(user, pass))
|
assert(mongoc:auth(user, pass))
|
||||||
end
|
end
|
||||||
|
local rs_data = mongoc:runCommand("ismaster")
|
||||||
|
if rs_data.ok == 1 then
|
||||||
|
if rs_data.hosts then
|
||||||
|
local backup = {}
|
||||||
|
for _, v in ipairs(rs_data.hosts) do
|
||||||
|
local host, port = __parse_addr(v)
|
||||||
|
table.insert(backup, {host = host, port = port})
|
||||||
|
end
|
||||||
|
mongoc.__sock:changebackup(backup)
|
||||||
|
end
|
||||||
|
if rs_data.ismaster then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
local host, port = __parse_addr(rs_data.primary)
|
||||||
|
mongoc.host = host
|
||||||
|
mongoc.port = port
|
||||||
|
mongoc.__sock:changehost(host, port)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mongo.client( conf )
|
function mongo.client( conf )
|
||||||
|
local first = conf
|
||||||
|
local backup = nil
|
||||||
|
if conf.rs then
|
||||||
|
first = conf.rs[1]
|
||||||
|
backup = conf.rs
|
||||||
|
end
|
||||||
local obj = {
|
local obj = {
|
||||||
host = conf.host,
|
host = first.host,
|
||||||
port = conf.port or 27017,
|
port = first.port or 27017,
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.__id = 0
|
obj.__id = 0
|
||||||
@@ -99,6 +128,7 @@ function mongo.client( conf )
|
|||||||
port = obj.port,
|
port = obj.port,
|
||||||
response = dispatch_reply,
|
response = dispatch_reply,
|
||||||
auth = mongo_auth(obj),
|
auth = mongo_auth(obj),
|
||||||
|
backup = backup,
|
||||||
}
|
}
|
||||||
setmetatable(obj, client_meta)
|
setmetatable(obj, client_meta)
|
||||||
obj.__sock:connect(true) -- try connect only once
|
obj.__sock:connect(true) -- try connect only once
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ function socket_channel.channel(desc)
|
|||||||
local c = {
|
local c = {
|
||||||
__host = assert(desc.host),
|
__host = assert(desc.host),
|
||||||
__port = assert(desc.port),
|
__port = assert(desc.port),
|
||||||
|
__backup = desc.backup,
|
||||||
__auth = desc.auth,
|
__auth = desc.auth,
|
||||||
__response = desc.response, -- It's for session mode
|
__response = desc.response, -- It's for session mode
|
||||||
__request = {}, -- request seq { response func or session } -- It's for order mode
|
__request = {}, -- request seq { response func or session } -- It's for order mode
|
||||||
@@ -152,34 +153,66 @@ 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 connect_once(self)
|
local function connect_once(self)
|
||||||
|
if self.__closed then
|
||||||
|
return false
|
||||||
|
end
|
||||||
assert(not self.__sock and not self.__authcoroutine)
|
assert(not self.__sock and not self.__authcoroutine)
|
||||||
local fd = socket.open(self.__host, self.__port)
|
local fd = socket.open(self.__host, self.__port)
|
||||||
|
if not fd then
|
||||||
|
fd = connect_backup(self)
|
||||||
if not fd then
|
if not fd then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
self.__authcoroutine = coroutine.running()
|
end
|
||||||
|
|
||||||
self.__sock = setmetatable( {fd} , channel_socket_meta )
|
self.__sock = setmetatable( {fd} , channel_socket_meta )
|
||||||
skynet.fork(dispatch_function(self), self)
|
skynet.fork(dispatch_function(self), self)
|
||||||
|
|
||||||
if self.__auth then
|
if self.__auth then
|
||||||
|
self.__authcoroutine = coroutine.running()
|
||||||
local ok , message = pcall(self.__auth, self)
|
local ok , message = pcall(self.__auth, self)
|
||||||
if not ok then
|
if not ok then
|
||||||
close_channel_socket(self)
|
close_channel_socket(self)
|
||||||
if message ~= socket_error then
|
if message ~= socket_error then
|
||||||
|
self.__authcoroutine = false
|
||||||
skynet.error("socket: auth failed", message)
|
skynet.error("socket: auth failed", message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.__authcoroutine = false
|
self.__authcoroutine = false
|
||||||
|
if ok and not self.__sock then
|
||||||
|
-- auth may change host, so connect again
|
||||||
|
return connect_once(self)
|
||||||
|
end
|
||||||
return ok
|
return ok
|
||||||
end
|
end
|
||||||
|
|
||||||
self.__authcoroutine = false
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function try_connect(self , once)
|
local function try_connect(self , once)
|
||||||
local t = 100
|
local t = 0
|
||||||
while not self.__closed do
|
while not self.__closed do
|
||||||
if connect_once(self) then
|
if connect_once(self) then
|
||||||
if not once then
|
if not once then
|
||||||
@@ -292,6 +325,20 @@ function channel:close()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function channel:changehost(host, port)
|
||||||
|
self.__host = host
|
||||||
|
if port then
|
||||||
|
self.__port = port
|
||||||
|
end
|
||||||
|
if not self.__closed then
|
||||||
|
close_channel_socket(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function channel:changebackup(backup)
|
||||||
|
self.__backup = backup
|
||||||
|
end
|
||||||
|
|
||||||
channel_meta.__gc = channel.close
|
channel_meta.__gc = channel.close
|
||||||
|
|
||||||
local function wrapper_socket_function(f)
|
local function wrapper_socket_function(f)
|
||||||
|
|||||||
Reference in New Issue
Block a user