Files
SWOOSH/replay.go
2025-10-24 18:35:13 +11:00

46 lines
1.2 KiB
Go

package swoosh
import "fmt"
// Replay deterministically replays WAL records on top of a snapshot and returns the resulting state.
func Replay(wal WALStore, snapshot Snapshot) (OrchestratorState, error) {
base, err := cloneState(snapshot.State)
if err != nil {
return OrchestratorState{}, fmt.Errorf("clone snapshot state: %w", err)
}
if base.StateHash == "" {
hash, err := computeStateHash(base)
if err != nil {
return OrchestratorState{}, fmt.Errorf("compute snapshot hash: %w", err)
}
base.StateHash = hash
}
start := snapshot.LastAppliedIndex + 1
records, err := wal.Replay(start)
if err != nil {
return OrchestratorState{}, fmt.Errorf("replay wal: %w", err)
}
state := base
for _, record := range records {
if state.StateHash != record.StatePreHash {
return OrchestratorState{}, fmt.Errorf("wal pre-hash mismatch at index %d", record.Index)
}
next, err := Reduce(state, record.Transition, record.Guard)
if err != nil {
return OrchestratorState{}, fmt.Errorf("reduce wal record %d: %w", record.Index, err)
}
if next.StateHash != record.StatePostHash {
return OrchestratorState{}, fmt.Errorf("wal post-hash mismatch at index %d", record.Index)
}
state = next
}
return state, nil
}