59 lines
2.1 KiB
Rust
59 lines
2.1 KiB
Rust
//! Internal engine state — not part of the public FFI API.
|
|
//!
|
|
//! The [`Engine`] struct bundles an open [`Database`] connection and a
|
|
//! [`Hlc`] (Hybrid Logical Clock) for the local node. A single global
|
|
//! instance is held behind a [`Mutex`] so that FRB's thread-pool workers
|
|
//! can safely share access.
|
|
|
|
use std::sync::Mutex;
|
|
|
|
use chronogrid_core::{Database, Hlc};
|
|
|
|
/// Runtime engine holding the encrypted database and the node's HLC.
|
|
pub(crate) struct Engine {
|
|
/// Encrypted SQLCipher database connection with ChronoGrid schema.
|
|
pub(crate) db: Database,
|
|
/// Hybrid Logical Clock for causally ordered CRDT mutations.
|
|
pub(crate) hlc: Hlc,
|
|
}
|
|
|
|
/// Global engine singleton.
|
|
///
|
|
/// `None` before [`super::engine::init_engine`] is called, `Some` while the
|
|
/// engine is active, and `None` again after [`super::engine::close_engine`].
|
|
pub(crate) static ENGINE: Mutex<Option<Engine>> = Mutex::new(None);
|
|
|
|
// ── Convenience helpers ──────────────────────────────────────────────────────
|
|
|
|
/// Acquires the engine lock and calls `f` with a shared reference.
|
|
///
|
|
/// Returns `Err` if the engine has not been initialized or the lock is
|
|
/// poisoned.
|
|
pub(crate) fn with_engine<T>(
|
|
f: impl FnOnce(&Engine) -> anyhow::Result<T>,
|
|
) -> anyhow::Result<T> {
|
|
let guard = ENGINE
|
|
.lock()
|
|
.map_err(|e| anyhow::anyhow!("engine lock poisoned: {e}"))?;
|
|
let engine = guard
|
|
.as_ref()
|
|
.ok_or_else(|| anyhow::anyhow!("engine not initialized — call init_engine first"))?;
|
|
f(engine)
|
|
}
|
|
|
|
/// Acquires the engine lock and calls `f` with a mutable reference.
|
|
///
|
|
/// Returns `Err` if the engine has not been initialized or the lock is
|
|
/// poisoned.
|
|
pub(crate) fn with_engine_mut<T>(
|
|
f: impl FnOnce(&mut Engine) -> anyhow::Result<T>,
|
|
) -> anyhow::Result<T> {
|
|
let mut guard = ENGINE
|
|
.lock()
|
|
.map_err(|e| anyhow::anyhow!("engine lock poisoned: {e}"))?;
|
|
let engine = guard
|
|
.as_mut()
|
|
.ok_or_else(|| anyhow::anyhow!("engine not initialized — call init_engine first"))?;
|
|
f(engine)
|
|
}
|