pub struct WalManager { /* private fields */ }Expand description
Write-Ahead Log manager
Implementations§
Source§impl WalManager
impl WalManager
Sourcepub async fn new(
path: PathBuf,
config: WalConfig,
) -> Result<WalManager, WalError>
pub async fn new( path: PathBuf, config: WalConfig, ) -> Result<WalManager, WalError>
Create a new WAL manager instance.
This constructor initializes a WAL manager with the specified file path and configuration. It creates the necessary directory structure and opens the WAL file for append operations. The file is created if it doesn’t exist, and opened in append mode for existing files.
§Arguments
path- The file system path where the WAL file should be storedconfig- Configuration options including format, size limits, and compression settings
§Returns
Returns a Result containing the initialized WalManager, or a WalError if
initialization fails.
§Errors
WalError::Io- If directory creation or file operations fail
§Examples
use std::path::PathBuf;
use sentinel_wal::{WalConfig, WalFormat, WalManager};
let config = WalConfig {
format: WalFormat::Binary, // or WalFormat::JsonLines
max_file_size: Some(10 * 1024 * 1024), // 10MB
..Default::default()
};
let wal = WalManager::new(PathBuf::from("data/myapp.wal"), config).await?;
// WAL is now ready for writing entriesSourcepub async fn write_entry(&self, entry: LogEntry) -> Result<(), WalError>
pub async fn write_entry(&self, entry: LogEntry) -> Result<(), WalError>
Write a log entry to the WAL.
This method appends a log entry to the WAL file using the configured format (binary or JSON Lines). The entry is serialized and written atomically to ensure data integrity. For JSON Lines format, each entry is written as a separate line.
§Arguments
entry- The log entry to write to the WAL
§Returns
Returns Ok(()) on successful write, or a WalError if the operation fails.
§Errors
WalError::Serialization- If entry serialization failsWalError::Io- If file write operations fail
§Examples
use sentinel_wal::{WalManager, WalConfig, LogEntry, EntryType};
use std::path::PathBuf;
use serde_json::json;
let config = WalConfig::default();
let mut wal = WalManager::new(PathBuf::from("data/app.wal"), config).await?;
// Write an insert operation
let entry = LogEntry::new(
EntryType::Insert,
"users".to_string(),
"user-123".to_string(),
Some(json!({"name": "Alice", "email": "alice@example.com"}))
);
wal.write_entry(entry).await?;
// Write a delete operation
let delete_entry = LogEntry::new(
EntryType::Delete,
"users".to_string(),
"user-123".to_string(),
None
);
wal.write_entry(delete_entry).await?;Sourcepub async fn read_all_entries(&self) -> Result<Vec<LogEntry>, WalError>
pub async fn read_all_entries(&self) -> Result<Vec<LogEntry>, WalError>
Read all log entries from the WAL for recovery.
This method reads and parses all entries from the WAL file(s) in the configured format. It’s typically used during database recovery to replay operations. The method automatically detects the format (binary or JSON Lines) and parses entries accordingly.
For binary format, entries are parsed by finding checksum boundaries. For JSON Lines format, entries are parsed line by line.
§Returns
Returns a Result containing a vector of all LogEntry instances found in the WAL,
or a WalError if reading or parsing fails.
§Errors
WalError::Io- If file operations failWalError::Serialization- If entry parsing fails
§Examples
use std::path::PathBuf;
use sentinel_wal::{WalConfig, WalManager};
let config = WalConfig::default();
let wal = WalManager::new(PathBuf::from("data/app.wal"), config).await?;
// Read all entries for recovery
let entries = wal.read_all_entries().await?;
println!("Found {} entries in WAL", entries.len());
for entry in entries {
println!(
"Entry: {:?} on {} in collection {}",
entry.entry_type,
entry.document_id_str(),
entry.collection_str()
);
}Sourcepub fn stream_entries(
&self,
) -> impl Stream<Item = Result<LogEntry, WalError>> + Send + 'static
pub fn stream_entries( &self, ) -> impl Stream<Item = Result<LogEntry, WalError>> + Send + 'static
Stream log entries from the WAL file.
This method provides a streaming interface to read WAL entries without loading
the entire file into memory. It’s more memory-efficient than read_all_entries()
for large WAL files. The stream automatically handles format detection and parsing.
For binary format, entries are streamed by reading length prefixes. For JSON Lines format, entries are streamed line by line.
§Returns
Returns a Stream that yields Result<LogEntry> items. The stream will yield
Ok(entry) for successfully parsed entries and Err(error) for parsing failures.
§Examples
use std::path::PathBuf;
use sentinel_wal::{WalConfig, WalManager};
use futures::StreamExt;
let config = WalConfig::default();
let wal = WalManager::new(PathBuf::from("data/app.wal"), config).await?;
// Stream entries for processing
let mut stream = wal.stream_entries();
use futures::pin_mut;
pin_mut!(stream);
let mut count = 0;
while let Some(result) = stream.next().await {
match result {
Ok(entry) => {
count += 1;
println!("Processed entry {}: {:?}", count, entry.entry_type);
},
Err(e) => {
eprintln!("Error reading entry: {}", e);
},
}
}
println!("Total entries processed: {}", count);Sourcepub async fn checkpoint(&self) -> Result<(), WalError>
pub async fn checkpoint(&self) -> Result<(), WalError>
Perform a checkpoint operation on the WAL.
A checkpoint ensures that all pending WAL entries are durably written to disk and creates a recovery point. This is different from truncation - checkpointing preserves the WAL for potential future recovery while marking a safe recovery point.
The checkpoint process:
- Flushes any buffered writes to disk
- Ensures file metadata is synchronized
- Records the checkpoint position for recovery
§Returns
Returns Ok(()) on successful checkpoint, or a WalError if the operation fails.
§Errors
WalError::Io- If file synchronization operations fail
§Examples
use std::path::PathBuf;
use sentinel_wal::{EntryType, LogEntry, WalConfig, WalManager};
let config = WalConfig::default();
let wal = WalManager::new(PathBuf::from("data/app.wal"), config).await?;
// Write some entries
let entry = LogEntry::new(
EntryType::Insert,
"users".to_string(),
"user-123".to_string(),
None,
);
wal.write_entry(entry).await?;
// Create a checkpoint
wal.checkpoint().await?;
// At this point, all entries are safely on disk
// and can be recovered from if neededSourcepub async fn size(&self) -> Result<u64, WalError>
pub async fn size(&self) -> Result<u64, WalError>
Get the current size of the WAL file in bytes.
This method returns the size of the WAL file on disk, which can be used
to monitor file growth and determine if rotation is needed based on
the configured max_file_size limit.
§Returns
Returns a Result containing the file size in bytes, or a WalError if
the metadata cannot be read.
§Errors
WalError::Io- If file metadata operations fail
§Examples
use std::path::PathBuf;
use sentinel_wal::{WalConfig, WalManager};
let config = WalConfig {
max_file_size: Some(10 * 1024 * 1024), // 10MB
..Default::default()
};
let wal =
WalManager::new(PathBuf::from("data/app.wal"), config.clone()).await?;
let size = wal.size().await?;
println!("WAL file size: {} bytes", size);
if let Some(max_size) = config.max_file_size {
if size >= max_size {
println!("WAL file should be rotated");
}
}Sourcepub async fn entries_count(&self) -> Result<usize, WalError>
pub async fn entries_count(&self) -> Result<usize, WalError>
Get the number of entries in the WAL.
This returns the count of entries that have been written to the WAL. Note that this may not reflect the current state if entries have been checkpointed or if the WAL has been rotated.
§Returns
Returns the number of entries written to the WAL.
§Examples
use std::path::PathBuf;
use sentinel_wal::{WalConfig, WalManager};
let wal = WalManager::new(PathBuf::from("data.wal"), WalConfig::default())
.await?;
let count = wal.entries_count().await?;
println!("WAL has {} entries", count);