From f825f08680c02ac4780d2d50c1199517f2ee72d2 Mon Sep 17 00:00:00 2001 From: pingqiu Date: Sun, 5 Apr 2026 16:29:12 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20Phase=2020=20T3=20=E2=80=94=20correct=20?= =?UTF-8?q?V2=20promotion=20observability=20to=20tri-state=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace misleading V2PromotionEnabled/V2PromotionReady booleans with single V2PromotionMode string: "disabled", "placeholder_fail_closed", or "transport_ready". Previous V2PromotionReady was true whenever any querier was installed, including the placeholder that always returns error. Now the diagnostic accurately distinguishes placeholder (fail-closed until proto regen) from real gRPC transport. blockV2EvidenceTransport bool on MasterServer tracks whether the real transport querier is installed. Currently always false (placeholder). Set to true only when real gRPC querier replaces the placeholder after proto regen. Co-Authored-By: Claude Opus 4.6 (1M context) --- weed/server/master_block_failover.go | 13 +++++++++---- weed/server/master_server.go | 7 ++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/weed/server/master_block_failover.go b/weed/server/master_block_failover.go index ada422c79..0afbe6f41 100644 --- a/weed/server/master_block_failover.go +++ b/weed/server/master_block_failover.go @@ -54,8 +54,7 @@ type FailoverVolumeState struct { // Volume-oriented: each entry describes one volume's failover state. // Aggregate counts are derived from the volume list. type FailoverDiagnostic struct { - V2PromotionEnabled bool // T3: whether durability-first V2 promotion is active - V2PromotionReady bool // T3: whether V2 evidence querier is wired (false = fail-closed placeholder) + V2PromotionMode string // T3: "disabled", "placeholder_fail_closed", "transport_ready" Volumes []FailoverVolumeState PendingRebuildCount map[string]int // dead server → count of pending rebuilds DeferredPromotionCount map[string]int // dead server → count of deferred promotion timers @@ -99,8 +98,14 @@ func (fs *blockFailoverState) DiagnosticSnapshot() FailoverDiagnostic { // V2 promotion rollout state so operators can observe the active mode. func (ms *MasterServer) FailoverDiagnosticSnapshot() FailoverDiagnostic { diag := ms.blockFailover.DiagnosticSnapshot() - diag.V2PromotionEnabled = ms.blockV2Promotion - diag.V2PromotionReady = ms.blockV2Promotion && ms.blockVSQueryEvidence != nil + switch { + case !ms.blockV2Promotion: + diag.V2PromotionMode = "disabled" + case ms.blockV2EvidenceTransport: + diag.V2PromotionMode = "transport_ready" + default: + diag.V2PromotionMode = "placeholder_fail_closed" + } return diag } diff --git a/weed/server/master_server.go b/weed/server/master_server.go index 868d69b66..0fbb775c4 100644 --- a/weed/server/master_server.go +++ b/weed/server/master_server.go @@ -110,9 +110,10 @@ type MasterServer struct { blockVSPrepareExpand func(ctx context.Context, server string, name string, newSize, expandEpoch uint64) error blockVSCommitExpand func(ctx context.Context, server string, name string, expandEpoch uint64) (uint64, error) blockVSCancelExpand func(ctx context.Context, server string, name string, expandEpoch uint64) error - blockVSQueryEvidence BlockPromotionEvidenceQuerier // T2: fresh on-demand promotion evidence - nextExpandEpoch atomic.Uint64 - blockV2Promotion bool // T3: when true, use durability-first V2 promotion; when false, legacy V1 + blockVSQueryEvidence BlockPromotionEvidenceQuerier // T2: fresh on-demand promotion evidence + blockV2EvidenceTransport bool // T3: true only when real gRPC querier is installed (not placeholder) + nextExpandEpoch atomic.Uint64 + blockV2Promotion bool // T3: when true, use durability-first V2 promotion; when false, legacy V1 // Test-only hook: called after AcquireExpandInflight but before the // re-read Lookup in coordinated expand. Nil in production.