-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add support for setting protocol handlers with {.raises.}
annotation
#1064
Changes from 2 commits
14fee3b
417922c
302359b
69f18ec
843fb45
967c40c
71dbcef
3af3aa5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
# Nim-LibP2P | ||
# Copyright (c) 2023 Status Research & Development GmbH | ||
# Copyright (c) 2023-2024 Status Research & Development GmbH | ||
# Licensed under either of | ||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) | ||
# * MIT license ([LICENSE-MIT](LICENSE-MIT)) | ||
|
@@ -19,14 +19,16 @@ const | |
|
||
type | ||
LPProtoHandler* = proc ( | ||
conn: Connection, | ||
proto: string): | ||
Future[void] | ||
{.gcsafe, raises: [].} | ||
conn: Connection, | ||
proto: string): Future[void] {.async.} | ||
|
||
LPProtoHandler2* = proc ( | ||
conn: Connection, | ||
proto: string): Future[void] {.async: (raises: [CancelledError]).} | ||
|
||
LPProtocol* = ref object of RootObj | ||
codecs*: seq[string] | ||
handler*: LPProtoHandler ## this handler gets invoked by the protocol negotiator | ||
handlerImpl: LPProtoHandler ## invoked by the protocol negotiator | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this rename breaks There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's what I mentioned above. It has to be renamed otherwise There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. breaks nimbus-eth2 though There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1 liner to fix |
||
started*: bool | ||
maxIncomingStreams: Opt[int] | ||
|
||
|
@@ -41,23 +43,47 @@ proc `maxIncomingStreams=`*(p: LPProtocol, val: int) = | |
p.maxIncomingStreams = Opt.some(val) | ||
|
||
func codec*(p: LPProtocol): string = | ||
assert(p.codecs.len > 0, "Codecs sequence was empty!") | ||
doAssert(p.codecs.len > 0, "Codecs sequence was empty!") | ||
p.codecs[0] | ||
|
||
func `codec=`*(p: LPProtocol, codec: string) = | ||
# always insert as first codec | ||
# if we use this abstraction | ||
p.codecs.insert(codec, 0) | ||
|
||
template `handler`*(p: LPProtocol): LPProtoHandler = | ||
p.handlerImpl | ||
|
||
template `handler`*( | ||
p: LPProtocol, conn: Connection, proto: string): Future[void] = | ||
p.handlerImpl(conn, proto) | ||
|
||
func `handler=`*(p: LPProtocol, handler: LPProtoHandler) = | ||
p.handlerImpl = handler | ||
|
||
func `handler=`*(p: LPProtocol, handler: LPProtoHandler2) = | ||
proc wrap(conn: Connection, proto: string): Future[void] {.async.} = | ||
await handler(conn, proto) | ||
p.handlerImpl = wrap | ||
|
||
proc new*( | ||
T: type LPProtocol, | ||
codecs: seq[string], | ||
handler: LPProtoHandler, | ||
maxIncomingStreams: Opt[int] | int = Opt.none(int)): T = | ||
T: type LPProtocol, | ||
codecs: seq[string], | ||
handler: LPProtoHandler, | ||
maxIncomingStreams: Opt[int] | int = Opt.none(int)): T = | ||
T( | ||
codecs: codecs, | ||
handler: handler, | ||
handlerImpl: handler, | ||
maxIncomingStreams: | ||
when maxIncomingStreams is int: Opt.some(maxIncomingStreams) | ||
else: maxIncomingStreams | ||
) | ||
|
||
proc new*( | ||
T: type LPProtocol, | ||
codecs: seq[string], | ||
handler: LPProtoHandler2, | ||
maxIncomingStreams: Opt[int] | int = Opt.none(int)): T = | ||
proc wrap(conn: Connection, proto: string): Future[void] {.async.} = | ||
await handler(conn, proto) | ||
T.new(codec, wrap, maxIncomingStreams) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm..
not that I necessarily disagree with this change, but this becomes an odd case which should have been solved by covariance - ie technically, because we allow any exception to be raised, we should not constrain here to
[CancelledError]
(raises: [ValueError]
would also be "correct")..I wonder if there's a way to solve this with some generics, ie create a
new
that takes annew[E](handler: proc(): InternalRaisesFuture[void, E]
- if that's possible, it's probably something we should formalize in chronos somehow, to allow expressing it without referencingInternal..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, it would still involve going through the
new
orhandler=
instead of constructing the object manually. Agree that making it more generic would also serve the role of allowing{.async: raises.}
annotation, but for now would have to go withInternal
. I guess that's alright to get started.