use super::super::channels::ChannelName;
use super::super::error::AionSurfaceError;
use super::super::types::{Payload, SignalPayload};
use crate::channel::{ChannelHandle, ChannelMode, Schema};
use crate::conversation::ParticipantPid;
#[derive(Clone, Debug)]
pub struct SignalDeclaration {
pub signal_name: String,
pub content_type: String,
pub payload_schema: Option<Schema>,
}
impl SignalDeclaration {
#[must_use]
pub fn new(signal_name: impl Into<String>, content_type: impl Into<String>) -> Self {
Self {
signal_name: signal_name.into(),
content_type: content_type.into(),
payload_schema: None,
}
}
#[must_use]
pub fn with_payload_schema(
signal_name: impl Into<String>,
content_type: impl Into<String>,
payload_schema: Schema,
) -> Self {
Self {
signal_name: signal_name.into(),
content_type: content_type.into(),
payload_schema: Some(payload_schema),
}
}
}
#[derive(Clone, Debug)]
pub struct SignalWorkflowConfig {
pub namespace: String,
pub workflow_id: String,
pub workflow_pid: ParticipantPid,
pub declarations: Vec<SignalDeclaration>,
pub mode: ChannelMode,
}
impl SignalWorkflowConfig {
#[must_use]
pub fn new(
namespace: impl Into<String>,
id: impl Into<String>,
pid: ParticipantPid,
declarations: Vec<SignalDeclaration>,
) -> Self {
Self {
namespace: namespace.into(),
workflow_id: id.into(),
workflow_pid: pid,
declarations,
mode: ChannelMode::Ephemeral,
}
}
#[must_use]
pub const fn with_mode(mut self, mode: ChannelMode) -> Self {
self.mode = mode;
self
}
}
#[derive(Clone, Debug)]
pub struct SignalChannel {
pub channel_name: ChannelName,
pub handle: ChannelHandle,
pub declarations: Vec<SignalDeclaration>,
pub mode: ChannelMode,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum WorkflowTerminalStatus {
Completed,
Failed,
Cancelled,
TimedOut,
}
impl WorkflowTerminalStatus {
pub(super) const fn as_str(self) -> &'static str {
match self {
Self::Completed => "Completed",
Self::Failed => "Failed",
Self::Cancelled => "Cancelled",
Self::TimedOut => "TimedOut",
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SignalOperationKind {
SignalDelivered,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SignalOperation {
pub kind: SignalOperationKind,
pub channel_name: String,
pub workflow_id: String,
pub signal_name: String,
pub payload: Payload,
pub mode: ChannelMode,
}
impl SignalOperation {
pub(super) fn delivered(
channel_name: &ChannelName,
workflow_id: &str,
signal: &SignalPayload,
mode: ChannelMode,
) -> Self {
Self {
kind: SignalOperationKind::SignalDelivered,
channel_name: String::from(channel_name.clone()),
workflow_id: workflow_id.to_owned(),
signal_name: signal.signal_name.clone(),
payload: signal.payload.clone(),
mode,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RecordedSignalDelivery {
pub channel_name: String,
pub workflow_id: String,
pub signal: SignalPayload,
}
impl RecordedSignalDelivery {
#[must_use]
pub const fn new(channel_name: String, workflow_id: String, signal: SignalPayload) -> Self {
Self {
channel_name,
workflow_id,
signal,
}
}
}
pub trait SignalDeliverer: std::fmt::Debug + Send + Sync {
fn deliver(
&self,
workflow_pid: ParticipantPid,
signal: SignalPayload,
) -> Result<(), AionSurfaceError>;
}
pub trait SignalRecorder: std::fmt::Debug + Send + Sync {
fn replay_deliveries(
&self,
channel_name: &str,
workflow_id: &str,
) -> Result<Vec<RecordedSignalDelivery>, AionSurfaceError>;
fn record(&self, operation: SignalOperation) -> Result<(), AionSurfaceError>;
}