mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-20 13:30:46 +02:00
feat: Phase 16M/17 + promote fixes + testrunner updates
Phase 16M: explicit replica readiness on heartbeat seam - master.proto: optional bool replica_ready = 19 (proto regenerated on M01) - block_heartbeat_proto.go: write/read ReplicaReady with presence semantics - master_block_registry.go: replicaReadyObservedFromHeartbeat prefers explicit proto field, falls back to address heuristic when absent - volume_server_block.go: heartbeat emits ReplicaReady from core projection Phase 17: host effects extraction + stop line - phase-17-log.md: Batch 10/11 delivery notes Promote fixes: - master_block_failover.go: deterministic replica addrs from path hash - qa_promote_replication_test.go: address-upgrade trigger test - qa_promote_rejoin_live_test.go: new live rejoin test Testrunner: - devops.go: action improvements - recovery-baseline-failover.yaml, suite-ha-failover.yaml: scenario updates - cp11b3-manual-promote.yaml: promote scenario alignment - fresh_volume_write_test.go: new component test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
7855d5240c
commit
cf16e53b04
@@ -84,7 +84,9 @@ func (q *BlockAssignmentQueue) Confirm(server string, path string, epoch uint64)
|
||||
}
|
||||
|
||||
// ConfirmFromHeartbeat batch-confirms assignments that match reported heartbeat info.
|
||||
// An assignment is confirmed if the VS reports (path, epoch) that matches.
|
||||
// Same-epoch refresh assignments that carry replica transport are only confirmed
|
||||
// once the heartbeat reflects that transport, so they are not dropped before
|
||||
// the promoted VS actually applies them.
|
||||
func (q *BlockAssignmentQueue) ConfirmFromHeartbeat(server string, infos []blockvol.BlockVolumeInfoMessage) {
|
||||
if len(infos) == 0 {
|
||||
return
|
||||
@@ -97,26 +99,42 @@ func (q *BlockAssignmentQueue) ConfirmFromHeartbeat(server string, infos []block
|
||||
return
|
||||
}
|
||||
|
||||
// Build a set of reported (path, epoch) pairs.
|
||||
type key struct {
|
||||
path string
|
||||
epoch uint64
|
||||
}
|
||||
reported := make(map[key]bool, len(infos))
|
||||
for _, info := range infos {
|
||||
reported[key{info.Path, info.Epoch}] = true
|
||||
}
|
||||
|
||||
// Keep only assignments not confirmed.
|
||||
kept := pending[:0]
|
||||
for _, a := range pending {
|
||||
if !reported[key{a.Path, a.Epoch}] {
|
||||
if !assignmentConfirmedByHeartbeat(a, infos) {
|
||||
kept = append(kept, a)
|
||||
}
|
||||
}
|
||||
q.queues[server] = kept
|
||||
}
|
||||
|
||||
func assignmentConfirmedByHeartbeat(a blockvol.BlockVolumeAssignment, infos []blockvol.BlockVolumeInfoMessage) bool {
|
||||
for _, info := range infos {
|
||||
if info.Path != a.Path || info.Epoch != a.Epoch {
|
||||
continue
|
||||
}
|
||||
expectedData, expectedCtrl, requiresReplicaTransport := assignmentReplicaTransport(a)
|
||||
if !requiresReplicaTransport {
|
||||
return true
|
||||
}
|
||||
if info.ReplicaDataAddr == expectedData && info.ReplicaCtrlAddr == expectedCtrl {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func assignmentReplicaTransport(a blockvol.BlockVolumeAssignment) (dataAddr, ctrlAddr string, ok bool) {
|
||||
if a.ReplicaDataAddr != "" || a.ReplicaCtrlAddr != "" {
|
||||
return a.ReplicaDataAddr, a.ReplicaCtrlAddr, true
|
||||
}
|
||||
if len(a.ReplicaAddrs) == 1 {
|
||||
return a.ReplicaAddrs[0].DataAddr, a.ReplicaAddrs[0].CtrlAddr, true
|
||||
}
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
// Pending returns the number of pending assignments for the server.
|
||||
func (q *BlockAssignmentQueue) Pending(server string) int {
|
||||
q.mu.Lock()
|
||||
|
||||
Reference in New Issue
Block a user