mirror of https://github.com/status-im/nim-eth.git
More flexible definitions of Responders
This commit is contained in:
parent
1adad7f4da
commit
a492e3c218
|
@ -23,6 +23,11 @@ template networkState*(connection: Peer, Protocol: type): untyped =
|
|||
|
||||
proc initProtocolState*[T](state: T, x: Peer|EthereumNode) {.gcsafe.} = discard
|
||||
|
||||
proc resolveFuture[MsgType](msg: pointer, future: FutureBase) {.gcsafe.} =
|
||||
var f = Future[MsgType](future)
|
||||
doAssert(not f.finished())
|
||||
f.complete(cast[ptr MsgType](msg)[])
|
||||
|
||||
proc requestResolver[MsgType](msg: pointer, future: FutureBase) {.gcsafe.} =
|
||||
var f = Future[Option[MsgType]](future)
|
||||
if not f.finished:
|
||||
|
|
|
@ -17,9 +17,10 @@ type
|
|||
timeoutParam*: NimNode
|
||||
recIdent*: NimNode
|
||||
recBody*: NimNode
|
||||
userHandler*: NimNode
|
||||
protocol*: P2PProtocol
|
||||
response*: Message
|
||||
userHandler*: NimNode
|
||||
initResponderCall*: NimNode
|
||||
|
||||
Request* = ref object
|
||||
queries*: seq[Message]
|
||||
|
@ -93,6 +94,7 @@ type
|
|||
# Code generators
|
||||
implementMsg*: proc (msg: Message)
|
||||
implementProtocolInit*: proc (protocol: P2PProtocol): NimNode
|
||||
|
||||
afterProtocolInit*: proc (protocol: P2PProtocol)
|
||||
|
||||
# Bound symbols to the back-end run-time types and procs
|
||||
|
@ -213,6 +215,9 @@ proc init*(T: type P2PProtocol, backendFactory: BackendFactory,
|
|||
outProcRegistrations: newStmtList())
|
||||
|
||||
result.backend = backendFactory(result)
|
||||
assert(not result.backend.implementProtocolInit.isNil)
|
||||
assert(not result.backend.ResponderType.isNil)
|
||||
|
||||
result.processProtocolBody body
|
||||
|
||||
if not result.backend.afterProtocolInit.isNil:
|
||||
|
@ -312,6 +317,11 @@ proc ensureTimeoutParam(procDef: NimNode, timeouts: int64): NimNode =
|
|||
proc hasReqId*(msg: Message): bool =
|
||||
msg.protocol.useRequestIds and msg.kind in {msgRequest, msgResponse}
|
||||
|
||||
proc ResponderType(msg: Message): NimNode =
|
||||
var resp = if msg.kind == msgRequest: msg.response else: msg
|
||||
newTree(nnkBracketExpr,
|
||||
msg.protocol.backend.ResponderType, resp.recIdent)
|
||||
|
||||
proc newMsg(protocol: P2PProtocol, kind: MessageKind, id: int,
|
||||
procDef: NimNode, timeoutParam: NimNode = nil,
|
||||
response: Message = nil): Message =
|
||||
|
@ -354,16 +364,16 @@ proc newMsg(protocol: P2PProtocol, kind: MessageKind, id: int,
|
|||
assert response != nil
|
||||
let
|
||||
peerParam = userHandler.params[1][0]
|
||||
ResponderType = protocol.backend.ResponderType
|
||||
ResponseRecord = response.recIdent
|
||||
ResponderType = result.ResponderType
|
||||
initResponderCall = newCall(ident"init", ResponderType, peerParam)
|
||||
|
||||
if protocol.useRequestIds:
|
||||
userHandler.addPreludeDefs quote do:
|
||||
let `responseVar` = `ResponderType`[`ResponseRecord`](peer: `peerParam`,
|
||||
reqId: `reqIdVar`)
|
||||
else:
|
||||
userHandler.addPreludeDefs quote do:
|
||||
let `responseVar` = `ResponderType`[`ResponseRecord`](peer: `peerParam`)
|
||||
initResponderCall.add reqIdVar
|
||||
|
||||
userHandler.addPreludeDefs quote do:
|
||||
let `responseVar` = `initResponderCall`
|
||||
|
||||
result.initResponderCall = initResponderCall
|
||||
|
||||
protocol.outRecvProcs.add userHandler
|
||||
result.userHandler = userHandler
|
||||
|
@ -418,12 +428,9 @@ proc createSendProc*(msg: Message,
|
|||
# 1 to the correct strongly-typed ResponderType. The incoming procs still
|
||||
# gets the normal Peer paramter.
|
||||
let
|
||||
ResponderTypeHead = msg.protocol.backend.ResponderType
|
||||
ResponderType = newTree(nnkBracketExpr, ResponderTypeHead, msg.recIdent)
|
||||
ResponderType = msg.ResponderType
|
||||
sendProcName = msg.ident
|
||||
|
||||
assert ResponderTypeHead != nil
|
||||
|
||||
def[3][1][1] = ResponderType
|
||||
|
||||
# We create a helper that enables the `response.send()` syntax
|
||||
|
|
|
@ -45,9 +45,17 @@ var
|
|||
template allProtocols*: auto = {.gcsafe.}: gProtocols
|
||||
template devp2pInfo: auto = {.gcsafe.}: gDevp2pInfo
|
||||
|
||||
proc init*[MsgName](T: type ResponderWithId[MsgName],
|
||||
peer: Peer, reqId: int): T =
|
||||
T(peer: peer, reqId: reqId)
|
||||
|
||||
proc init*[MsgName](T: type ResponderWithoutId[MsgName], peer: Peer): T =
|
||||
T(peer)
|
||||
|
||||
chronicles.formatIt(Peer): $(it.remote)
|
||||
|
||||
proc disconnect*(peer: Peer, reason: DisconnectionReason, notifyOtherPeer = false) {.gcsafe, async.}
|
||||
proc disconnect*(peer: Peer, reason: DisconnectionReason,
|
||||
notifyOtherPeer = false) {.gcsafe, async.}
|
||||
|
||||
template raisePeerDisconnected(msg: string, r: DisconnectionReason) =
|
||||
var e = newException(PeerDisconnected, msg)
|
||||
|
|
Loading…
Reference in New Issue