// // Copyright (c) 2025-2026 rustmailer.com (https://rustmailer.com) // // This file is part of the Bichon Email Archiving Project // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . use crate::settings::dir::DATA_DIR_MANAGER; use memdb::{Durability, MemDb}; use std::sync::LazyLock; use std::time::Duration; pub static DB_MANAGER: LazyLock = LazyLock::new(DatabaseManager::new); pub struct DatabaseManager { db: MemDb, } impl DatabaseManager { fn new() -> Self { let db_path = &DATA_DIR_MANAGER.memdb_dir; std::fs::create_dir_all(db_path).expect("Failed to create memdb data directory"); let db = MemDb::open_with(db_path, Durability::Batch { max_ops: 100 }) .expect("Failed to open memdb database"); // Start periodic snapshot worker (every 5 minutes) db.start_snapshot_worker(Duration::from_secs(300)); // Start periodic flush worker (every 10 seconds) so buffered writes // are flushed regularly and not only at the batch threshold. db.start_flush_worker(Duration::from_secs(10)); DatabaseManager { db } } /// Get a reference to the MemDb instance. pub fn db(&self) -> &MemDb { &self.db } /// Flush any buffered WAL entries to disk. Must be called before shutdown /// to avoid losing writes that haven't hit the batch threshold yet. pub fn flush(&self) { if let Err(e) = self.db.flush() { eprintln!("[memdb] flush error on shutdown: {e}"); } } }