@@ -136,7 +136,7 @@ pub enum Event<TRequest, TResponse, TChannelResponse = TResponse> {
136
136
/// An outbound request failed.
137
137
OutboundFailure {
138
138
/// The peer to whom the request was sent.
139
- peer : PeerId ,
139
+ peer : Option < PeerId > ,
140
140
/// The (local) ID of the failed request.
141
141
request_id : OutboundRequestId ,
142
142
/// The error that occurred.
@@ -333,6 +333,24 @@ impl Config {
333
333
}
334
334
}
335
335
336
+ #[ derive( Debug , Eq , PartialEq , Hash ) ]
337
+ enum PendingOutgoingRequest {
338
+ PeerId ( PeerId ) ,
339
+ ConnectionId ( ConnectionId ) ,
340
+ }
341
+
342
+ impl From < PeerId > for PendingOutgoingRequest {
343
+ fn from ( peer_id : PeerId ) -> Self {
344
+ Self :: PeerId ( peer_id)
345
+ }
346
+ }
347
+
348
+ impl From < ConnectionId > for PendingOutgoingRequest {
349
+ fn from ( connection_id : ConnectionId ) -> Self {
350
+ Self :: ConnectionId ( connection_id)
351
+ }
352
+ }
353
+
336
354
/// A request/response protocol for some message codec.
337
355
pub struct Behaviour < TCodec >
338
356
where
@@ -360,7 +378,8 @@ where
360
378
addresses : PeerAddresses ,
361
379
/// Requests that have not yet been sent and are waiting for a connection
362
380
/// to be established.
363
- pending_outbound_requests : HashMap < PeerId , SmallVec < [ OutboundMessage < TCodec > ; 10 ] > > ,
381
+ pending_outbound_requests :
382
+ HashMap < PendingOutgoingRequest , SmallVec < [ OutboundMessage < TCodec > ; 10 ] > > ,
364
383
}
365
384
366
385
impl < TCodec > Behaviour < TCodec >
@@ -417,28 +436,45 @@ where
417
436
/// connection is established.
418
437
///
419
438
/// > **Note**: In order for such a dialing attempt to succeed,
420
- /// > the `RequestResonse` protocol must either be embedded
421
- /// > in another `NetworkBehaviour` that provides peer and
422
- /// > address discovery, or known addresses of peers must be
423
- /// > managed via [`Behaviour::add_address`] and
439
+ /// > the `peer` must be [`DialOpts`] with multiaddresses or
440
+ /// > in case of simple [`PeerId`] `RequestResponse` protocol
441
+ /// > must either be embedded in another `NetworkBehaviour`
442
+ /// > that provides peer and address discovery, or known addresses of
443
+ /// > peers must be managed via [`Behaviour::add_address`] and
424
444
/// > [`Behaviour::remove_address`].
425
- pub fn send_request ( & mut self , peer : & PeerId , request : TCodec :: Request ) -> OutboundRequestId {
445
+ pub fn send_request < Peer > ( & mut self , peer : Peer , request : TCodec :: Request ) -> OutboundRequestId
446
+ where
447
+ DialOpts : From < Peer > ,
448
+ {
426
449
let request_id = self . next_outbound_request_id ( ) ;
427
450
let request = OutboundMessage {
428
451
request_id,
429
452
request,
430
453
protocols : self . outbound_protocols . clone ( ) ,
431
454
} ;
432
455
433
- if let Some ( request) = self . try_send_request ( peer, request) {
434
- self . pending_events . push_back ( ToSwarm :: Dial {
435
- opts : DialOpts :: peer_id ( * peer) . build ( ) ,
436
- } ) ;
437
- self . pending_outbound_requests
438
- . entry ( * peer)
439
- . or_default ( )
440
- . push ( request) ;
441
- }
456
+ let opts = DialOpts :: from ( peer) ;
457
+ let maybe_peer_id = opts. get_peer_id ( ) ;
458
+ let request = if let Some ( peer_id) = & maybe_peer_id {
459
+ if let Some ( request) = self . try_send_request ( peer_id, request) {
460
+ request
461
+ } else {
462
+ // Sent successfully
463
+ return request_id;
464
+ }
465
+ } else {
466
+ request
467
+ } ;
468
+
469
+ self . pending_outbound_requests
470
+ . entry ( if let Some ( peer_id) = maybe_peer_id {
471
+ peer_id. into ( )
472
+ } else {
473
+ opts. connection_id ( ) . into ( )
474
+ } )
475
+ . or_default ( )
476
+ . push ( request) ;
477
+ self . pending_events . push_back ( ToSwarm :: Dial { opts } ) ;
442
478
443
479
request_id
444
480
}
@@ -506,7 +542,7 @@ where
506
542
// Check if request is still pending to be sent.
507
543
let pen_conn = self
508
544
. pending_outbound_requests
509
- . get ( peer)
545
+ . get ( & PendingOutgoingRequest :: from ( * peer) )
510
546
. map ( |rps| rps. iter ( ) . any ( |rp| rp. request_id == * request_id) )
511
547
. unwrap_or ( false ) ;
512
548
@@ -665,30 +701,41 @@ where
665
701
for request_id in connection. pending_outbound_responses {
666
702
self . pending_events
667
703
. push_back ( ToSwarm :: GenerateEvent ( Event :: OutboundFailure {
668
- peer : peer_id,
704
+ peer : Some ( peer_id) ,
669
705
request_id,
670
706
error : OutboundFailure :: ConnectionClosed ,
671
707
} ) ) ;
672
708
}
673
709
}
674
710
675
- fn on_dial_failure ( & mut self , DialFailure { peer_id, .. } : DialFailure ) {
676
- if let Some ( peer) = peer_id {
677
- // If there are pending outgoing requests when a dial failure occurs,
678
- // it is implied that we are not connected to the peer, since pending
679
- // outgoing requests are drained when a connection is established and
680
- // only created when a peer is not connected when a request is made.
681
- // Thus these requests must be considered failed, even if there is
682
- // another, concurrent dialing attempt ongoing.
683
- if let Some ( pending) = self . pending_outbound_requests . remove ( & peer) {
684
- for request in pending {
685
- self . pending_events
686
- . push_back ( ToSwarm :: GenerateEvent ( Event :: OutboundFailure {
687
- peer,
688
- request_id : request. request_id ,
689
- error : OutboundFailure :: DialFailure ,
690
- } ) ) ;
691
- }
711
+ fn on_dial_failure (
712
+ & mut self ,
713
+ DialFailure {
714
+ peer_id,
715
+ connection_id,
716
+ ..
717
+ } : DialFailure ,
718
+ ) {
719
+ let key = if let Some ( peer_id) = peer_id {
720
+ peer_id. into ( )
721
+ } else {
722
+ connection_id. into ( )
723
+ } ;
724
+
725
+ // If there are pending outgoing requests when a dial failure occurs,
726
+ // it is implied that we are not connected to the peer, since pending
727
+ // outgoing requests are drained when a connection is established and
728
+ // only created when a peer is not connected when a request is made.
729
+ // Thus, these requests must be considered failed, even if there is
730
+ // another, concurrent dialing attempt ongoing.
731
+ if let Some ( pending) = self . pending_outbound_requests . remove ( & key) {
732
+ for request in pending {
733
+ self . pending_events
734
+ . push_back ( ToSwarm :: GenerateEvent ( Event :: OutboundFailure {
735
+ peer : peer_id,
736
+ request_id : request. request_id ,
737
+ error : OutboundFailure :: DialFailure ,
738
+ } ) ) ;
692
739
}
693
740
}
694
741
}
@@ -703,7 +750,7 @@ where
703
750
) {
704
751
let mut connection = Connection :: new ( connection_id, remote_address) ;
705
752
706
- if let Some ( pending_requests) = self . pending_outbound_requests . remove ( & peer) {
753
+ if let Some ( pending_requests) = self . pending_outbound_requests . remove ( & peer. into ( ) ) {
707
754
for request in pending_requests {
708
755
connection
709
756
. pending_outbound_responses
@@ -887,7 +934,7 @@ where
887
934
888
935
self . pending_events
889
936
. push_back ( ToSwarm :: GenerateEvent ( Event :: OutboundFailure {
890
- peer,
937
+ peer : Some ( peer ) ,
891
938
request_id,
892
939
error : OutboundFailure :: Timeout ,
893
940
} ) ) ;
@@ -901,7 +948,7 @@ where
901
948
902
949
self . pending_events
903
950
. push_back ( ToSwarm :: GenerateEvent ( Event :: OutboundFailure {
904
- peer,
951
+ peer : Some ( peer ) ,
905
952
request_id,
906
953
error : OutboundFailure :: UnsupportedProtocols ,
907
954
} ) ) ;
@@ -912,7 +959,7 @@ where
912
959
913
960
self . pending_events
914
961
. push_back ( ToSwarm :: GenerateEvent ( Event :: OutboundFailure {
915
- peer,
962
+ peer : Some ( peer ) ,
916
963
request_id,
917
964
error : OutboundFailure :: Io ( error) ,
918
965
} ) )
0 commit comments