Files
seaweedfs/sw-block/engine/replication/event.go
T
pingqiuandClaude Opus 4.6 d2d57851b0 feat: rebuild MVP — dual-lane session with bitmap protection
Rebuild session protocol implementation for v2-rebuild-mvp-session-protocol.md.

New files:
- rebuild_bitmap.go: RebuildBitmap — session-scoped dense bitset for
  WAL-applied LBA tracking. MarkApplied on local WAL write (not receive).
  ShouldApplyBase returns false for WAL-covered LBAs (WAL always wins).

- rebuild_session.go: RebuildSession — replica-side two-line rebuild.
  WAL lane (ApplyWALEntry) + base lane (ApplyBaseBlock) with bitmap
  conflict resolution. TryComplete requires BOTH base_complete AND
  wal_applied_lsn >= target_lsn. Volume-level control surface:
  StartRebuildSession, ApplyRebuildSessionWALEntry/BaseBlock,
  MarkRebuildSessionBaseComplete, TryCompleteRebuildSession,
  CancelRebuildSession, ActiveRebuildSession.

- rebuild_mvp_test.go: 4 correctness tests — base+WAL converge,
  WAL-applied never overwritten by base, bitmap set on applied not
  received, control surface start/supersede/complete.

- rebuild_transport_test.go: 2 transport-level tests — two-line with
  real WAL shipping, live writes during base copy with bitmap conflict.

Design docs:
- v2-rebuild-mvp-session-protocol.md: MVP spec with message set, apply
  rules, completion/failure/crash rules, test matrix
- v2-sync-recovery-protocol.md: full protocol context (keepup/catchup/
  rebuild unified design, primary decision logic, two-line model)
- v2-session-protocol-shape.md: protocol shape overview

Protocol engine (reference, not production):
- sw-block/protocol/: 7-event engine with ~300 lines, 13 tests

6 rebuild tests pass, all existing component tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:30:34 -07:00

207 lines
5.4 KiB
Go

package replication
// Event is one bounded input into the Phase 14 core skeleton.
// Events describe observation or intent; they do not perform side effects.
type Event interface {
VolumeID() string
}
// AssignmentDelivered carries master-owned assignment truth: local role, epoch,
// and replica membership for one volume.
type AssignmentDelivered struct {
ID string
Epoch uint64
Role VolumeRole
Replicas []ReplicaAssignment
RecoveryTarget SessionKind
}
func (e AssignmentDelivered) VolumeID() string { return e.ID }
// RoleApplied confirms the local runtime applied the desired role.
type RoleApplied struct {
ID string
}
func (e RoleApplied) VolumeID() string { return e.ID }
// ReceiverReadyObserved confirms replica receiver readiness.
type ReceiverReadyObserved struct {
ID string
}
func (e ReceiverReadyObserved) VolumeID() string { return e.ID }
// ShipperConfiguredObserved confirms shipper wiring exists.
type ShipperConfiguredObserved struct {
ID string
}
func (e ShipperConfiguredObserved) VolumeID() string { return e.ID }
// ShipperConnectedObserved confirms the shipper is connected.
type ShipperConnectedObserved struct {
ID string
}
func (e ShipperConnectedObserved) VolumeID() string { return e.ID }
// DiagnosticShippedAdvanced updates sender-side diagnostic progress only.
type DiagnosticShippedAdvanced struct {
ID string
ShippedLSN uint64
}
func (e DiagnosticShippedAdvanced) VolumeID() string { return e.ID }
// CommittedLSNAdvanced updates the committed boundary truth without implying
// replica durability or checkpoint advancement.
type CommittedLSNAdvanced struct {
ID string
CommittedLSN uint64
}
func (e CommittedLSNAdvanced) VolumeID() string { return e.ID }
// BarrierAccepted advances authoritative durable progress.
type BarrierAccepted struct {
ID string
FlushedLSN uint64
}
func (e BarrierAccepted) VolumeID() string { return e.ID }
// BarrierRejected marks the bounded path degraded until a later success clears it.
type BarrierRejected struct {
ID string
Reason string
}
func (e BarrierRejected) VolumeID() string { return e.ID }
// SyncAckObserved records one sync ack plus the bounded facts the primary needs
// to decide the next session step (keep-up, catch-up, or rebuild).
type SyncAckObserved struct {
ReplicaID string
ID string
AckKind SyncAckKind
TargetLSN uint64
PrimaryTailLSN uint64
DurableLSN uint64
AppliedLSN uint64
Reason string
}
func (e SyncAckObserved) VolumeID() string { return e.ID }
// CheckpointAdvanced updates the durable base-image boundary.
type CheckpointAdvanced struct {
ID string
CheckpointLSN uint64
}
func (e CheckpointAdvanced) VolumeID() string { return e.ID }
// SessionStarted begins one primary-owned session contract for a replica.
type SessionStarted struct {
ReplicaID string
ID string
Kind SessionKind
TargetLSN uint64
Reason string
}
func (e SessionStarted) VolumeID() string { return e.ID }
// SessionProgressObserved updates bounded progress for one running session.
type SessionProgressObserved struct {
ReplicaID string
ID string
Kind SessionKind
AchievedLSN uint64
}
func (e SessionProgressObserved) VolumeID() string { return e.ID }
// SessionCompleted closes one session contract at an explicit achieved boundary.
type SessionCompleted struct {
ReplicaID string
ID string
Kind SessionKind
AchievedLSN uint64
FlushedLSN uint64
CheckpointLSN uint64
}
func (e SessionCompleted) VolumeID() string { return e.ID }
// SessionFailed reports one failed session attempt without independently choosing
// the next semantic recovery path.
type SessionFailed struct {
ReplicaID string
ID string
Kind SessionKind
Reason string
}
func (e SessionFailed) VolumeID() string { return e.ID }
// CatchUpPlanned freezes the current replay target as bounded recovery truth.
type CatchUpPlanned struct {
ReplicaID string
ID string
TargetLSN uint64
}
func (e CatchUpPlanned) VolumeID() string { return e.ID }
// RecoveryProgressObserved updates achieved replay/rebuild progress without
// implying publication or durability closure by itself.
type RecoveryProgressObserved struct {
ReplicaID string
ID string
AchievedLSN uint64
}
func (e RecoveryProgressObserved) VolumeID() string { return e.ID }
// CatchUpCompleted closes a previously planned catch-up path at an explicit
// achieved boundary.
type CatchUpCompleted struct {
ReplicaID string
ID string
AchievedLSN uint64
}
func (e CatchUpCompleted) VolumeID() string { return e.ID }
// NeedsRebuildObserved is a fail-closed rebuild escalation.
type NeedsRebuildObserved struct {
ReplicaID string
ID string
Reason string
}
func (e NeedsRebuildObserved) VolumeID() string { return e.ID }
// RebuildStarted moves the recovery truth from blocked-needs-rebuild into an
// explicit rebuilding path with a frozen target.
type RebuildStarted struct {
ReplicaID string
ID string
TargetLSN uint64
}
func (e RebuildStarted) VolumeID() string { return e.ID }
// RebuildCommitted clears the rebuild condition with bounded durable truth.
type RebuildCommitted struct {
ReplicaID string
ID string
AchievedLSN uint64
FlushedLSN uint64
CheckpointLSN uint64
}
func (e RebuildCommitted) VolumeID() string { return e.ID }