Skip to main content

submilli_engine/runtime/
durable.rs

1//! Shared identities for durable execution.
2
3/// Identity of one run. Its effects and resource handles share this namespace.
4#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
5#[serde(transparent)]
6pub struct RunId(pub String);
7
8impl From<String> for RunId {
9    fn from(value: String) -> Self {
10        Self(value)
11    }
12}
13impl From<&str> for RunId {
14    fn from(value: &str) -> Self {
15        Self(value.to_owned())
16    }
17}
18impl std::ops::Deref for RunId {
19    type Target = str;
20    fn deref(&self) -> &str {
21        self.as_str()
22    }
23}
24impl std::fmt::Display for RunId {
25    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        formatter.write_str(self.as_str())
27    }
28}
29impl RunId {
30    pub fn as_str(&self) -> &str {
31        &self.0
32    }
33}
34
35/// Identity of one logical call. Retries must reuse it; distinct calls must not.
36#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
37#[serde(transparent)]
38pub struct EffectId(pub String);
39impl From<String> for EffectId {
40    fn from(value: String) -> Self {
41        Self(value)
42    }
43}
44impl From<&str> for EffectId {
45    fn from(value: &str) -> Self {
46        Self(value.to_owned())
47    }
48}
49impl std::ops::Deref for EffectId {
50    type Target = str;
51    fn deref(&self) -> &str {
52        &self.0
53    }
54}
55impl std::fmt::Display for EffectId {
56    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        formatter.write_str(self.as_str())
58    }
59}
60
61impl EffectId {
62    pub fn as_str(&self) -> &str {
63        &self.0
64    }
65
66    /// Temporary per-call identity until durable execution supplies stable IDs.
67    /// This stub is not replay-stable; backend retries must retain their ID.
68    pub fn stub() -> std::io::Result<Self> {
69        let mut bytes = [0; 16];
70        getrandom::getrandom(&mut bytes)
71            .map_err(|error| std::io::Error::other(format!("effect ID entropy: {error}")))?;
72        Ok(uuid::Builder::from_random_bytes(bytes)
73            .into_uuid()
74            .to_string()
75            .into())
76    }
77}