mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-08 13:07:45 +01:00
feat: Phase 20 acceptance fixes + sw-test-runner suite mode
Acceptance rows closed: - WriteLBA/SyncCache contract: code comments document write-back vs durability fence semantics - RF=2 stable identity: v2bridge always uses SetReplicaAddrs (preserves ServerID); blockcmd dispatcher also fixed to use setupPrimaryReplicationMulti; test asserts exact expected ReplicaID="vs-2" (not just non-empty) - Tests treating WriteLBA as commit: replica_read_test rewritten with SyncCache as durability fence - publish_healthy contract: 3 gate tests with hard assertions including gate 3 (PrimaryShipperConnected) - SetReplicaAddr deprecation warning added - WALShipper.ReplicaID() getter added for identity verification Test runner enhancements: - sw-test-runner suite command: build → deploy → run N scenarios in one invocation with --skip-deploy support - Suite YAML definitions for T6 Stage 0 and Stage 1 - deploy action: kill stale processes, clean dirs, cross-compile, upload - run-phase20-t6.ps1 PowerShell script (deprecated by suite command) Engine/runtime fixes: - Recovery executor nil-safety improvements - Recovery bundle BuildRecoveryBundle defensive checks - ShipperGroup MinReplicaFlushedLSNAll surface Docs: acceptance checklist refined, test matrix updated, T6 runbook, engine maintainer tutorial, design README updated. 26 files changed, ~1600 insertions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
275c3ee1c7
commit
44103a1bd7
27 files changed
+2472
-166
No files matched your search
@@ -1,14 +1,27 @@
|
||||
package runtime
|
||||
|
||||
import engine "github.com/seaweedfs/seaweedfs/sw-block/engine/replication"
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
engine "github.com/seaweedfs/seaweedfs/sw-block/engine/replication"
|
||||
)
|
||||
|
||||
// RecoveryCallbacks is the host-side callback interface for recovery execution.
|
||||
// The runtime helper drives plan execution; the host supplies concrete
|
||||
// IO bindings and receives completion notifications.
|
||||
type RecoveryCallbacks interface {
|
||||
// OnRecoveryProgress is called when replay/rebuild reaches an explicit
|
||||
// achieved boundary but the recovery session is not yet fully closed.
|
||||
OnRecoveryProgress(volumeID, replicaID string, achievedLSN uint64)
|
||||
|
||||
// OnCatchUpCompleted is called after successful catch-up execution.
|
||||
OnCatchUpCompleted(volumeID, replicaID string, achievedLSN uint64)
|
||||
|
||||
// OnCatchUpFailed is called when catch-up execution fails with a
|
||||
// classified reason that the host may need to surface into core events.
|
||||
OnCatchUpFailed(volumeID, replicaID, reason string)
|
||||
|
||||
// OnRebuildCompleted is called after successful rebuild execution.
|
||||
// The host should read the post-rebuild snapshot and emit the
|
||||
// appropriate core event.
|
||||
@@ -28,6 +41,9 @@ func ExecuteCatchUpPlan(
|
||||
exec := engine.NewCatchUpExecutor(driver, plan)
|
||||
exec.IO = io
|
||||
if err := exec.Execute(nil, 0); err != nil {
|
||||
if callbacks != nil {
|
||||
callbacks.OnCatchUpFailed(volumeID, replicaID, classifyCatchUpFailure(err))
|
||||
}
|
||||
return err
|
||||
}
|
||||
if callbacks != nil {
|
||||
@@ -35,6 +51,7 @@ func ExecuteCatchUpPlan(
|
||||
if achievedLSN == 0 {
|
||||
achievedLSN = plan.CatchUpStartLSN
|
||||
}
|
||||
callbacks.OnRecoveryProgress(volumeID, replicaID, achievedLSN)
|
||||
callbacks.OnCatchUpCompleted(volumeID, replicaID, achievedLSN)
|
||||
}
|
||||
return nil
|
||||
@@ -56,7 +73,31 @@ func ExecuteRebuildPlan(
|
||||
return err
|
||||
}
|
||||
if callbacks != nil {
|
||||
callbacks.OnRecoveryProgress(volumeID, replicaID, plan.RebuildTargetLSN)
|
||||
callbacks.OnRebuildCompleted(volumeID, replicaID, plan)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func classifyCatchUpFailure(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
msg := err.Error()
|
||||
switch {
|
||||
case errors.Is(err, engine.ErrTruncationUnsafe):
|
||||
return "truncation_unsafe"
|
||||
case strings.Contains(msg, "WAL recycled"):
|
||||
return "retention_lost"
|
||||
case strings.Contains(msg, "duration_exceeded"):
|
||||
return "catchup_duration_exceeded"
|
||||
case strings.Contains(msg, "progress_stalled"):
|
||||
return "catchup_progress_stalled"
|
||||
case strings.Contains(msg, "entries_limit_exceeded"):
|
||||
return "catchup_entries_limit_exceeded"
|
||||
case strings.Contains(msg, "budget violation"):
|
||||
return "catchup_budget_exceeded"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user