liminal-server 0.23.1

Standalone server for the liminal messaging bus
Documentation
//! Deadline timer ownership follows the pending entry.

use super::{Duration, EntryState, Instant, PendingReplyTable, TimerRef};

impl PendingReplyTable {
    /// Pending entries admitted in this slice that still need their one timer.
    pub(in crate::server::connection) fn timers_to_arm(
        &self,
        now: Instant,
    ) -> Vec<(u64, Duration)> {
        self.entries
            .iter()
            .filter(|entry| entry.state == EntryState::Pending && entry.timer.is_none())
            .map(|entry| (entry.op_id, entry.deadline.saturating_duration_since(now)))
            .collect()
    }

    /// Attaches the timer minted for `op_id`. Failure means the entry completed
    /// between candidate collection and installation, so the caller cancels it.
    pub(in crate::server::connection) fn install_timer(
        &mut self,
        op_id: u64,
        timer: TimerRef,
    ) -> bool {
        let Some(entry) = self.entries.iter_mut().find(|entry| entry.op_id == op_id) else {
            return false;
        };
        if entry.state != EntryState::Pending || entry.timer.is_some() {
            return false;
        }
        entry.timer = Some(timer);
        true
    }

    /// Timer handles whose entries completed or closed since the last sync.
    pub(in crate::server::connection) fn take_retired_timers(&mut self) -> Vec<TimerRef> {
        std::mem::take(&mut self.retired_timers)
    }

    /// Whether any pending deadline is already due; used by the final race probe.
    pub(in crate::server::connection) fn has_due(&self, now: Instant) -> bool {
        self.entries
            .iter()
            .any(|entry| entry.state == EntryState::Pending && entry.deadline <= now)
    }

    pub(super) fn retire_timer(&mut self, timer: Option<TimerRef>) {
        if let Some(timer) = timer {
            self.retired_timers.push(timer);
        }
    }
}