synwire_checkpoint/types.rs
1//! Checkpoint types for persisting graph state.
2
3use std::collections::HashMap;
4
5use serde::{Deserialize, Serialize};
6
7/// A checkpoint of graph state.
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Checkpoint {
10 /// Unique checkpoint ID.
11 pub id: String,
12 /// Channel values at this checkpoint.
13 pub channel_values: HashMap<String, serde_json::Value>,
14 /// Channel versions for conflict detection.
15 pub channel_versions: HashMap<String, ChannelVersion>,
16 /// Pending writes not yet applied.
17 pub pending_writes: Vec<PendingWrite>,
18 /// Format version for migration support.
19 pub format_version: String,
20}
21
22impl Checkpoint {
23 /// Create a new checkpoint with the given ID and default values.
24 pub fn new(id: String) -> Self {
25 Self {
26 id,
27 channel_values: HashMap::new(),
28 channel_versions: HashMap::new(),
29 pending_writes: Vec::new(),
30 format_version: "1.0".into(),
31 }
32 }
33}
34
35/// A version marker for a channel, used for conflict detection.
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct ChannelVersion {
38 /// The monotonically increasing version number.
39 pub version: u64,
40}
41
42/// A pending write that has not yet been applied to the checkpoint.
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct PendingWrite {
45 /// The channel this write targets.
46 pub channel: String,
47 /// The value to write.
48 pub value: serde_json::Value,
49}
50
51/// Metadata associated with a checkpoint.
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct CheckpointMetadata {
54 /// The source that created this checkpoint.
55 pub source: CheckpointSource,
56 /// The step number in the graph execution.
57 pub step: i64,
58 /// Writes that were applied at this step.
59 pub writes: HashMap<String, serde_json::Value>,
60 /// Parent checkpoint references.
61 pub parents: HashMap<String, String>,
62}
63
64/// The source of a checkpoint creation.
65#[derive(Debug, Clone, Serialize, Deserialize)]
66#[non_exhaustive]
67pub enum CheckpointSource {
68 /// Checkpoint created from initial input.
69 Input,
70 /// Checkpoint created during a loop iteration.
71 Loop,
72 /// Checkpoint created from an explicit update.
73 Update,
74}
75
76/// A complete checkpoint tuple containing all associated data.
77#[derive(Debug, Clone)]
78pub struct CheckpointTuple {
79 /// The configuration that identifies this checkpoint.
80 pub config: CheckpointConfig,
81 /// The checkpoint data.
82 pub checkpoint: Checkpoint,
83 /// Metadata about how this checkpoint was created.
84 pub metadata: CheckpointMetadata,
85 /// The parent checkpoint configuration, if any.
86 pub parent_config: Option<CheckpointConfig>,
87}
88
89/// Configuration identifying a checkpoint within a thread.
90#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct CheckpointConfig {
92 /// The thread ID this checkpoint belongs to.
93 pub thread_id: String,
94 /// The specific checkpoint ID, if targeting an exact checkpoint.
95 pub checkpoint_id: Option<String>,
96}
97
98/// Errors that can occur during checkpoint operations.
99#[derive(Debug, thiserror::Error)]
100#[non_exhaustive]
101pub enum CheckpointError {
102 /// The requested checkpoint was not found.
103 #[error("checkpoint not found")]
104 NotFound,
105 /// The serialized state exceeds the configured maximum size.
106 #[error("state too large: {size} bytes exceeds max {max}")]
107 StateTooLarge {
108 /// The actual size of the serialized state.
109 size: usize,
110 /// The maximum allowed size.
111 max: usize,
112 },
113 /// A serialization or deserialization error occurred.
114 #[error("serialization error: {0}")]
115 Serialization(String),
116 /// An error occurred in the underlying storage backend.
117 #[error("storage error: {0}")]
118 Storage(String),
119}