feat(wakucanary): add latency measurement using ping protocol (#2074)

This commit is contained in:
Vaclav Pavlin 2023-09-26 15:02:12 +02:00 committed by GitHub
parent a27d005ffc
commit 6cb9a8da86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 32 additions and 1 deletions

View File

@ -47,7 +47,7 @@ type
logLevel* {.
desc: "Sets the log level",
defaultValue: LogLevel.DEBUG,
defaultValue: LogLevel.INFO,
name: "log-level",
abbr: "l".}: LogLevel
@ -68,6 +68,11 @@ type
defaultValue: ""
name: "websocket-secure-cert-path".}: string
ping* {.
desc: "Ping the peer node to measure latency",
defaultValue: true,
name: "ping" .}: bool
proc parseCmdArg*(T: type chronos.Duration, p: string): T =
try:
result = chronos.seconds(parseInt(p))
@ -98,6 +103,18 @@ proc areProtocolsSupported(
return false
proc pingNode(node: WakuNode, peerInfo: RemotePeerInfo): Future[void] {.async, gcsafe.} =
try:
let conn = await node.switch.dial(peerInfo.peerId, peerInfo.addrs, PingCodec)
let pingDelay = await node.libp2pPing.ping(conn)
info "Peer response time (ms)", peerId = peerInfo.peerId, ping=pingDelay.millis
except CatchableError:
var msg = getCurrentExceptionMsg()
if msg == "Future operation cancelled!":
msg = "timedout"
error "Failed to ping the peer", peer=peerInfo, err=msg
proc main(rng: ref HmacDrbgContext): Future[int] {.async.} =
let conf: WakuCanaryConf = WakuCanaryConf.load()
@ -173,8 +190,19 @@ proc main(rng: ref HmacDrbgContext): Future[int] {.async.} =
let node = builder.build().tryGet()
if conf.ping:
try:
await mountLibp2pPing(node)
except CatchableError:
error "failed to mount libp2p ping protocol: " & getCurrentExceptionMsg()
return 1
await node.start()
var pingFut:Future[bool]
if conf.ping:
pingFut = pingNode(node, peer).withTimeout(conf.timeout)
let timedOut = not await node.connectToNodes(@[peer]).withTimeout(conf.timeout)
if timedOut:
error "Timedout after", timeout = conf.timeout
@ -183,6 +211,9 @@ proc main(rng: ref HmacDrbgContext): Future[int] {.async.} =
let lp2pPeerStore = node.switch.peerStore
let conStatus = node.peerManager.peerStore[ConnectionBook][peer.peerId]
if conf.ping:
discard await pingFut
if conStatus in [Connected, CanConnect]:
let nodeProtocols = lp2pPeerStore[ProtoBook][peer.peerId]
if not areProtocolsSupported(conf.protocols, nodeProtocols):