///|
/// Creates an empty execution counter set.
pub fn ExecutionMetrics::zero() -> ExecutionMetrics {
{
attempted: 0,
successful: 0,
rejected: 0,
guard_rejected: 0,
unknown_event: 0,
no_outgoing_state: 0,
duplicate_configuration: 0,
invalid_configuration: 0,
lifecycle_hooks: 0,
}
}
///|
/// Copies all counters so snapshots and public reads do not share mutable state.
pub fn ExecutionMetrics::copy(self : ExecutionMetrics) -> ExecutionMetrics {
{
attempted: self.attempted,
successful: self.successful,
rejected: self.rejected,
guard_rejected: self.guard_rejected,
unknown_event: self.unknown_event,
no_outgoing_state: self.no_outgoing_state,
duplicate_configuration: self.duplicate_configuration,
invalid_configuration: self.invalid_configuration,
lifecycle_hooks: self.lifecycle_hooks,
}
}
///|
fn ExecutionMetrics::record_success(self : ExecutionMetrics) -> Unit {
self.attempted += 1
self.successful += 1
}
///|
fn ExecutionMetrics::record_rejection(
self : ExecutionMetrics,
err : TransitionError,
) -> Unit {
self.attempted += 1
self.rejected += 1
match err {
GuardRejected => self.guard_rejected += 1
EventNotHandledInCurrentState => self.unknown_event += 1
NoTransitionsForCurrentState => self.no_outgoing_state += 1
DuplicateTransitionDefinition => self.duplicate_configuration += 1
InvalidConfiguration => self.invalid_configuration += 1
}
}
///|
fn ExecutionMetrics::record_hook(self : ExecutionMetrics) -> Unit {
self.lifecycle_hooks += 1
}
///|
/// Returns a copy of the execution metrics.
pub fn[S, E, Ctx] Engine::metrics(self : Engine[S, E, Ctx]) -> ExecutionMetrics {
self.metrics_value.copy()
}
///|
/// Returns the complete event-attempt audit log.
pub fn[S, E, Ctx] Engine::audit_log(
self : Engine[S, E, Ctx],
) -> Array[AuditRecord[S, E]] {
self.audit_entries.copy()
}
///|
/// Resets metrics and audit entries without changing workflow state.
pub fn[S, E, Ctx] Engine::reset_metrics(self : Engine[S, E, Ctx]) -> Unit {
self.metrics_value = ExecutionMetrics::zero()
self.audit_entries.clear()
}
///|
fn[S, E, Ctx] Engine::record_success(
self : Engine[S, E, Ctx],
from : S,
event : E,
to : S,
history_index : Int,
) -> Unit {
self.metrics_value.record_success()
self.audit_entries.push({
from,
to,
event,
success: true,
error: None,
history_index: Some(history_index),
})
}
///|
fn[S, E, Ctx] Engine::record_failure(
self : Engine[S, E, Ctx],
current : S,
event : E,
err : TransitionError,
) -> Unit {
self.metrics_value.record_rejection(err)
self.audit_entries.push({
from: current,
to: current,
event,
success: false,
error: Some(err),
history_index: None,
})
}
///|
fn[S, E, Ctx] Engine::record_hook(self : Engine[S, E, Ctx]) -> Unit {
self.metrics_value.record_hook()
}