wal

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: AGPL-3.0 Imports: 11 Imported by: 0

Documentation

Overview

Package wal is Atlas's write-ahead log: a segmented, append-only record store with group commit.

The log is the single source of truth (ADR-0001). Durability comes from fsync, but one fsync per record caps throughput at a few thousand per second (ADR-0005), so the WAL separates buffering from flushing: Log.Append stages records in memory and Log.Sync writes the whole batch and issues exactly one fsync. A processor appends every event of a batch, then calls Sync once — the "durable before visible" boundary (invariant I2).

Entries are opaque byte slices; the WAL does not interpret them, which keeps it decoupled from the record model. Each entry is framed with a length and a CRC32C so forward iteration can detect a torn tail left by a crash mid-batch and stop cleanly at the last durable record.

A Log is owned by a single goroutine (the partition's writer, invariant I3) and is not safe for concurrent use.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Log

type Log struct {
	// contains filtered or unexported fields
}

Log is a segmented append-only write-ahead log.

func Open

func Open(opts Options) (*Log, error)

Open opens (or creates) the log in opts.Dir. If the last segment has a torn tail from a crash mid-batch, it is truncated to the last valid frame so subsequent appends remain readable.

func (*Log) Append

func (l *Log) Append(data []byte) error

Append stages data as the next record. It is buffered, not durable, until Sync returns. The data is copied into the WAL's buffer, so the caller may reuse its slice immediately.

Records must be non-empty: a zero-length frame is indistinguishable from the zeroed tail a crash can leave, so the reader treats length zero as end of log. Real records always carry a header, so this is not a practical limit.

func (*Log) Close

func (l *Log) Close() error

Close closes the active segment. Records staged but not yet Synced are discarded — by contract they were never durable.

func (*Log) Replay

func (l *Log) Replay(fn func(data []byte) error) error

Replay calls fn for every durable record across all segments, in append order. It reads only what is on disk, so records staged but not yet Synced are not visible. Replay is the recovery entry point: a processor folds these records through applyToState to rebuild state (ADR-0001).

The data slice passed to fn is owned by the caller for the duration of the call; it is freshly allocated per record, so it remains valid after fn returns. If fn returns an error, Replay stops and returns it.

func (*Log) Sync

func (l *Log) Sync() error

Sync writes all staged records and issues exactly one fsync, making the whole batch durable. It is a no-op if nothing is staged. Nothing externally observable may happen before Sync returns (invariant I2).

type Options

type Options struct {
	// Dir is the directory holding segment files. Created if absent.
	Dir string
	// MaxSegmentSize is the soft cap after which the next Sync rolls to a new
	// segment. Zero means the default (64 MiB). A single batch is never split
	// across segments, so a segment may exceed this by up to one batch.
	MaxSegmentSize int64
}

Options configures a Log.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL