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 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.} =
|
proc requestResolver[MsgType](msg: pointer, future: FutureBase) {.gcsafe.} =
|
||||||
var f = Future[Option[MsgType]](future)
|
var f = Future[Option[MsgType]](future)
|
||||||
if not f.finished:
|
if not f.finished:
|
||||||
|
|
|
@ -17,9 +17,10 @@ type
|
||||||
timeoutParam*: NimNode
|
timeoutParam*: NimNode
|
||||||
recIdent*: NimNode
|
recIdent*: NimNode
|
||||||
recBody*: NimNode
|
recBody*: NimNode
|
||||||
userHandler*: NimNode
|
|
||||||
protocol*: P2PProtocol
|
protocol*: P2PProtocol
|
||||||
response*: Message
|
response*: Message
|
||||||
|
userHandler*: NimNode
|
||||||
|
initResponderCall*: NimNode
|
||||||
|
|
||||||
Request* = ref object
|
Request* = ref object
|
||||||
queries*: seq[Message]
|
queries*: seq[Message]
|
||||||
|
@ -93,6 +94,7 @@ type
|
||||||
# Code generators
|
# Code generators
|
||||||
implementMsg*: proc (msg: Message)
|
implementMsg*: proc (msg: Message)
|
||||||
implementProtocolInit*: proc (protocol: P2PProtocol): NimNode
|
implementProtocolInit*: proc (protocol: P2PProtocol): NimNode
|
||||||
|
|
||||||
afterProtocolInit*: proc (protocol: P2PProtocol)
|
afterProtocolInit*: proc (protocol: P2PProtocol)
|
||||||
|
|
||||||
# Bound symbols to the back-end run-time types and procs
|
# Bound symbols to the back-end run-time types and procs
|
||||||
|
@ -213,6 +215,9 @@ proc init*(T: type P2PProtocol, backendFactory: BackendFactory,
|
||||||
outProcRegistrations: newStmtList())
|
outProcRegistrations: newStmtList())
|
||||||
|
|
||||||
result.backend = backendFactory(result)
|
result.backend = backendFactory(result)
|
||||||
|
assert(not result.backend.implementProtocolInit.isNil)
|
||||||
|
assert(not result.backend.ResponderType.isNil)
|
||||||
|
|
||||||
result.processProtocolBody body
|
result.processProtocolBody body
|
||||||
|
|
||||||
if not result.backend.afterProtocolInit.isNil:
|
if not result.backend.afterProtocolInit.isNil:
|
||||||
|
@ -312,6 +317,11 @@ proc ensureTimeoutParam(procDef: NimNode, timeouts: int64): NimNode =
|
||||||
proc hasReqId*(msg: Message): bool =
|
proc hasReqId*(msg: Message): bool =
|
||||||
msg.protocol.useRequestIds and msg.kind in {msgRequest, msgResponse}
|
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,
|
proc newMsg(protocol: P2PProtocol, kind: MessageKind, id: int,
|
||||||
procDef: NimNode, timeoutParam: NimNode = nil,
|
procDef: NimNode, timeoutParam: NimNode = nil,
|
||||||
response: Message = nil): Message =
|
response: Message = nil): Message =
|
||||||
|
@ -354,16 +364,16 @@ proc newMsg(protocol: P2PProtocol, kind: MessageKind, id: int,
|
||||||
assert response != nil
|
assert response != nil
|
||||||
let
|
let
|
||||||
peerParam = userHandler.params[1][0]
|
peerParam = userHandler.params[1][0]
|
||||||
ResponderType = protocol.backend.ResponderType
|
ResponderType = result.ResponderType
|
||||||
ResponseRecord = response.recIdent
|
initResponderCall = newCall(ident"init", ResponderType, peerParam)
|
||||||
|
|
||||||
if protocol.useRequestIds:
|
if protocol.useRequestIds:
|
||||||
userHandler.addPreludeDefs quote do:
|
initResponderCall.add reqIdVar
|
||||||
let `responseVar` = `ResponderType`[`ResponseRecord`](peer: `peerParam`,
|
|
||||||
reqId: `reqIdVar`)
|
userHandler.addPreludeDefs quote do:
|
||||||
else:
|
let `responseVar` = `initResponderCall`
|
||||||
userHandler.addPreludeDefs quote do:
|
|
||||||
let `responseVar` = `ResponderType`[`ResponseRecord`](peer: `peerParam`)
|
result.initResponderCall = initResponderCall
|
||||||
|
|
||||||
protocol.outRecvProcs.add userHandler
|
protocol.outRecvProcs.add userHandler
|
||||||
result.userHandler = userHandler
|
result.userHandler = userHandler
|
||||||
|
@ -418,12 +428,9 @@ proc createSendProc*(msg: Message,
|
||||||
# 1 to the correct strongly-typed ResponderType. The incoming procs still
|
# 1 to the correct strongly-typed ResponderType. The incoming procs still
|
||||||
# gets the normal Peer paramter.
|
# gets the normal Peer paramter.
|
||||||
let
|
let
|
||||||
ResponderTypeHead = msg.protocol.backend.ResponderType
|
ResponderType = msg.ResponderType
|
||||||
ResponderType = newTree(nnkBracketExpr, ResponderTypeHead, msg.recIdent)
|
|
||||||
sendProcName = msg.ident
|
sendProcName = msg.ident
|
||||||
|
|
||||||
assert ResponderTypeHead != nil
|
|
||||||
|
|
||||||
def[3][1][1] = ResponderType
|
def[3][1][1] = ResponderType
|
||||||
|
|
||||||
# We create a helper that enables the `response.send()` syntax
|
# We create a helper that enables the `response.send()` syntax
|
||||||
|
|
|
@ -45,9 +45,17 @@ var
|
||||||
template allProtocols*: auto = {.gcsafe.}: gProtocols
|
template allProtocols*: auto = {.gcsafe.}: gProtocols
|
||||||
template devp2pInfo: auto = {.gcsafe.}: gDevp2pInfo
|
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)
|
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) =
|
template raisePeerDisconnected(msg: string, r: DisconnectionReason) =
|
||||||
var e = newException(PeerDisconnected, msg)
|
var e = newException(PeerDisconnected, msg)
|
||||||
|
|
Loading…
Reference in New Issue