use std::sync::Arc;
use grafeo_common::utils::error::{Error, Result};
use super::GrafeoDB;
impl GrafeoDB {
pub async fn async_wal_checkpoint(self: &Arc<Self>) -> Result<()> {
let db = Arc::clone(self);
tokio::task::spawn_blocking(move || db.wal_checkpoint())
.await
.map_err(|e| Error::Internal(format!("async checkpoint task failed: {e}")))?
}
#[cfg(feature = "grafeo-file")]
pub async fn async_write_snapshot(self: &Arc<Self>) -> Result<()> {
let db = Arc::clone(self);
tokio::task::spawn_blocking(move || {
let Some(ref fm) = db.file_manager else {
return Err(Error::Internal(
"no file manager configured for snapshot write".to_string(),
));
};
db.checkpoint_to_file(fm)
})
.await
.map_err(|e| Error::Internal(format!("async snapshot task failed: {e}")))?
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn async_wal_checkpoint_in_memory() {
let db = Arc::new(GrafeoDB::new_in_memory());
db.async_wal_checkpoint().await.unwrap();
}
#[tokio::test]
async fn async_wal_checkpoint_with_data() {
let dir = tempfile::tempdir().unwrap();
let db = Arc::new(GrafeoDB::open(dir.path().join("test.grafeo")).unwrap());
let session = db.session();
session.execute("INSERT (:Person {name: 'Alix'})").unwrap();
session.execute("INSERT (:Person {name: 'Gus'})").unwrap();
drop(session);
db.async_wal_checkpoint().await.unwrap();
}
#[tokio::test]
async fn async_wal_checkpoint_does_not_block_runtime() {
let db = Arc::new(GrafeoDB::new_in_memory());
let (checkpoint_result, concurrent_result) =
tokio::join!(db.async_wal_checkpoint(), async { 42 },);
checkpoint_result.unwrap();
assert_eq!(concurrent_result, 42);
}
#[cfg(feature = "grafeo-file")]
#[tokio::test]
async fn async_write_snapshot_roundtrip() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("test.grafeo");
let db = Arc::new(GrafeoDB::open(&path).unwrap());
let session = db.session();
session.execute("INSERT (:Person {name: 'Alix'})").unwrap();
drop(session);
db.async_write_snapshot().await.unwrap();
drop(db);
let db2 = GrafeoDB::open(&path).unwrap();
let session2 = db2.session();
let result = session2.execute("MATCH (p:Person) RETURN p.name").unwrap();
assert_eq!(result.rows.len(), 1);
}
}