add __nowating flag to cluster config, see issue #803

This commit is contained in:
Cloud Wu
2018-05-22 19:48:54 +08:00
parent 6c7cb5313d
commit a8ab809928
3 changed files with 32 additions and 14 deletions

View File

@@ -22,6 +22,7 @@ skynet.start(function()
} }
print(pcall(cluster.call, "db", "@sdb", "GET", "a")) -- db is down print(pcall(cluster.call, "db", "@sdb", "GET", "a")) -- db is down
end) end)
cluster.reload { __nowaiting = false }
local pingserver = cluster.snax("db3", "pingserver") local pingserver = cluster.snax("db3", "pingserver")
print(pingserver.req.ping "hello") print(pingserver.req.ping "hello")
end) end)

View File

@@ -1,2 +1,4 @@
__nowaiting = true -- If you turn this flag off, cluster.call would block when node name is absent
db = "127.0.0.1:2528" db = "127.0.0.1:2528"
db2 = "127.0.0.1:2529" db2 = "127.0.0.1:2529"

View File

@@ -7,6 +7,7 @@ local config_name = skynet.getenv "cluster"
local node_address = {} local node_address = {}
local node_session = {} local node_session = {}
local command = {} local command = {}
local config = {}
local function read_response(sock) local function read_response(sock)
local sz = socket.header(sock:read(2)) local sz = socket.header(sock:read(2))
@@ -27,14 +28,14 @@ local function open_channel(t, key)
ct = {} ct = {}
connecting[key] = ct connecting[key] = ct
local address = node_address[key] local address = node_address[key]
if address == nil then if address == nil and not config.nowaiting then
local co = coroutine.running() local co = coroutine.running()
assert(ct.namequery == nil) assert(ct.namequery == nil)
ct.namequery = co ct.namequery = co
skynet.error("Wating for cluster node [".. key.."]") skynet.error("Waiting for cluster node [".. key.."]")
skynet.wait(co) skynet.wait(co)
address = node_address[key] address = node_address[key]
assert(address ~= nil) assert(address ~= nil or config.nowaiting)
end end
local succ, err, c local succ, err, c
if address then if address then
@@ -51,7 +52,7 @@ local function open_channel(t, key)
ct.channel = c ct.channel = c
end end
else else
err = "cluster node [" .. key .. "] is down." err = string.format("cluster node [%s] is %s.", key, address == false and "down" or "absent")
end end
connecting[key] = nil connecting[key] = nil
for _, co in ipairs(ct) do for _, co in ipairs(ct) do
@@ -74,18 +75,32 @@ local function loadconfig(tmp)
end end
end end
for name,address in pairs(tmp) do for name,address in pairs(tmp) do
assert(address == false or type(address) == "string") if name:sub(1,2) == "__" then
if node_address[name] ~= address then name = name:sub(3)
-- address changed config[name] = address
if rawget(node_channel, name) then skynet.error(string.format("Config %s = %s", name, address))
node_channel[name] = nil -- reset connection else
assert(address == false or type(address) == "string")
if node_address[name] ~= address then
-- address changed
if rawget(node_channel, name) then
node_channel[name] = nil -- reset connection
end
node_address[name] = address
end
local ct = connecting[name]
if ct and ct.namequery and not config.nowaiting then
skynet.error(string.format("Cluster node [%s] resloved : %s", name, address))
skynet.wakeup(ct.namequery)
end end
node_address[name] = address
end end
local ct = connecting[name] end
if ct and ct.namequery then if config.nowaiting then
skynet.error(string.format("Cluster node [%s] resloved : %s", name, address)) -- wakeup all connecting request
skynet.wakeup(ct.namequery) for name, ct in pairs(connecting) do
if ct.namequery then
skynet.wakeup(ct.namequery)
end
end end
end end
end end