Initial SWOOSH executor and reducer implementation
This commit is contained in:
45
replay.go
Normal file
45
replay.go
Normal file
@@ -0,0 +1,45 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user