liminal-server 0.23.1

Standalone server for the liminal messaging bus
Documentation
//! The previous incarnation's stop, witnessed by the capacity publication.
use super::capacity_snapshot::{CapacitySnapshot, read_capacity_snapshot};
use crate::server::participant::ParticipantSemanticError;
use liminal::durability::DurableStore;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(super) enum PreviousStop {
    Clean,
    Unclean,
    Unknown,
}

pub(super) struct ConversationRepair {
    pub(super) server_incarnation: u64,
    pub(super) conversation_id: u64,
    pub(super) done: usize,
    pub(super) total: usize,
    pub(super) appended_rows: u64,
    pub(super) conversation_elapsed_ms: u64,
    pub(super) elapsed_ms: u64,
}

impl PreviousStop {
    pub(super) fn read(
        store: &dyn DurableStore,
        current: u64,
    ) -> Result<Self, ParticipantSemanticError> {
        if current == 1 {
            return Ok(Self::Unknown);
        }
        match read_capacity_snapshot(store)? {
            Some((_, Ok(CapacitySnapshot::LegacyCleanStop(_)))) => Ok(Self::Unknown),
            Some((
                _,
                Ok(CapacitySnapshot::CleanStop {
                    server_incarnation, ..
                }),
            )) if server_incarnation.checked_add(1) == Some(current) => Ok(Self::Clean),
            Some((_, Err(refusal))) => {
                tracing::warn!(%refusal, "previous stop's capacity publication was refused by name");
                Ok(Self::Unclean)
            }
            _ => Ok(Self::Unclean),
        }
    }

    pub(super) const fn name(self) -> &'static str {
        match self {
            Self::Clean => "clean",
            Self::Unclean => "unclean",
            Self::Unknown => "unknown",
        }
    }

    pub(super) fn started(self, server_incarnation: u64, conversations: usize) {
        if self == Self::Unclean {
            tracing::warn!(
                step = "restart repair",
                server_incarnation,
                conversations,
                previous_stop = self.name(),
                "restart repair started"
            );
        } else {
            tracing::info!(
                step = "restart repair",
                server_incarnation,
                conversations,
                previous_stop = self.name(),
                "restart repair started"
            );
        }
    }

    pub(super) fn conversation_finished(self, progress: &ConversationRepair) {
        if self == Self::Unclean {
            tracing::warn!(
                step = "restart repair",
                previous_stop = self.name(),
                server_incarnation = progress.server_incarnation,
                conversation_id = progress.conversation_id,
                done = progress.done,
                total = progress.total,
                appended_rows = progress.appended_rows,
                conversation_elapsed_ms = progress.conversation_elapsed_ms,
                elapsed_ms = progress.elapsed_ms,
                "restart repair finished a conversation"
            );
        } else {
            tracing::info!(
                step = "restart repair",
                previous_stop = self.name(),
                server_incarnation = progress.server_incarnation,
                conversation_id = progress.conversation_id,
                done = progress.done,
                total = progress.total,
                appended_rows = progress.appended_rows,
                conversation_elapsed_ms = progress.conversation_elapsed_ms,
                elapsed_ms = progress.elapsed_ms,
                "restart repair finished a conversation"
            );
        }
    }

    pub(super) fn finished(self, server_incarnation: u64, conversations: usize, elapsed_ms: u64) {
        if self == Self::Unclean {
            tracing::warn!(
                step = "restart repair",
                server_incarnation,
                conversations,
                previous_stop = self.name(),
                elapsed_ms,
                "restart repair finished"
            );
        } else {
            tracing::info!(
                step = "restart repair",
                server_incarnation,
                conversations,
                previous_stop = self.name(),
                elapsed_ms,
                "restart repair finished"
            );
        }
    }
}