pub(super) fn perform_housekeeping(&mut self, now: Instant) -> Vec<DialRequest<H>> {
        let mut to_forget = Vec::new();
        let mut to_fail = Vec::new();
        let mut to_reconnect = Vec::new();

        for (&addr, outgoing) in self.outgoing.iter() {
            let span = make_span(addr, Some(outgoing));

            span.in_scope(|| match outgoing.state {
                // Decide whether to attempt reconnecting a failed-waiting address.
                OutgoingState::Waiting {
                    failures_so_far,
                    last_failure,
                    ..
                } => {
                    if failures_so_far > self.config.retry_attempts {
                        if outgoing.is_unforgettable {
                            // Unforgettable addresses simply have their timer reset.
                            info!("unforgettable address reset");

                            to_reconnect.push((addr, 0));
                        } else {
                            // Address had too many attempts at reconnection, we will forget
                            // it after exiting this closure.
                            to_forget.push(addr);

                            info!("address forgotten");
                        }
                    } else {
                        // The address has not exceeded the limit, so check if it is due.
                        let due = last_failure + self.config.calc_backoff(failures_so_far);
                        if now >= due {
                            debug!(attempts = failures_so_far, "address reconnecting");

                            to_reconnect.push((addr, failures_so_far));
                        }
                    }
                }

                OutgoingState::Blocked { since } => {
                    if now >= since + self.config.unblock_after {
                        info!("address unblocked");

                        to_reconnect.push((addr, 0));
                    }
                }

                OutgoingState::Connecting {
                    since,
                    failures_so_far,
                } => {
                    let timeout = since + self.config.sweep_timeout;
                    if now >= timeout {
                        // The outer component has not called us with a `DialOutcome` in a
                        // reasonable amount of time. This should happen very rarely, ideally
                        // never.
                        warn!("address timed out connecting, was swept");

                        // Count the timeout as a failure against the connection.
                        to_fail.push((addr, failures_so_far + 1));
                    }
                }

                OutgoingState::Connected { .. } | OutgoingState::Loopback => {
                    // Entry is ignored. Not outputting any `trace` because this is log spam even at
                    // the `trace` level.
                }
            });
        }

        // Remove all addresses marked for forgetting.
        to_forget.into_iter().for_each(|addr| {
            self.outgoing.remove(&addr);
        });

        // Fail connections that are taking way too long to connect.
        to_fail.into_iter().for_each(|(addr, failures_so_far)| {
            let span = make_span(addr, self.outgoing.get(&addr));

            span.in_scope(|| {
                self.change_outgoing_state(
                    addr,
                    OutgoingState::Waiting {
                        failures_so_far,
                        error: None,
                        last_failure: now,
                    },
                )
            });
        });

        // Reconnect all others.
        to_reconnect
            .into_iter()
            .map(|(addr, failures_so_far)| {
                let span = make_span(addr, self.outgoing.get(&addr));

                span.clone().in_scope(|| {
                    self.change_outgoing_state(
                        addr,
                        OutgoingState::Connecting {
                            failures_so_far,
                            since: now,
                        },
                    )
                });

                DialRequest::Dial { addr, span }
            })
            .collect()
    }
/// Performs housekeeping like reconnection or unblocking peers.
///
/// This function must periodically be called. A good interval is every second.
Performs housekeeping like reconnection or unblocking peers.
This function must periodically be called. A good interval is every second.
Performs housekeeping like reconnection or unblocking peers . This function must periodically be called . A good interval is every second .
pub(super) fn perform_housekeeping(&mut self, now: Instant) -> Vec<DialRequest<H>> {
        let mut to_forget = Vec::new();
        let mut to_fail = Vec::new();
        let mut to_reconnect = Vec::new();
        for (&addr, outgoing) in self.outgoing.iter() {
            let span = make_span(addr, Some(outgoing));
            span.in_scope(|| match outgoing.state {
                // Decide whether to attempt reconnecting a failed-waiting address.
                OutgoingState::Waiting {
                    failures_so_far,
                    last_failure,
                    ..
                } => {
                    if failures_so_far > self.config.retry_attempts {
                        if outgoing.is_unforgettable {
                            // Unforgettable addresses simply have their timer reset.
                            info!("unforgettable address reset");
                            to_reconnect.push((addr, 0));
                        } else {
                            // Address had too many attempts at reconnection, we will forget
                            // it after exiting this closure.
                            to_forget.push(addr);
                            info!("address forgotten");
                        }
                    } else {
                        // The address has not exceeded the limit, so check if it is due.
                        let due = last_failure + self.config.calc_backoff(failures_so_far);
                        if now >= due {
                            debug!(attempts = failures_so_far, "address reconnecting");
                            to_reconnect.push((addr, failures_so_far));
                        }
                    }
                }
                OutgoingState::Blocked { since } => {
                    if now >= since + self.config.unblock_after {
                        info!("address unblocked");
                        to_reconnect.push((addr, 0));
                    }
                }
                OutgoingState::Connecting {
                    since,
                    failures_so_far,
                } => {
                    let timeout = since + self.config.sweep_timeout;
                    if now >= timeout {
                        // The outer component has not called us with a `DialOutcome` in a
                        // reasonable amount of time. This should happen very rarely, ideally
                        // never.
                        warn!("address timed out connecting, was swept");
                        // Count the timeout as a failure against the connection.
                        to_fail.push((addr, failures_so_far + 1));
                    }
                }
                OutgoingState::Connected { .. } | OutgoingState::Loopback => {
                    // Entry is ignored. Not outputting any `trace` because this is log spam even at
                    // the `trace` level.
                }
            });
        }
        // Remove all addresses marked for forgetting.
        to_forget.into_iter().for_each(|addr| {
            self.outgoing.remove(&addr);
        });
        // Fail connections that are taking way too long to connect.
        to_fail.into_iter().for_each(|(addr, failures_so_far)| {
            let span = make_span(addr, self.outgoing.get(&addr));
            span.in_scope(|| {
                self.change_outgoing_state(
                    addr,
                    OutgoingState::Waiting {
                        failures_so_far,
                        error: None,
                        last_failure: now,
                    },
                )
            });
        });
        // Reconnect all others.
        to_reconnect
            .into_iter()
            .map(|(addr, failures_so_far)| {
                let span = make_span(addr, self.outgoing.get(&addr));
                span.clone().in_scope(|| {
                    self.change_outgoing_state(
                        addr,
                        OutgoingState::Connecting {
                            failures_so_far,
                            since: now,
                        },
                    )
                });
                DialRequest::Dial { addr, span }
            })
            .collect()
    }
pub ( super ) fn perform_housekeeping ( & mut self , now : Instant ) -> Vec < DialRequest < H > > { let mut to_forget = Vec :: new ( ) ; let mut to_fail = Vec :: new ( ) ; let mut to_reconnect = Vec :: new ( ) ; for ( & addr , outgoing ) in self . outgoing . iter ( ) { let span = make_span ( addr , Some ( outgoing ) ) ; span . in_scope ( | | match outgoing . state { // Decide whether to attempt reconnecting a failed-waiting address. OutgoingState :: Waiting { failures_so_far , last_failure , .. } => { if failures_so_far > self . config . retry_attempts { if outgoing . is_unforgettable { // Unforgettable addresses simply have their timer reset. info ! ( " " ) ; to_reconnect . push ( ( addr , 0 ) ) ; } else { // Address had too many attempts at reconnection, we will forget // it after exiting this closure. to_forget . push ( addr ) ; info ! ( " " ) ; } } else { // The address has not exceeded the limit, so check if it is due. let due = last_failure + self . config . calc_backoff ( failures_so_far ) ; if now >= due { debug ! ( attempts failures_so_far " " ) ; to_reconnect . push ( ( addr , failures_so_far ) ) ; } } } OutgoingState :: Blocked { since } => { if now >= since + self . config . unblock_after { info ! ( " " ) ; to_reconnect . push ( ( addr , 0 ) ) ; } } OutgoingState :: Connecting { since , failures_so_far , } => { let timeout = since + self . config . sweep_timeout ; if now >= timeout { // The outer component has not called us with a `DialOutcome` in a // reasonable amount of time. This should happen very rarely, ideally // never. warn ! ( " " ) ; // Count the timeout as a failure against the connection. to_fail . push ( ( addr , failures_so_far + 1 ) ) ; } } OutgoingState :: Connected { .. } | OutgoingState :: Loopback => { // Entry is ignored. Not outputting any `trace` because this is log spam even at // the `trace` level. } } ) ; } // Remove all addresses marked for forgetting. to_forget . into_iter ( ) . for_each ( | addr | { self . outgoing . remove ( & addr ) ; } ) ; // Fail connections that are taking way too long to connect. to_fail . into_iter ( ) . for_each ( | ( addr , failures_so_far ) | { let span = make_span ( addr , self . outgoing . get ( & addr ) ) ; span . in_scope ( | | { self . change_outgoing_state ( addr , OutgoingState :: Waiting { failures_so_far , error : None , last_failure : now , } , ) } ) ; } ) ; // Reconnect all others. to_reconnect . into_iter ( ) . map ( | ( addr , failures_so_far ) | { let span = make_span ( addr , self . outgoing . get ( & addr ) ) ; span . clone ( ) . in_scope ( | | { self . change_outgoing_state ( addr , OutgoingState :: Connecting { failures_so_far , since : now , } , ) } ) ; DialRequest :: Dial { addr , span } } ) . collect ( ) }
Performs housekeeping like reconnection or unblocking peers.
Performs housekeeping like reconnection or unblocking peers .
&mut self
now
Instant
&mut self
now
Instant