mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-16 12:16:36 +00:00
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>
207 lines
5.4 KiB
Go
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 }
|