⎇ d6b8f18b43c9bd9bf7268e48b61392a2d62bb229
crates/ente-snapshot/src/lib.rs
Historia
Quién tocó qué
crudo
Pausa: 11 crates del fractal Ente #0 con cerebro completo
1//! Persistencia del fractal. Captura el estado live (Cards encarnadas con
2//! sus identidades preservadas) a un blob JSON. Al restaurar, las mismas
3//! Ulids vuelven a la vida — los PIDs cambian (kernel no los preserva) pero
4//! el grafo se reconstruye con la misma topología.
5//!
6//! Lo que NO se persiste:
7//! - PIDs (irrelevantes tras reboot)
8//! - bus_connections (runtime-only)
9//! - pending_invokes (en vuelo, se descartan)
10//! - device presence (uevents reconstruyen el índice)
11
12use ente_card::EntityCard;
13use serde::{Deserialize, Serialize};
14use std::path::Path;
15use ulid::Ulid;
16
17pub const SNAPSHOT_VERSION: u16 = 1;
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct FractalSnapshot {
21 pub version: u16,
22 pub timestamp_ms: u64,
23 pub seed_id: Ulid,
24 pub seed_label: String,
25 /// Cards live al momento del checkpoint, excluyendo la Semilla.
26 /// Al restaurar se inyectan en `genesis` con sus Ulids originales.
27 pub entes: Vec<EntityCard>,
28}
29
30impl FractalSnapshot {
31 pub fn write(&self, path: &Path) -> anyhow::Result<()> {
32 let bytes = serde_json::to_vec_pretty(self)?;
33 if let Some(parent) = path.parent() {
34 std::fs::create_dir_all(parent).ok();
35 }
36 // Escritura atómica: temp file + rename.
37 let tmp = path.with_extension("tmp");
38 std::fs::write(&tmp, &bytes)?;
39 std::fs::rename(&tmp, path)?;
40 Ok(())
41 }
42
43 pub fn read(path: &Path) -> anyhow::Result<Self> {
44 let bytes = std::fs::read(path)?;
45 let snap: FractalSnapshot = serde_json::from_slice(&bytes)?;
46 if snap.version != SNAPSHOT_VERSION {
47 anyhow::bail!(
48 "snapshot version {} no soportada (esperada {})",
49 snap.version, SNAPSHOT_VERSION
50 );
51 }
52 Ok(snap)
53 }
54}
55
56pub fn now_ms() -> u64 {
57 std::time::SystemTime::now()
58 .duration_since(std::time::UNIX_EPOCH)
59 .map(|d| d.as_millis() as u64)
60 .unwrap_or(0)
61}