2019-10-17 15:42:19 -07:00
|
|
|
//! The timestamp collector collects liveness information from peers.
|
2019-10-07 15:36:16 -07:00
|
|
|
|
2021-06-22 14:59:06 -07:00
|
|
|
use std::{net::SocketAddr, sync::Arc};
|
2019-10-07 15:36:16 -07:00
|
|
|
|
2019-12-13 14:25:14 -08:00
|
|
|
use futures::{channel::mpsc, prelude::*};
|
2021-11-18 04:34:51 -08:00
|
|
|
use thiserror::Error;
|
|
|
|
use tokio::task::JoinHandle;
|
2019-10-07 15:36:16 -07:00
|
|
|
|
2021-11-18 04:34:51 -08:00
|
|
|
use crate::{meta_addr::MetaAddrChange, AddressBook, BoxError, Config};
|
2019-10-07 15:36:16 -07:00
|
|
|
|
2021-11-04 04:34:00 -07:00
|
|
|
/// The `AddressBookUpdater` hooks into incoming message streams for each peer
|
|
|
|
/// and lets the owner of the sender handle update the address book. For
|
|
|
|
/// example, it can be used to record per-connection last-seen timestamps, or
|
|
|
|
/// add new initial peers to the address book.
|
2021-11-18 04:34:51 -08:00
|
|
|
#[derive(Debug, Eq, PartialEq)]
|
|
|
|
pub struct AddressBookUpdater;
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, Debug, Error, Eq, PartialEq, Hash)]
|
|
|
|
#[error("all address book updater senders are closed")]
|
|
|
|
pub struct AllAddressBookUpdaterSendersClosed;
|
2019-10-07 15:36:16 -07:00
|
|
|
|
2021-11-04 04:34:00 -07:00
|
|
|
impl AddressBookUpdater {
|
|
|
|
/// Spawn a new [`AddressBookUpdater`] task, updating a new [`AddressBook`]
|
2021-11-18 04:34:51 -08:00
|
|
|
/// configured with Zebra's actual `local_listener` address.
|
2021-06-22 14:59:06 -07:00
|
|
|
///
|
2021-11-18 04:34:51 -08:00
|
|
|
/// Returns handles for:
|
|
|
|
/// - the transmission channel for address book update events,
|
|
|
|
/// - the address book, and
|
|
|
|
/// - the address book updater task.
|
2021-06-14 20:31:16 -07:00
|
|
|
pub fn spawn(
|
2021-11-18 04:34:51 -08:00
|
|
|
config: &Config,
|
2021-06-22 14:59:06 -07:00
|
|
|
local_listener: SocketAddr,
|
2021-06-14 20:31:16 -07:00
|
|
|
) -> (
|
|
|
|
Arc<std::sync::Mutex<AddressBook>>,
|
|
|
|
mpsc::Sender<MetaAddrChange>,
|
2021-11-18 04:34:51 -08:00
|
|
|
JoinHandle<Result<(), BoxError>>,
|
2021-06-14 20:31:16 -07:00
|
|
|
) {
|
2019-10-21 15:56:16 -07:00
|
|
|
use tracing::Level;
|
2021-11-18 04:34:51 -08:00
|
|
|
|
|
|
|
// 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());
|
|
|
|
|
2021-05-06 18:08:06 -07:00
|
|
|
let address_book = Arc::new(std::sync::Mutex::new(AddressBook::new(
|
2021-06-22 14:59:06 -07:00
|
|
|
local_listener,
|
2021-11-18 04:34:51 -08:00
|
|
|
span!(Level::TRACE, "address book updater"),
|
2021-05-06 18:08:06 -07:00
|
|
|
)));
|
2019-10-17 16:38:44 -07:00
|
|
|
let worker_address_book = address_book.clone();
|
2019-10-07 15:36:16 -07:00
|
|
|
|
|
|
|
let worker = async move {
|
2019-10-17 16:38:44 -07:00
|
|
|
while let Some(event) = worker_rx.next().await {
|
2021-04-18 23:04:24 -07:00
|
|
|
// # Correctness
|
|
|
|
//
|
|
|
|
// Briefly hold the address book threaded mutex, to update the
|
|
|
|
// state for a single address.
|
2019-10-17 16:38:44 -07:00
|
|
|
worker_address_book
|
|
|
|
.lock()
|
|
|
|
.expect("mutex should be unpoisoned")
|
|
|
|
.update(event);
|
2019-10-07 15:36:16 -07:00
|
|
|
}
|
2021-11-18 04:34:51 -08:00
|
|
|
|
|
|
|
Err(AllAddressBookUpdaterSendersClosed.into())
|
2019-10-07 15:36:16 -07:00
|
|
|
};
|
|
|
|
|
2021-11-18 04:34:51 -08:00
|
|
|
let address_book_updater_task_handle = tokio::spawn(worker.boxed());
|
|
|
|
|
|
|
|
(address_book, worker_tx, address_book_updater_task_handle)
|
2019-10-07 15:36:16 -07:00
|
|
|
}
|
|
|
|
}
|