pub fn spawn(
        config: &Config,
        local_listener: SocketAddr,
    ) -> (
        Arc<std::sync::Mutex<AddressBook>>,
        mpsc::Sender<MetaAddrChange>,
        watch::Receiver<AddressMetrics>,
        JoinHandle<Result<(), BoxError>>,
    ) {
        use tracing::Level;

        // Create an mpsc channel for peerset address book updates,
        // based on the maximum number of inbound and outbound peers.
        let (worker_tx, mut worker_rx) = mpsc::channel(config.peerset_total_connection_limit());

        let address_book =
            AddressBook::new(local_listener, span!(Level::TRACE, "address book updater"));
        let address_metrics = address_book.address_metrics_watcher();
        let address_book = Arc::new(std::sync::Mutex::new(address_book));

        let worker_address_book = address_book.clone();
        let worker = move || {
            while let Some(event) = worker_rx.blocking_recv() {
                // # Correctness
                //
                // Briefly hold the address book threaded mutex, to update the
                // state for a single address.
                worker_address_book
                    .lock()
                    .expect("mutex should be unpoisoned")
                    .update(event);
            }

            Err(AllAddressBookUpdaterSendersClosed.into())
        };

        // Correctness: spawn address book accesses on a blocking thread,
        //              to avoid deadlocks (see #1976)
        let address_book_updater_task_handle = tokio::task::spawn_blocking(worker);

        (
            address_book,
            worker_tx,
            address_metrics,
            address_book_updater_task_handle,
        )
    }
/// Spawn a new [`AddressBookUpdater`] task, updating a new [`AddressBook`]
/// configured with Zebra's actual `local_listener` address.
///
/// Returns handles for:
/// - the address book,
/// - the transmission channel for address book update events,
/// - a watch channel for address book metrics, and
/// - the address book updater task join handle.
///
/// The task exits with an error when the returned [`mpsc::Sender`] is closed.


Returns handles for:
the address book,
the transmission channel for address book update events,
a watch channel for address book metrics, and
the address book updater task join handle.

The task exits with an error when the returned [`mpsc::Sender`] is closed.
Returns handles for : the address book the transmission channel for address book update events a watch channel for address book metrics and the address book updater task join handle . The task exits with an error when the returned [ ` mpsc :: Sender ` ] is closed .
pub fn spawn(
        config: &Config,
        local_listener: SocketAddr,
    ) -> (
        Arc<std::sync::Mutex<AddressBook>>,
        mpsc::Sender<MetaAddrChange>,
        watch::Receiver<AddressMetrics>,
        JoinHandle<Result<(), BoxError>>,
    ) {
        use tracing::Level;
        // Create an mpsc channel for peerset address book updates,
        // based on the maximum number of inbound and outbound peers.
        let (worker_tx, mut worker_rx) = mpsc::channel(config.peerset_total_connection_limit());
        let address_book =
            AddressBook::new(local_listener, span!(Level::TRACE, "address book updater"));
        let address_metrics = address_book.address_metrics_watcher();
        let address_book = Arc::new(std::sync::Mutex::new(address_book));
        let worker_address_book = address_book.clone();
        let worker = move || {
            while let Some(event) = worker_rx.blocking_recv() {
                // # Correctness
                //
                // Briefly hold the address book threaded mutex, to update the
                // state for a single address.
                worker_address_book
                    .lock()
                    .expect("mutex should be unpoisoned")
                    .update(event);
            }
            Err(AllAddressBookUpdaterSendersClosed.into())
        };
        // Correctness: spawn address book accesses on a blocking thread,
        //              to avoid deadlocks (see #1976)
        let address_book_updater_task_handle = tokio::task::spawn_blocking(worker);
        (
            address_book,
            worker_tx,
            address_metrics,
            address_book_updater_task_handle,
        )
    }
pub fn spawn ( config : & Config , local_listener : SocketAddr , ) -> ( Arc < std :: sync :: Mutex < AddressBook > > , mpsc :: Sender < MetaAddrChange > , watch :: Receiver < AddressMetrics > , JoinHandle < Result < ( ) , BoxError > > , ) { use tracing :: Level ; // Create an mpsc channel for peerset address book updates, // based on the maximum number of inbound and outbound peers. let ( worker_tx , mut worker_rx ) = mpsc :: channel ( config . peerset_total_connection_limit ( ) ) ; let address_book = AddressBook :: new ( local_listener , span ! ( Level TRACE " " ) ) ; let address_metrics = address_book . address_metrics_watcher ( ) ; let address_book = Arc :: new ( std :: sync :: Mutex :: new ( address_book ) ) ; let worker_address_book = address_book . clone ( ) ; let worker = move | | { while let Some ( event ) = worker_rx . blocking_recv ( ) { // # Correctness // // Briefly hold the address book threaded mutex, to update the // state for a single address. worker_address_book . lock ( ) . expect ( " " ) . update ( event ) ; } Err ( AllAddressBookUpdaterSendersClosed . into ( ) ) } ; // Correctness: spawn address book accesses on a blocking thread, //              to avoid deadlocks (see #1976) let address_book_updater_task_handle = tokio :: task :: spawn_blocking ( worker ) ; ( address_book , worker_tx , address_metrics , address_book_updater_task_handle , ) }
Spawn a new [`AddressBookUpdater`] task, updating a new [`AddressBook`]
configured with Zebra's actual `local_listener` address.
Spawn a new [ ` AddressBookUpdater ` ] task updating a new [ ` AddressBook ` ] configured with Zebra ' s actual ` local_listener ` address .
config
&Config
local_listener
SocketAddr