@@ -27,8 +27,8 @@ use std::{
27
27
} ;
28
28
29
29
use either:: Either ;
30
- use futures:: { channel:: oneshot, prelude:: * , stream :: SelectAll } ;
31
- use futures_bounded:: Delay ;
30
+ use futures:: { channel:: oneshot, prelude:: * } ;
31
+ use futures_bounded:: { Delay , StreamSet } ;
32
32
use libp2p_core:: { upgrade, ConnectedPoint } ;
33
33
use libp2p_identity:: PeerId ;
34
34
use libp2p_swarm:: {
@@ -78,7 +78,8 @@ pub struct Handler {
78
78
pending_messages : VecDeque < ( KadRequestMsg , QueryId ) > ,
79
79
80
80
/// List of active inbound substreams with the state they are in.
81
- inbound_substreams : SelectAll < InboundSubstreamState > ,
81
+ /// The streams are typed `InboundSubstreamState`, but the set uses the item type.
82
+ inbound_substreams : StreamSet < ConnectionHandlerEvent < ProtocolConfig , ( ) , HandlerEvent > > ,
82
83
83
84
/// The connected endpoint of the connection that the handler
84
85
/// is associated with.
@@ -120,8 +121,6 @@ enum InboundSubstreamState {
120
121
PendingFlush ( UniqueConnecId , KadInStreamSink < Stream > ) ,
121
122
/// The substream is being closed.
122
123
Closing ( KadInStreamSink < Stream > ) ,
123
- /// The substream was cancelled in favor of a new one.
124
- Cancelled ,
125
124
126
125
Poisoned {
127
126
phantom : PhantomData < QueryId > ,
@@ -174,9 +173,6 @@ impl InboundSubstreamState {
174
173
| InboundSubstreamState :: Closing ( substream) => {
175
174
* self = InboundSubstreamState :: Closing ( substream) ;
176
175
}
177
- InboundSubstreamState :: Cancelled => {
178
- * self = InboundSubstreamState :: Cancelled ;
179
- }
180
176
InboundSubstreamState :: Poisoned { .. } => unreachable ! ( ) ,
181
177
}
182
178
}
@@ -462,7 +458,10 @@ impl Handler {
462
458
endpoint,
463
459
remote_peer_id,
464
460
next_connec_unique_id : UniqueConnecId ( 0 ) ,
465
- inbound_substreams : Default :: default ( ) ,
461
+ inbound_substreams : StreamSet :: new (
462
+ move || Delay :: futures_timer ( substreams_timeout) ,
463
+ MAX_NUM_STREAMS ,
464
+ ) ,
466
465
outbound_substreams : futures_bounded:: FuturesTupleSet :: new (
467
466
move || Delay :: futures_timer ( substreams_timeout) ,
468
467
MAX_NUM_STREAMS ,
@@ -519,38 +518,45 @@ impl Handler {
519
518
} ) ;
520
519
}
521
520
522
- if self . inbound_substreams . len ( ) == MAX_NUM_STREAMS {
523
- if let Some ( s) = self . inbound_substreams . iter_mut ( ) . find ( |s| {
524
- matches ! (
525
- s,
526
- // An inbound substream waiting to be reused.
527
- InboundSubstreamState :: WaitingMessage { first: false , .. }
528
- )
529
- } ) {
530
- * s = InboundSubstreamState :: Cancelled ;
521
+ let connec_unique_id = self . next_connec_unique_id ;
522
+ self . next_connec_unique_id . 0 += 1 ;
523
+ let new_substream = InboundSubstreamState :: WaitingMessage {
524
+ first : true ,
525
+ connection_id : connec_unique_id,
526
+ substream : protocol,
527
+ } ;
528
+
529
+ if self . inbound_substreams . len ( ) >= MAX_NUM_STREAMS {
530
+ if let Some ( s) = self
531
+ . inbound_substreams
532
+ . iter_mut_of_type :: < InboundSubstreamState > ( )
533
+ . find ( |s| {
534
+ matches ! (
535
+ * * s,
536
+ // An inbound substream waiting to be reused.
537
+ InboundSubstreamState :: WaitingMessage { first: false , .. }
538
+ )
539
+ } )
540
+ {
541
+ * s. get_mut ( ) = new_substream;
531
542
tracing:: debug!(
532
543
peer=?self . remote_peer_id,
533
544
"New inbound substream to peer exceeds inbound substream limit. \
534
- Removed older substream waiting to be reused."
545
+ Replacing older substream that was waiting to be reused."
535
546
)
536
547
} else {
537
548
tracing:: warn!(
538
549
peer=?self . remote_peer_id,
539
550
"New inbound substream to peer exceeds inbound substream limit. \
540
551
No older substream waiting to be reused. Dropping new substream."
541
552
) ;
542
- return ;
543
553
}
554
+ } else {
555
+ self . inbound_substreams
556
+ . try_push ( new_substream)
557
+ . map_err ( |_| ( ) )
558
+ . expect ( "Just checked that stream set is not full; qed" ) ;
544
559
}
545
-
546
- let connec_unique_id = self . next_connec_unique_id ;
547
- self . next_connec_unique_id . 0 += 1 ;
548
- self . inbound_substreams
549
- . push ( InboundSubstreamState :: WaitingMessage {
550
- first : true ,
551
- connection_id : connec_unique_id,
552
- substream : protocol,
553
- } ) ;
554
560
}
555
561
556
562
/// Takes the given [`KadRequestMsg`] and composes it into an outbound request-response protocol
@@ -617,15 +623,15 @@ impl ConnectionHandler for Handler {
617
623
HandlerIn :: Reset ( request_id) => {
618
624
if let Some ( state) = self
619
625
. inbound_substreams
620
- . iter_mut ( )
621
- . find ( |state| match state {
626
+ . iter_mut_of_type :: < InboundSubstreamState > ( )
627
+ . find ( |state| match * * state {
622
628
InboundSubstreamState :: WaitingBehaviour ( conn_id, _, _) => {
623
- conn_id == & request_id. connec_unique_id
629
+ conn_id == request_id. connec_unique_id
624
630
}
625
631
_ => false ,
626
632
} )
627
633
{
628
- state. close ( ) ;
634
+ state. get_mut ( ) . close ( ) ;
629
635
}
630
636
}
631
637
HandlerIn :: FindNodeReq { key, query_id } => {
@@ -764,8 +770,16 @@ impl ConnectionHandler for Handler {
764
770
Poll :: Pending => { }
765
771
}
766
772
767
- if let Poll :: Ready ( Some ( event) ) = self . inbound_substreams . poll_next_unpin ( cx) {
768
- return Poll :: Ready ( event) ;
773
+ if let Poll :: Ready ( Some ( event_result) ) = self . inbound_substreams . poll_next_unpin ( cx) {
774
+ match event_result {
775
+ Ok ( event) => return Poll :: Ready ( event) ,
776
+ Err ( _stream_set_timeout) => {
777
+ tracing:: trace!(
778
+ "Inbound substream timed out waiting for peer, send, or close"
779
+ ) ;
780
+ continue ;
781
+ }
782
+ }
769
783
}
770
784
771
785
if self . outbound_substreams . len ( ) < MAX_NUM_STREAMS {
@@ -849,8 +863,11 @@ fn compute_new_protocol_status(
849
863
850
864
impl Handler {
851
865
fn answer_pending_request ( & mut self , request_id : RequestId , mut msg : KadResponseMsg ) {
852
- for state in self . inbound_substreams . iter_mut ( ) {
853
- match state. try_answer_with ( request_id, msg) {
866
+ for state in self
867
+ . inbound_substreams
868
+ . iter_mut_of_type :: < InboundSubstreamState > ( )
869
+ {
870
+ match state. get_mut ( ) . try_answer_with ( request_id, msg) {
854
871
Ok ( ( ) ) => return ,
855
872
Err ( m) => {
856
873
msg = m;
@@ -1007,7 +1024,6 @@ impl futures::Stream for InboundSubstreamState {
1007
1024
}
1008
1025
} ,
1009
1026
InboundSubstreamState :: Poisoned { .. } => unreachable ! ( ) ,
1010
- InboundSubstreamState :: Cancelled => return Poll :: Ready ( None ) ,
1011
1027
}
1012
1028
}
1013
1029
}
0 commit comments