use std::sync::mpsc;
use std::time::Duration;
use crate::channel::schema::{SchemaId, SchemaValidationError};
use crate::error::LiminalError;
pub(super) const COMMAND_TIMEOUT: Duration = Duration::from_secs(5);
enum WaitFailure {
Dead,
TimedOut,
}
pub(super) fn wait_live<T>(
response: &mpsc::Receiver<Result<T, LiminalError>>,
pid: u64,
) -> Result<Result<T, LiminalError>, LiminalError> {
receive(response).map_err(|failure| match failure {
WaitFailure::Dead => LiminalError::DeliveryFailed {
message: format!("channel actor pid {pid} died before replying"),
},
WaitFailure::TimedOut => LiminalError::DeliveryFailed {
message: "channel command timed out".to_owned(),
},
})
}
pub(super) fn wait_schema_live(
response: &mpsc::Receiver<Result<SchemaId, SchemaValidationError>>,
pid: u64,
) -> Result<Result<SchemaId, SchemaValidationError>, SchemaValidationError> {
receive(response).map_err(|failure| match failure {
WaitFailure::Dead => SchemaValidationError::InvalidSchema {
message: format!("channel actor pid {pid} died before evolving the schema"),
},
WaitFailure::TimedOut => SchemaValidationError::InvalidSchema {
message: "channel schema-evolution reply unavailable".to_owned(),
},
})
}
fn receive<R>(response: &mpsc::Receiver<R>) -> Result<R, WaitFailure> {
response
.recv_timeout(COMMAND_TIMEOUT)
.map_err(|error| match error {
mpsc::RecvTimeoutError::Disconnected => WaitFailure::Dead,
mpsc::RecvTimeoutError::Timeout => WaitFailure::TimedOut,
})
}