liminal-server 0.25.4

Standalone server for the liminal messaging bus
Documentation
//! The connection process's participant publications: registered once, served
//! under the push slice budget, and released at teardown.

use super::{ConnectionTransport, TransportConnectionProcess};
use crate::ServerError;
use crate::server::connection::participant_delivery::{
    UNIT2_PUSH_SLICE_BUDGET, service_participant_publications,
};
use beamr::native::native_process::NativeOutcome;

impl<T: ConnectionTransport> TransportConnectionProcess<T> {
    pub(super) fn service_participant_pushes(&mut self, pid: u64) -> Option<NativeOutcome> {
        let service = self.runtime.participant_service()?;
        #[cfg(test)]
        let held_before = self.state.held_pushes.participant_len();
        let result = service_participant_publications(
            &mut self.state,
            service,
            &mut self.outbound,
            UNIT2_PUSH_SLICE_BUDGET,
        );
        #[cfg(test)]
        let result = if std::mem::take(&mut self.fail_next_pump) {
            Err(
                super::super::participant_delivery::ParticipantPumpError::Semantic(
                    crate::server::participant::ParticipantSemanticError::Unavailable,
                ),
            )
        } else {
            result
        };
        if let Err(error) = result
            && !error.is_capacity_refusal()
        {
            tracing::error!(
                connection_pid = pid,
                %error,
                "participant publication failed; tearing down the connection"
            );
            return Some(self.tear_down_lost(pid));
        }
        #[cfg(test)]
        if self.state.held_pushes.participant_len() > held_before
            && self.runtime.pause_participant_holdback(pid)
        {
            self.runtime.mark_parked(pid);
            return Some(NativeOutcome::Wait);
        }
        None
    }

    pub(super) fn ensure_participant_publication_registered(
        &mut self,
        pid: u64,
    ) -> Result<(), ServerError> {
        if self.state.participant_publication_registered {
            return Ok(());
        }
        let (Some(incarnation), Some(inbox), Some(service), Some(waker)) = (
            self.state.connection_incarnation,
            self.state.participant_publication.as_ref(),
            self.runtime.participant_service(),
            self.runtime.ready_waker(pid),
        ) else {
            return Ok(());
        };
        service
            .publication_registry()
            .register(incarnation, inbox, waker)
            .map_err(participant_publication_error)?;
        self.state.participant_publication_registered = true;
        Ok(())
    }

    pub(super) fn release_participant_publication(&mut self) {
        if self.state.participant_publication_registered {
            if let (Some(incarnation), Some(service)) = (
                self.state.connection_incarnation,
                self.runtime.participant_service(),
            ) {
                service.publication_registry().deregister(incarnation);
            }
            self.state.participant_publication_registered = false;
        }
    }
}

pub(super) fn participant_publication_error(
    error: crate::server::participant::ParticipantPublicationError,
) -> ServerError {
    ServerError::ListenerAccept {
        message: format!("participant publication registry failed: {error}"),
    }
}