feat(rustdb): add restore and periodic persistence support for in-memory storage

This commit is contained in:
2026-04-05 01:30:28 +00:00
parent 8ce6ff11c3
commit 8646d58f06
4 changed files with 41 additions and 3 deletions

View File

@@ -1,5 +1,12 @@
# Changelog # Changelog
## 2026-04-05 - 2.4.0 - feat(rustdb)
add restore and periodic persistence support for in-memory storage
- Restore previously persisted state during startup when a persist path is configured.
- Spawn a background task to periodically persist in-memory data using the configured interval.
- Warn when running purely in-memory without durable persistence configured.
## 2026-04-04 - 2.3.1 - fix(package) ## 2026-04-04 - 2.3.1 - fix(package)
update package metadata update package metadata

View File

@@ -1,6 +1,8 @@
pub mod management; pub mod management;
use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use anyhow::Result; use anyhow::Result;
use dashmap::DashMap; use dashmap::DashMap;
@@ -33,7 +35,16 @@ impl RustDb {
// Create storage adapter // Create storage adapter
let storage: Arc<dyn StorageAdapter> = match options.storage { let storage: Arc<dyn StorageAdapter> = match options.storage {
StorageType::Memory => { StorageType::Memory => {
let adapter = MemoryStorageAdapter::new(); let adapter = if let Some(ref pp) = options.persist_path {
tracing::info!("MemoryStorageAdapter with periodic persistence to {}", pp);
MemoryStorageAdapter::with_persist_path(PathBuf::from(pp))
} else {
tracing::warn!(
"SmartDB is using in-memory storage — data will NOT survive a restart. \
Set storage to 'file' for durable persistence."
);
MemoryStorageAdapter::new()
};
Arc::new(adapter) Arc::new(adapter)
} }
StorageType::File => { StorageType::File => {
@@ -49,6 +60,26 @@ impl RustDb {
// Initialize storage // Initialize storage
storage.initialize().await?; storage.initialize().await?;
// Restore any previously persisted state (no-op for file storage and
// memory storage without a persist_path).
storage.restore().await?;
// Spawn periodic persistence task for memory storage with persist_path.
if options.storage == StorageType::Memory && options.persist_path.is_some() {
let persist_storage = storage.clone();
let interval_ms = options.persist_interval_ms;
tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_millis(interval_ms));
interval.tick().await; // skip the immediate first tick
loop {
interval.tick().await;
if let Err(e) = persist_storage.persist().await {
tracing::error!("Periodic persist failed: {}", e);
}
}
});
}
let ctx = Arc::new(CommandContext { let ctx = Arc::new(CommandContext {
storage, storage,
indexes: Arc::new(DashMap::new()), indexes: Arc::new(DashMap::new()),

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartdb', name: '@push.rocks/smartdb',
version: '2.3.1', version: '2.4.0',
description: 'A MongoDB-compatible embedded database server with wire protocol support, backed by a high-performance Rust engine.' description: 'A MongoDB-compatible embedded database server with wire protocol support, backed by a high-performance Rust engine.'
} }

File diff suppressed because one or more lines are too long