Skip to main content

ranvier_core/
timeline.rs

1use serde::{Deserialize, Serialize};
2
3/// Represents a discrete event in the execution timeline.
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub enum TimelineEvent {
6    /// Execution started at a node
7    NodeEnter {
8        node_id: String,
9        node_label: String,
10        timestamp: u64,
11    },
12    /// Execution finished at a node
13    NodeExit {
14        node_id: String,
15        outcome_type: String, // "Next", "Branch", "Error"
16        duration_ms: u64,
17        timestamp: u64,
18    },
19    /// Execution paused at a node (debugger)
20    NodePaused { node_id: String, timestamp: u64 },
21    /// A branch decision was made
22    Branchtaken { branch_id: String, timestamp: u64 },
23    /// A faulted node is being retried (DLQ RetryThenDlq policy)
24    NodeRetry {
25        node_id: String,
26        attempt: u32,
27        max_attempts: u32,
28        backoff_ms: u64,
29        timestamp: u64,
30    },
31    /// All retry attempts exhausted; event sent to Dead Letter Queue
32    DlqExhausted {
33        node_id: String,
34        total_attempts: u32,
35        timestamp: u64,
36    },
37}
38
39/// A sequential record of an execution session.
40#[derive(Debug, Clone, Serialize, Deserialize, Default)]
41pub struct Timeline {
42    pub events: Vec<TimelineEvent>,
43}
44
45impl Timeline {
46    pub fn new() -> Self {
47        Self::default()
48    }
49
50    pub fn push(&mut self, event: TimelineEvent) {
51        self.events.push(event);
52    }
53
54    /// Sort events by timestamp
55    pub fn sort(&mut self) {
56        self.events.sort_by_key(|e| match e {
57            TimelineEvent::NodeEnter { timestamp, .. } => *timestamp,
58            TimelineEvent::NodeExit { timestamp, .. } => *timestamp,
59            TimelineEvent::NodePaused { timestamp, .. } => *timestamp,
60            TimelineEvent::Branchtaken { timestamp, .. } => *timestamp,
61            TimelineEvent::NodeRetry { timestamp, .. } => *timestamp,
62            TimelineEvent::DlqExhausted { timestamp, .. } => *timestamp,
63        });
64    }
65}