@@ -275,12 +275,6 @@ declarePublicCounter nbc_successful_discoveries,
275
275
declarePublicCounter nbc_failed_discoveries,
276
276
" Number of failed discoveries"
277
277
278
- const delayBuckets = [1.0 , 5.0 , 10.0 , 20.0 , 40.0 , 60.0 ]
279
-
280
- declareHistogram nbc_resolve_time,
281
- " Time(s) used while resolving peer information" ,
282
- buckets = delayBuckets
283
-
284
278
const
285
279
snappy_implementation {.strdefine .} = " libp2p"
286
280
@@ -348,6 +342,9 @@ proc getFuture*(peer: Peer): Future[void] {.inline.} =
348
342
peer.disconnectedFut = newFuture [void ](" Peer.disconnectedFut" )
349
343
peer.disconnectedFut
350
344
345
+ proc isAlive * (peer: Peer ): bool =
346
+ peer.connectionState notin {Disconnecting , Disconnected }
347
+
351
348
proc getScore * (a: Peer ): int =
352
349
# # Returns current score value for peer ``peer``.
353
350
a.score
@@ -358,6 +355,41 @@ proc updateScore*(peer: Peer, score: int) {.inline.} =
358
355
if peer.score > PeerScoreHighLimit :
359
356
peer.score = PeerScoreHighLimit
360
357
358
+ proc join * (peer: Peer ): Future [void ] =
359
+ var retFuture = newFuture [void ](" peer.lifetime.join" )
360
+ let peerFut = peer.getFuture ()
361
+ let alreadyFinished = peerFut.finished ()
362
+
363
+ proc continuation (udata: pointer ) {.gcsafe .} =
364
+ if not (retFuture.finished ()):
365
+ retFuture.complete ()
366
+
367
+ proc cancellation (udata: pointer ) {.gcsafe .} =
368
+ if not (alreadyFinished):
369
+ peerFut.removeCallback (continuation)
370
+
371
+ if alreadyFinished:
372
+ # All the `peer.disconnectedFut` callbacks are already scheduled in current
373
+ # `poll()` call, to avoid race we going to finish only in next `poll()`
374
+ # call.
375
+ callSoon (continuation, cast [pointer ](retFuture))
376
+ else :
377
+ # `peer.disconnectedFut` is not yet finished, but we want to be scheduled
378
+ # after all callbacks.
379
+ peerFut.addCallback (continuation)
380
+
381
+ return retFuture
382
+
383
+ proc notifyAndWait * (peer: Peer ): Future [void ] =
384
+ # # Notify all the waiters that peer life is finished and wait until all
385
+ # # callbacks will be processed.
386
+ let joinFut = peer.join ()
387
+ let fut = peer.disconnectedFut
388
+ peer.connectionState = Disconnecting
389
+ fut.complete ()
390
+ peer.disconnectedFut = nil
391
+ joinFut
392
+
361
393
proc calcThroughput (dur: Duration , value: uint64 ): float =
362
394
let secs = float (chronos.seconds (1 ).nanoseconds)
363
395
if isZero (dur):
@@ -941,17 +973,16 @@ proc resolvePeer(peer: Peer) =
941
973
discard peer.info.peerId.extractPublicKey (key)
942
974
keys.PublicKey .fromRaw (key.skkey.getBytes ()).get ().toNodeId ()
943
975
944
- debug " Peer's ENR recovery task started" , node_id = $ nodeId
945
-
946
976
# This is "fast-path" for peers which was dialed. In this case discovery
947
977
# already has most recent ENR information about this peer.
948
978
let gnode = peer.network.discovery.getNode (nodeId)
949
979
if gnode.isSome ():
950
980
peer.enr = some (gnode.get ().record)
951
981
inc (nbc_successful_discoveries)
952
- let delay = now (chronos.Moment ) - startTime
953
- nbc_resolve_time.observe (delay.toFloatSeconds ())
954
- debug " Peer's ENR recovered" , delay = $ delay
982
+ debug " Peer's ENR recovered"
983
+ else :
984
+ inc (nbc_failed_discoveries)
985
+ debug " Peer's ENR could not be recovered"
955
986
956
987
proc handlePeer * (peer: Peer ) {.async .} =
957
988
let res = peer.network.peerPool.addPeerNoWait (peer, peer.direction)
@@ -980,8 +1011,7 @@ proc handlePeer*(peer: Peer) {.async.} =
980
1011
# Peer was added to PeerPool.
981
1012
peer.score = NewPeerScore
982
1013
peer.connectionState = Connected
983
- # We spawn task which will obtain ENR for this peer.
984
- resolvePeer (peer)
1014
+ peer.resolvePeer ()
985
1015
debug " Peer successfully connected" , peer = peer,
986
1016
connections = peer.connections
987
1017
@@ -1048,10 +1078,8 @@ proc onConnEvent(node: Eth2Node, peerId: PeerID, event: ConnEvent) {.async.} =
1048
1078
# Whatever caused disconnection, avoid connection spamming
1049
1079
node.addSeen (peerId, SeenTableTimeReconnect )
1050
1080
1051
- let fut = peer.disconnectedFut
1052
- if not (isNil (fut)):
1053
- fut.complete ()
1054
- peer.disconnectedFut = nil
1081
+ if not (isNil (peer.disconnectedFut)):
1082
+ await peer.notifyAndWait ()
1055
1083
else :
1056
1084
# TODO (cheatfate): This could be removed when bug will be fixed inside
1057
1085
# `nim-libp2p`.
0 commit comments