fix timeoutmonitor loop (#463)
* fix timeoutmonitor loop * Clarify that cancellation can happen while in timeoutMonitor
This commit is contained in:
parent
18443dafc1
commit
5c2a54bdd9
|
@ -63,6 +63,7 @@ method closeImpl*(s: Connection): Future[void] =
|
||||||
trace "Closing connection", s
|
trace "Closing connection", s
|
||||||
if not isNil(s.timerTaskFut) and not s.timerTaskFut.finished:
|
if not isNil(s.timerTaskFut) and not s.timerTaskFut.finished:
|
||||||
s.timerTaskFut.cancel()
|
s.timerTaskFut.cancel()
|
||||||
|
s.timerTaskFut = nil
|
||||||
|
|
||||||
trace "Closed connection", s
|
trace "Closed connection", s
|
||||||
|
|
||||||
|
@ -71,6 +72,32 @@ method closeImpl*(s: Connection): Future[void] =
|
||||||
func hash*(p: Connection): Hash =
|
func hash*(p: Connection): Hash =
|
||||||
cast[pointer](p).hash
|
cast[pointer](p).hash
|
||||||
|
|
||||||
|
proc pollActivity(s: Connection): Future[bool] {.async.} =
|
||||||
|
if s.closed and s.atEof:
|
||||||
|
return false # Done, no more monitoring
|
||||||
|
|
||||||
|
if s.activity:
|
||||||
|
s.activity = false
|
||||||
|
return true
|
||||||
|
|
||||||
|
# Inactivity timeout happened, call timeout monitor
|
||||||
|
|
||||||
|
trace "Connection timed out", s
|
||||||
|
if not(isNil(s.timeoutHandler)):
|
||||||
|
trace "Calling timeout handler", s
|
||||||
|
|
||||||
|
try:
|
||||||
|
await s.timeoutHandler()
|
||||||
|
except CancelledError:
|
||||||
|
# timeoutHandler is expected to be fast, but it's still possible that
|
||||||
|
# cancellation will happen here - no need to warn about it - we do want to
|
||||||
|
# stop the polling however
|
||||||
|
debug "Timeout handler cancelled", s
|
||||||
|
except CatchableError as exc: # Shouldn't happen
|
||||||
|
warn "exception in timeout handler", s, exc = exc.msg
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
proc timeoutMonitor(s: Connection) {.async, gcsafe.} =
|
proc timeoutMonitor(s: Connection) {.async, gcsafe.} =
|
||||||
## monitor the channel for inactivity
|
## monitor the channel for inactivity
|
||||||
##
|
##
|
||||||
|
@ -80,31 +107,14 @@ proc timeoutMonitor(s: Connection) {.async, gcsafe.} =
|
||||||
## be reset
|
## be reset
|
||||||
##
|
##
|
||||||
|
|
||||||
try:
|
|
||||||
while true:
|
while true:
|
||||||
|
try: # Sleep at least once!
|
||||||
await sleepAsync(s.timeout)
|
await sleepAsync(s.timeout)
|
||||||
|
except CancelledError:
|
||||||
if s.closed and s.atEof:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if s.activity:
|
if not await s.pollActivity():
|
||||||
s.activity = false
|
return
|
||||||
continue
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
# reset channel on inactivity timeout
|
|
||||||
trace "Connection timed out", s
|
|
||||||
if not(isNil(s.timeoutHandler)):
|
|
||||||
trace "Calling timeout handler", s
|
|
||||||
await s.timeoutHandler()
|
|
||||||
|
|
||||||
except CancelledError as exc:
|
|
||||||
raise exc
|
|
||||||
except CatchableError as exc: # Shouldn't happen
|
|
||||||
warn "exception in timeout", s, exc = exc.msg
|
|
||||||
finally:
|
|
||||||
s.timerTaskFut = nil
|
|
||||||
|
|
||||||
proc init*(C: type Connection,
|
proc init*(C: type Connection,
|
||||||
peerInfo: PeerInfo,
|
peerInfo: PeerInfo,
|
||||||
|
|
Loading…
Reference in New Issue