Durable Write-Ahead Log for local-first systems.
The wal module is the foundation of durability in Softadastra.
It guarantees that:
No accepted operation is ever lost, even in the presence of failures.
The goal of softadastra/wal is simple:
Persist every operation before it is executed or synchronized.
This module ensures that the system can always:
- Recover after a crash
- Resume after disconnection
- Replay operations deterministically
Write first. Sync later.
Every operation must:
- Be written to the WAL
- Be flushed to durable storage
- Then be processed or sent over the network
The wal module provides:
- Append-only log storage
- Durable persistence of operations
- Sequential ordering (monotonic sequence)
- Log replay capabilities
- Crash recovery
- No sync logic
- No network communication
- No filesystem watching
- No metadata management
π It only guarantees durability.
The WAL is never modified in place.
Only:
- Append
- Read
- Replay
An operation is considered valid only after it is persisted.
All operations have a strict sequence:
- Monotonic increasing IDs
- Deterministic replay
Replaying the same WAL must produce the same state.
modules/wal/
βββ include/softadastra/wal/
β βββ WalRecord.hpp
β βββ WalWriter.hpp
β βββ WalReader.hpp
β βββ WalStore.hpp
β βββ Sequence.hpp
βββ src/
Represents a single operation.
Typical fields:
- Sequence number
- Operation type
- Payload
- Timestamp
Responsible for:
- Appending records
- Ensuring durability (fsync or equivalent)
- Managing write ordering
Provides:
- Sequential reading
- Streaming replay
- Iteration over records
Manages:
- WAL files
- Segmentation (future)
- Rotation (future)
- Storage lifecycle
Handles:
- Monotonic sequence generation
- Ordering guarantees
- Replay positioning
#include <softadastra/wal/writer/WalWriter.hpp>
#include <softadastra/wal/utils/FileEventSerializer.hpp>
#include <softadastra/fs/events/FileEvent.hpp>
using namespace softadastra;
int main()
{
wal::core::WalConfig config;
config.path = "data/wal.log";
wal::writer::WalWriter writer(config);
// Example: file event β WAL
fs::events::FileEvent event = ...;
wal::core::WalRecord record;
record.type = wal::types::WalRecordType::Put;
record.timestamp = 123456;
record.payload =
wal::utils::FileEventSerializer::serialize(event);
writer.append(record);
}#include <softadastra/wal/reader/WalReader.hpp>
using namespace softadastra::wal;
void replay(const std::string &path)
{
reader::WalReader reader(path);
reader.for_each([](const core::WalRecord &record)
{
// deterministic apply(record)
});
}
int main()
{
replay("data/wal.log");
}Used by:
- Sync engine (primary)
- Metadata layer (indirectly)
- Application runtime
The WAL ensures:
- No data loss after commit
- Ordered operations
- Replay after crash
- Consistent recovery
The WAL is designed to survive:
- Process crash
- System crash
- Network failure
- Partial execution
- softadastra/core
- Filesystem (POSIX / platform APIs)
- Log segmentation
- Compaction
- Checksums and corruption detection
- Streaming WAL
- Replication-ready WAL
- Binary format optimization
- Never modify existing records
- Never skip sequence numbers
- Never execute before persisting
- Always guarantee flush before ack
The WAL is not just a log.
It is the source of truth.
- Guarantees durability
- Enables recovery
- Orders all operations
- Foundation of local-first systems
vix add @softadastra/walSee root LICENSE file.