mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
check conflict (#1798)
* rewind check conflict * Use auxsend instead of c.send
This commit is contained in:
@@ -69,6 +69,101 @@ local watching_session = {}
|
|||||||
local error_queue = {}
|
local error_queue = {}
|
||||||
local fork_queue = { h = 1, t = 0 }
|
local fork_queue = { h = 1, t = 0 }
|
||||||
|
|
||||||
|
local auxsend, auxtimeout
|
||||||
|
do ---- avoid session rewind conflict
|
||||||
|
local csend = c.send
|
||||||
|
local cintcommand = c.intcommand
|
||||||
|
local dangerzone
|
||||||
|
local dangerzone_size = 0x1000
|
||||||
|
local dangerzone_low = 0x70000000
|
||||||
|
local dangerzone_up = dangerzone_low + dangerzone_size
|
||||||
|
|
||||||
|
local set_checkrewind -- set auxsend and auxtimeout for safezone
|
||||||
|
local set_checkconflict -- set auxsend and auxtimeout for dangerzone
|
||||||
|
|
||||||
|
local function reset_dangerzone(session)
|
||||||
|
dangerzone_up = session
|
||||||
|
dangerzone_low = session
|
||||||
|
dangerzone = { [session] = true }
|
||||||
|
for s in pairs(session_id_coroutine) do
|
||||||
|
if s < dangerzone_low then
|
||||||
|
dangerzone_low = s
|
||||||
|
elseif s > dangerzone_up then
|
||||||
|
dangerzone_up = s
|
||||||
|
end
|
||||||
|
dangerzone[s] = true
|
||||||
|
end
|
||||||
|
dangerzone_low = dangerzone_low - dangerzone_size
|
||||||
|
end
|
||||||
|
|
||||||
|
-- in dangerzone, we should check if the next session already exist.
|
||||||
|
local function checkconflict(session)
|
||||||
|
local next_session = session + 1
|
||||||
|
if next_session > dangerzone_up then
|
||||||
|
-- leave dangerzone
|
||||||
|
reset_dangerzone(session)
|
||||||
|
assert(next_session > dangerzone_up)
|
||||||
|
set_checkrewind()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
if not dangerzone[next_session] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not session_id_coroutine[next_session] then
|
||||||
|
reset_dangerzone(session)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- skip the session already exist.
|
||||||
|
next_session = c.genid() + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function auxsend_checkconflict(addr, proto, msg, sz)
|
||||||
|
local session = csend(addr, proto, nil, msg, sz)
|
||||||
|
checkconflict(session)
|
||||||
|
return session
|
||||||
|
end
|
||||||
|
|
||||||
|
local function auxtimeout_checkconflict(timeout)
|
||||||
|
local session = cintcommand("TIMEOUT", timeout)
|
||||||
|
checkconflict(session)
|
||||||
|
return session
|
||||||
|
end
|
||||||
|
|
||||||
|
local function auxsend_checkrewind(addr, proto, msg, sz)
|
||||||
|
local session = csend(addr, proto, nil, msg, sz)
|
||||||
|
if session and session > dangerzone_low and session < dangerzone_up then
|
||||||
|
-- enter dangerzone
|
||||||
|
set_checkconflict(session)
|
||||||
|
end
|
||||||
|
return session
|
||||||
|
end
|
||||||
|
|
||||||
|
local function auxtimeout_checkrewind(timeout)
|
||||||
|
local session = cintcommand("TIMEOUT", timeout)
|
||||||
|
if session and session > dangerzone_low and session < dangerzone_up then
|
||||||
|
-- enter dangerzone
|
||||||
|
set_checkconflict(session)
|
||||||
|
end
|
||||||
|
return session
|
||||||
|
end
|
||||||
|
|
||||||
|
set_checkrewind = function()
|
||||||
|
auxsend = auxsend_checkrewind
|
||||||
|
auxtimeout = auxtimeout_checkrewind
|
||||||
|
end
|
||||||
|
|
||||||
|
set_checkconflict = function(session)
|
||||||
|
reset_dangerzone(session)
|
||||||
|
auxsend = auxsend_checkconflict
|
||||||
|
auxtimeout = auxtimeout_checkconflict
|
||||||
|
end
|
||||||
|
|
||||||
|
-- in safezone at the beginning
|
||||||
|
set_checkrewind()
|
||||||
|
end
|
||||||
|
|
||||||
do ---- request/select
|
do ---- request/select
|
||||||
local function send_requests(self)
|
local function send_requests(self)
|
||||||
local sessions = {}
|
local sessions = {}
|
||||||
@@ -85,7 +180,7 @@ do ---- request/select
|
|||||||
c.trace(tag, "call", 4)
|
c.trace(tag, "call", 4)
|
||||||
c.send(addr, skynet.PTYPE_TRACE, 0, tag)
|
c.send(addr, skynet.PTYPE_TRACE, 0, tag)
|
||||||
end
|
end
|
||||||
local session = c.send(addr, p.id , nil , p.pack(tunpack(req, 3, req.n)))
|
local session = auxsend(addr, p.id , p.pack(tunpack(req, 3, req.n)))
|
||||||
if session == nil then
|
if session == nil then
|
||||||
err = err or {}
|
err = err or {}
|
||||||
err[#err+1] = req
|
err[#err+1] = req
|
||||||
@@ -188,7 +283,7 @@ do ---- request/select
|
|||||||
self._error = send_requests(self)
|
self._error = send_requests(self)
|
||||||
self._resp = {}
|
self._resp = {}
|
||||||
if timeout then
|
if timeout then
|
||||||
self._timeout = c.intcommand("TIMEOUT",timeout)
|
self._timeout = auxtimeout(timeout)
|
||||||
session_id_coroutine[self._timeout] = self._thread
|
session_id_coroutine[self._timeout] = self._thread
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -373,7 +468,7 @@ end
|
|||||||
skynet.trace_timeout(false) -- turn off by default
|
skynet.trace_timeout(false) -- turn off by default
|
||||||
|
|
||||||
function skynet.timeout(ti, func)
|
function skynet.timeout(ti, func)
|
||||||
local session = c.intcommand("TIMEOUT",ti)
|
local session = auxtimeout(ti)
|
||||||
assert(session)
|
assert(session)
|
||||||
local co = co_create_for_timeout(func, ti)
|
local co = co_create_for_timeout(func, ti)
|
||||||
assert(session_id_coroutine[session] == nil)
|
assert(session_id_coroutine[session] == nil)
|
||||||
@@ -392,7 +487,7 @@ local function suspend_sleep(session, token)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function skynet.sleep(ti, token)
|
function skynet.sleep(ti, token)
|
||||||
local session = c.intcommand("TIMEOUT",ti)
|
local session = auxtimeout(ti)
|
||||||
assert(session)
|
assert(session)
|
||||||
token = token or coroutine.running()
|
token = token or coroutine.running()
|
||||||
local succ, ret = suspend_sleep(session, token)
|
local succ, ret = suspend_sleep(session, token)
|
||||||
@@ -605,7 +700,7 @@ function skynet.call(addr, typename, ...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local p = proto[typename]
|
local p = proto[typename]
|
||||||
local session = c.send(addr, p.id , nil , p.pack(...))
|
local session = auxsend(addr, p.id , p.pack(...))
|
||||||
if session == nil then
|
if session == nil then
|
||||||
error("call to invalid address " .. skynet.address(addr))
|
error("call to invalid address " .. skynet.address(addr))
|
||||||
end
|
end
|
||||||
@@ -619,7 +714,7 @@ function skynet.rawcall(addr, typename, msg, sz)
|
|||||||
c.send(addr, skynet.PTYPE_TRACE, 0, tag)
|
c.send(addr, skynet.PTYPE_TRACE, 0, tag)
|
||||||
end
|
end
|
||||||
local p = proto[typename]
|
local p = proto[typename]
|
||||||
local session = assert(c.send(addr, p.id , nil , msg, sz), "call to invalid address")
|
local session = assert(auxsend(addr, p.id , msg, sz), "call to invalid address")
|
||||||
return yield_call(addr, session)
|
return yield_call(addr, session)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -627,7 +722,7 @@ function skynet.tracecall(tag, addr, typename, msg, sz)
|
|||||||
c.trace(tag, "tracecall begin")
|
c.trace(tag, "tracecall begin")
|
||||||
c.send(addr, skynet.PTYPE_TRACE, 0, tag)
|
c.send(addr, skynet.PTYPE_TRACE, 0, tag)
|
||||||
local p = proto[typename]
|
local p = proto[typename]
|
||||||
local session = assert(c.send(addr, p.id , nil , msg, sz), "call to invalid address")
|
local session = assert(auxsend(addr, p.id , msg, sz), "call to invalid address")
|
||||||
local msg, sz = yield_call(addr, session)
|
local msg, sz = yield_call(addr, session)
|
||||||
c.trace(tag, "tracecall end")
|
c.trace(tag, "tracecall end")
|
||||||
return msg, sz
|
return msg, sz
|
||||||
|
|||||||
Reference in New Issue
Block a user