From cbe67720ce1e8870469862fb8a284b0e2e9d596a Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Mon, 25 Mar 2019 11:32:18 -0600 Subject: [PATCH] use Moment for tracking timeouts (#25) * use Moment for tracking timeouts * Use the new Duration type throughout RLPx --- eth/p2p/private/p2p_types.nim | 2 +- eth/p2p/rlpx.nim | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/eth/p2p/private/p2p_types.nim b/eth/p2p/private/p2p_types.nim index ef148e6..71253e0 100644 --- a/eth/p2p/private/p2p_types.nim +++ b/eth/p2p/private/p2p_types.nim @@ -128,7 +128,7 @@ type OutstandingRequest* = object id*: int future*: FutureBase - timeoutAt*: uint64 + timeoutAt*: Moment # Private types: MessageHandlerDecorator* = proc(msgId: int, n: NimNode): NimNode diff --git a/eth/p2p/rlpx.nim b/eth/p2p/rlpx.nim index c17a438..3d0e411 100644 --- a/eth/p2p/rlpx.nim +++ b/eth/p2p/rlpx.nim @@ -12,7 +12,7 @@ logScope: const devp2pVersion* = 4 - defaultReqTimeout = 10000 + defaultReqTimeout = milliseconds(10000) maxMsgSize = 1024 * 1024 include p2p_tracing @@ -298,13 +298,13 @@ proc send*[Msg](peer: Peer, msg: Msg): Future[void] = peer.sendMsg rlpWriter.finish proc registerRequest*(peer: Peer, - timeout: int, + timeout: Duration, responseFuture: FutureBase, responseMsgId: int): int = inc peer.lastReqId result = peer.lastReqId - let timeoutAt = fastEpochTime() + uint64(timeout) + let timeoutAt = Moment.fromNow(timeout) let req = OutstandingRequest(id: result, future: responseFuture, timeoutAt: timeoutAt) @@ -371,7 +371,7 @@ proc resolveResponseFuture(peer: Peer, msgId: int, msg: pointer, reqId: int) = template req: auto = outstandingReqs()[idx] if req.future.finished: - doAssert req.timeoutAt <= fastEpochTime() + doAssert req.timeoutAt <= Moment.now() # Here we'll remove the expired request by swapping # it with the last one in the deque (if necessary): if idx != outstandingReqs.len - 1: @@ -529,8 +529,9 @@ proc dispatchMessages*(peer: Peer) {.async.} = macro p2pProtocolImpl(name: static[string], version: static[uint], body: untyped, + # TODO Nim can't handle a proper duration paramter here + timeout: static[int64] = defaultReqTimeout.milliseconds, useRequestIds: static[bool] = true, - timeout: static[int] = defaultReqTimeout, shortName: static[string] = "", outgoingRequestDecorator: untyped = nil, incomingRequestDecorator: untyped = nil, @@ -575,6 +576,8 @@ macro p2pProtocolImpl(name: static[string], # Int = bindSym "int" Int = ident "int" Peer = bindSym "Peer" + Duration = bindSym "Duration" + milliseconds = bindSym "milliseconds" createNetworkState = bindSym "createNetworkState" createPeerState = bindSym "createPeerState" finish = bindSym "finish" @@ -725,7 +728,7 @@ macro p2pProtocolImpl(name: static[string], if reqTimeout == nil: reqTimeout = newTree(nnkIdentDefs, ident"timeout", - Int, newLit(defaultTimeout)) + Duration, newCall(milliseconds, newLit(defaultTimeout))) let reqToResponseOffset = responseMsgId - msgId let responseMsgId = quote do: `perPeerMsgIdVar` + `reqToResponseOffset` @@ -1102,11 +1105,11 @@ proc callDisconnectHandlers(peer: Peer, reason: DisconnectionReason): Future[voi proc handshakeImpl(peer: Peer, handshakeSendFut: Future[void], - timeout: int, + timeout: Duration, HandshakeType: type): Future[HandshakeType] {.async.} = asyncCheck handshakeSendFut var response = nextMsg(peer, HandshakeType) - if timeout > 0: + if timeout.milliseconds > 0: await response or sleepAsync(timeout) if not response.finished: discard disconnectAndRaise(peer, BreachOfProtocol, @@ -1115,7 +1118,7 @@ proc handshakeImpl(peer: Peer, discard await response return response.read -macro handshake*(peer: Peer, timeout = 0, sendCall: untyped): untyped = +macro handshake*(peer: Peer, timeout: untyped, sendCall: untyped): untyped = let msgName = $sendCall[0] msgType = newDotExpr(ident"CurrentProtocol", ident(msgName))