-
Notifications
You must be signed in to change notification settings - Fork 58
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
chore(examples): add pubsub example with production env #1333
Conversation
1ade95a
to
5aa334b
Compare
Jenkins BuildsClick to see older builds (6)
|
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.
Please check my comments 🙂
I recommend reading more code within nwaku
repository (production and test cases code). Many comments could be avoided by looking for usage examples within the repository.
|
||
# Make sure it matches the publisher. Use default value | ||
# see spec: https://rfc.vac.dev/spec/23/ | ||
let pubSubTopic = cast[PubsubTopic]("/waku/2/default-waku/proto") |
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.
let pubSubTopic = cast[PubsubTopic]("/waku/2/default-waku/proto") | |
let pubSubTopic = PubsubTopic("/waku/2/default-waku/proto") |
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.
Actually, this was a copy-paste from basic2
example, will update the example then.
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.
Yeah, apologies. The examples are quite outdated (esp. in terms of Nim usage!) so they've been making for a bad example. :/
let pubSubTopic = cast[PubsubTopic]("/waku/2/default-waku/proto") | ||
|
||
# any content topic can be chosen. make sure it matches the publisher | ||
let contentTopic = ContentTopic("/waku/2/pubsub-exampe/proto") |
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.
This content topic should follow the 23/WAKU2-TOPICS
RFC in regards of the content topics: https://rfc.vac.dev/spec/23/#content-topics
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.
What do you mean? I took the RFC as reference. app/version/name/enconding?
/{application-name}/{version-of-the-application}/{content-topic-name}/{encoding}
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.
I'm also confused here as to why this wouldn't be following the pattern? If Waku is seen as its own application, which we often do for examples, this would be following the pattern imo.
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.
The correct one for me would be something around the following:
- application-name:
examples
orwaku-examples
(waku
should not be a valid application name) - version-of-the-application: 1 (this is the first version of the application)
- content-topic-name:
relay-example
orpubsub-example
- encoding:
proto
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, `pubsub-example seems more accurate.
(waku should not be a valid application name)
what do you mean? do you want to enforce this?
speaking about this, with #1335 I have discovered that there are multiple content toppics that don't respect the spec, i.e. they have more fields. is this something that we want to enforce at some point?
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.
We won't enforce any content topic formats. /waku
is used widely as an application name already, particularly for bridging from waku v1 (in which /waku/1
is seen as the "application" and "version". An application is roughly defined as "something that defines its own payload format", but it's not possible to be precise here as content topics are not used in exactly the same way by all platforms, sometimes for good reason.
|
||
proc handler(topic: PubsubTopic, data: seq[byte]) {.async, gcsafe.} = | ||
let message = WakuMessage.init(data).value | ||
let payload = cast[string](message.payload) |
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.
let payload = cast[string](message.payload) | |
let payload = $message.payload |
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.
note that in my case it should be string.fromBytes(message.payload)
since as we haven't overloaded $
operator, $message.payload
just prints the bytes and not the strings :)
# any content topic can be chosen. make sure it matches the publisher | ||
let contentTopic = ContentTopic("/waku/2/pubsub-exampe/proto") | ||
|
||
proc handler(topic: PubsubTopic, data: seq[byte]) {.async, gcsafe.} = |
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.
proc handler(topic: PubsubTopic, data: seq[byte]) {.async, gcsafe.} = | |
proc handler(pubsubTopic: PubsubTopic, data: seq[byte]) {.async, gcsafe.} = |
while true: | ||
let numConnectedPeers = node.peerManager.peerStore.connectionBook.book.values().countIt(it == Connected) | ||
if numConnectedPeers >= 6: | ||
notice "subscriber is ready", connectedPeers=numConnectedPeers, required=6 | ||
break | ||
notice "waiting to be ready", connectedPeers=numConnectedPeers, required=6 | ||
await sleepAsync(5000) |
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.
I would rather not abuse of using while true:
+ sleepAsync()
. Use chronos' setTimer
like waku_metrics
does: https://github.com/status-im/nwaku/blob/master/waku/v2/node/waku_metrics.nim#L42-L76
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.
this loop breaks in 3-4 iterations once the minimum amount of peers are reached. I also want to block the execution here until these number of peers are reached. Using setTimer
doesn't seem to be the best choice for here, but correct me if im wrong.
examples/v2/publisher/publisher.nim
Outdated
notice "publisher service started" | ||
while true: | ||
let text = "hi there i'm a publisher" | ||
let message = WakuMessage(payload: cast[seq[byte]](text), # content of the message |
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.
Use stew/byteutils
:
let message = WakuMessage(payload: cast[seq[byte]](text), # content of the message | |
let message = WakuMessage(payload: toBytes(text), # content of the message |
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.
nice, will update basic2
example as well.
examples/v2/publisher/publisher.nim
Outdated
notice "published message", text = text, timestamp = message.timestamp, psTopic = pubSubTopic, contentTopic = contentTopic | ||
await sleepAsync(5000) | ||
|
||
discard setupAndPublish() |
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.
Idem. Don't discard futures. Use asyncSpawn
.
examples/v2/publisher/publisher.nim
Outdated
|
||
# Make sure it matches the publisher. Use default value | ||
# see spec: https://rfc.vac.dev/spec/23/ | ||
let pubSubTopic = cast[PubsubTopic]("/waku/2/default-waku/proto") |
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.
let pubSubTopic = cast[PubsubTopic]("/waku/2/default-waku/proto") | |
let pubSubTopic = PubsubTopic("/waku/2/default-waku/proto") |
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.
same, copy-paste from basic2
example. ofc makes no sense
examples/v2/publisher/publisher.nim
Outdated
let pubSubTopic = cast[PubsubTopic]("/waku/2/default-waku/proto") | ||
|
||
# any content topic can be chosen | ||
let contentTopic = ContentTopic("/waku/2/pubsub-exampe/proto") |
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.
Idem. This content topic is not following the 23/WAKU2-TOPICS
examples/v2/publisher/publisher.nim
Outdated
node.wakuDiscv5 = WakuDiscoveryV5.new( | ||
none(ValidIpAddress), none(Port), none(Port), | ||
ip, Port(discv5Port), bootstrapNodes, false, | ||
keys.PrivateKey(nodeKey.skkey), flags, [], node.rng) |
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.
Idem. "Magic numbers". Use key annotated arguments.
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.
This is a great addition, thanks! Our examples have needed some TLC for a while. Some minor comments below. I'd also prefer keeping the number of make targets simple for now (make example2
should cut it).
import | ||
confutils, | ||
std/[tables,sequtils], | ||
chronicles, | ||
chronicles/topics_registry, | ||
chronos, | ||
stew/shims/net, | ||
libp2p/crypto/crypto, | ||
eth/keys, | ||
eth/p2p/discoveryv5/enr |
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.
What is the pattern here @LNSD ? 🤔 I usually have std/
first, then external imports alphabetically, then internal, relative imports from furthest removed to closest. (Not really established before, but happy to make this convention.) I thought it's similar here, but then I'm unsure about stew
🤷
@@ -0,0 +1,33 @@ | |||
# basic2 |
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.
Is it just me doing something dumb, or does Github not render markdown headers correctly if the first letter is not capitalised (which would be annoying)?
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.
Github doesn't render them looks like :0
let contentTopic = ContentTopic("/waku/2/pubsub-exampe/proto") | ||
|
||
proc handler(topic: PubsubTopic, data: seq[byte]) {.async, gcsafe.} = | ||
let message = WakuMessage.init(data).value |
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.
Up to you, but I'm OK with an example crashing when a seriously unexpected condition arises. Could even consider using expect
to crash with a message.
let pubSubTopic = cast[PubsubTopic]("/waku/2/default-waku/proto") | ||
|
||
# any content topic can be chosen. make sure it matches the publisher | ||
let contentTopic = ContentTopic("/waku/2/pubsub-exampe/proto") |
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.
We won't enforce any content topic formats. /waku
is used widely as an application name already, particularly for bridging from waku v1 (in which /waku/1
is seen as the "application" and "version". An application is roughly defined as "something that defines its own payload format", but it's not possible to be precise here as content topics are not used in exactly the same way by all platforms, sometimes for good reason.
32bb0c3
to
ac6efe9
Compare
@LNSD thanks for the comments! just fixed them! |
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.
LGTM ✅
ac6efe9
to
09e91c7
Compare
Simple pubsub example to showcase how
nwaku
can be used. Some notes:example
with two codes:publisher
andsubscriber
.