rust_langgraph/
runtime.rs1use crate::config::Config;
7use std::sync::Arc;
8use tokio::sync::RwLock;
9
10#[derive(Debug, Clone)]
27pub struct Runtime {
28 config: Config,
29 checkpoint_id: Option<String>,
30 step: usize,
31}
32
33impl Runtime {
34 pub fn new(config: Config) -> Self {
36 Self {
37 config,
38 checkpoint_id: None,
39 step: 0,
40 }
41 }
42
43 pub fn config(&self) -> &Config {
45 &self.config
46 }
47
48 pub fn checkpoint_id(&self) -> Option<&str> {
50 self.checkpoint_id.as_deref()
51 }
52
53 pub fn step(&self) -> usize {
55 self.step
56 }
57
58 pub fn set_checkpoint_id(&mut self, id: impl Into<String>) {
60 self.checkpoint_id = Some(id.into());
61 }
62
63 pub fn increment_step(&mut self) {
65 self.step += 1;
66 }
67
68 pub fn thread_id(&self) -> Option<&str> {
70 self.config.thread_id.as_deref()
71 }
72}
73
74pub type SharedRuntime = Arc<RwLock<Runtime>>;
76
77pub fn shared_runtime(config: Config) -> SharedRuntime {
79 Arc::new(RwLock::new(Runtime::new(config)))
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn test_runtime_creation() {
88 let config = Config::new().with_thread_id("test");
89 let runtime = Runtime::new(config);
90
91 assert_eq!(runtime.thread_id(), Some("test"));
92 assert_eq!(runtime.step(), 0);
93 assert!(runtime.checkpoint_id().is_none());
94 }
95
96 #[test]
97 fn test_runtime_mutations() {
98 let config = Config::new();
99 let mut runtime = Runtime::new(config);
100
101 runtime.set_checkpoint_id("checkpoint-1");
102 assert_eq!(runtime.checkpoint_id(), Some("checkpoint-1"));
103
104 runtime.increment_step();
105 assert_eq!(runtime.step(), 1);
106
107 runtime.increment_step();
108 assert_eq!(runtime.step(), 2);
109 }
110
111 #[tokio::test]
112 async fn test_shared_runtime() {
113 let config = Config::new();
114 let runtime = shared_runtime(config);
115
116 {
117 let mut rt = runtime.write().await;
118 rt.increment_step();
119 }
120
121 {
122 let rt = runtime.read().await;
123 assert_eq!(rt.step(), 1);
124 }
125 }
126}