use crate::{Result, context::NodeContext};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LifecycleEventKind {
NodeScheduled,
NodeStarted,
NodeCompleted,
NodeFailed,
NodeCancelled,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LifecycleEvent {
kind: LifecycleEventKind,
context: NodeContext,
}
impl LifecycleEvent {
#[must_use]
pub const fn new(kind: LifecycleEventKind, context: NodeContext) -> Self {
Self { kind, context }
}
#[must_use]
pub const fn kind(&self) -> LifecycleEventKind {
self.kind
}
#[must_use]
pub const fn context(&self) -> &NodeContext {
&self.context
}
}
pub trait LifecycleHook: Sync {
fn observe(&self, event: &LifecycleEvent) -> Result<()>;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct NoopLifecycleHook;
impl LifecycleHook for NoopLifecycleHook {
fn observe(&self, _event: &LifecycleEvent) -> Result<()> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::context::ExecutionMetadata;
use pureflow_types::{ExecutionId, NodeId, WorkflowId};
fn execution_id(value: &str) -> ExecutionId {
ExecutionId::new(value).expect("valid execution id")
}
fn node_id(value: &str) -> NodeId {
NodeId::new(value).expect("valid node id")
}
fn workflow_id(value: &str) -> WorkflowId {
WorkflowId::new(value).expect("valid workflow id")
}
fn execution() -> ExecutionMetadata {
ExecutionMetadata::first_attempt(execution_id("run-1"))
}
#[test]
fn lifecycle_event_carries_kind_and_context() {
let context: NodeContext =
NodeContext::new(workflow_id("flow"), node_id("node"), execution());
let event: LifecycleEvent = LifecycleEvent::new(LifecycleEventKind::NodeStarted, context);
assert_eq!(event.kind(), LifecycleEventKind::NodeStarted);
assert_eq!(event.context().node_id().as_str(), "node");
}
#[test]
fn noop_lifecycle_hook_accepts_events() {
let context: NodeContext =
NodeContext::new(workflow_id("flow"), node_id("node"), execution());
let event: LifecycleEvent = LifecycleEvent::new(LifecycleEventKind::NodeCompleted, context);
NoopLifecycleHook
.observe(&event)
.expect("noop hook should accept lifecycle events");
}
}