liminal-server 0.24.1

Standalone server for the liminal messaging bus
Documentation
//! Retry bounds and stop signals do not need a live peer or a clock wait.
use super::{FIRST_RETRY, MAX_RETRY, OutboundLinkConfig, Slot, Wake};
use std::time::{Duration, Instant};
#[test]
fn peer_refused_open_is_counted_and_scheduled_like_a_failed_dial() -> Result<(), crate::ServerError>
{
    let services = std::sync::Arc::new(
        crate::server::connection::services::LiminalConnectionServices::empty()?,
    );
    let result = (|| {
        let registry = crate::link_bridge::BridgeRegistry::default();
        let wake = std::sync::Arc::new(Wake::default());
        let mut slot = Slot {
            entry: OutboundLinkConfig {
                link_id: "orders".to_owned(),
                peer_holder: "importer".to_owned(),
                peer_address: None,
                exports: vec!["orders".to_owned()],
            },
            bridge: None,
            retry_at: None,
            backoff: FIRST_RETRY,
            stopped: false,
        };
        let now = Instant::now();
        let reason = "link_refused:link_import needed".to_owned();
        super::answered(
            &mut slot,
            super::ChoiceOutcome::Refused {
                reason: reason.clone(),
            },
            &services,
            &registry,
            &wake,
            true,
            now,
        )?;
        let counters = registry.snapshot().remove("orders").unwrap_or_default();
        assert_eq!(counters.refused, 1, "peer refusal absent from health");
        assert_eq!(counters.dial_refused, 0);
        assert!(counters.refused_subjects.is_empty());
        assert_eq!(counters.last_refusal, Some(reason));
        assert!(!slot.stopped, "peer refusal stopped retries");
        assert_eq!(slot.retry_at, now.checked_add(FIRST_RETRY));
        assert_eq!(slot.backoff, FIRST_RETRY * 2);
        Ok(())
    })();
    let supervisor = crate::server::connection::ConnectionSupervisor::with_services(services)?;
    let stopped = crate::server::runtime::runtime_links::shutdown(
        &supervisor,
        Duration::ZERO,
        || Ok(()),
        (
            &mut crate::server::runtime::runtime_links::ConfiguredLinks::default(),
            || Ok(()),
        ),
    );
    crate::server::runtime::raise_in_precedence(result, stopped)
}
#[test]
fn retry_backoff_starts_at_one_second_and_caps_at_thirty() -> Result<(), crate::ServerError> {
    let mut slot = Slot {
        entry: OutboundLinkConfig {
            link_id: "orders".to_owned(),
            peer_holder: "importer".to_owned(),
            peer_address: None,
            exports: vec!["orders".to_owned()],
        },
        bridge: None,
        retry_at: None,
        backoff: FIRST_RETRY,
        stopped: false,
    };
    let now = Instant::now();
    for seconds in [1, 2, 4, 8, 16, 30, 30] {
        slot.schedule_at(now)?;
        assert_eq!(slot.retry_at, now.checked_add(Duration::from_secs(seconds)));
    }
    assert_eq!(slot.backoff, MAX_RETRY);
    Ok(())
}
#[test]
fn shutdown_releases_retry_wait_without_reaching_its_deadline() -> Result<(), crate::ServerError> {
    let wake = Wake::default();
    wake.stop()?;
    wake.wait(Instant::now().checked_add(MAX_RETRY))?;
    assert!(wake.stopping()?);
    Ok(())
}