From 85bc50ee1e310f2623a110c39dd2be7a1a331963 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sun, 8 Mar 2026 15:24:20 -0700 Subject: [PATCH] fix: consistent hasMore pattern and remove double-counted LoadCount in scoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adopt vacuum_handler's hasMore pattern: over-fetch by 1, check len > maxResults, and truncate — consistent truncation semantics - Remove direct LoadCount penalty in calculateBalanceScore since LoadCount is already factored into effectiveVolumeCount for utilization scoring; bump utilization weight from 40 to 50 to compensate for the removed 10-point load penalty --- weed/plugin/worker/volume_balance_handler.go | 8 ++++++-- weed/worker/tasks/balance/detection.go | 9 ++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/weed/plugin/worker/volume_balance_handler.go b/weed/plugin/worker/volume_balance_handler.go index 3a39cd16f..5fd7962d9 100644 --- a/weed/plugin/worker/volume_balance_handler.go +++ b/weed/plugin/worker/volume_balance_handler.go @@ -228,7 +228,7 @@ func (h *VolumeBalanceHandler) Detect( if maxResults <= 0 { maxResults = 1 } - results, err := balancetask.Detection(metrics, clusterInfo, workerConfig.TaskConfig, maxResults) + results, err := balancetask.Detection(metrics, clusterInfo, workerConfig.TaskConfig, maxResults+1) if err != nil { return err } @@ -236,7 +236,11 @@ func (h *VolumeBalanceHandler) Detect( glog.Warningf("Plugin worker failed to emit volume_balance detection trace: %v", traceErr) } - hasMore := len(results) >= maxResults + hasMore := false + if maxResults > 0 && len(results) > maxResults { + hasMore = true + results = results[:maxResults] + } proposals := make([]*plugin_pb.JobProposal, 0, len(results)) for _, result := range results { diff --git a/weed/worker/tasks/balance/detection.go b/weed/worker/tasks/balance/detection.go index 02706511e..9ed9ddf45 100644 --- a/weed/worker/tasks/balance/detection.go +++ b/weed/worker/tasks/balance/detection.go @@ -370,11 +370,13 @@ func calculateBalanceScore(disk *topology.DiskInfo, sourceRack, sourceDC string, score := 0.0 - // Prefer disks with lower effective volume count (current + pending moves) + // Prefer disks with lower effective volume count (current + pending moves). + // LoadCount is included so that disks already targeted by planned moves + // appear more utilized, naturally spreading work across targets. if disk.DiskInfo.MaxVolumeCount > 0 { effectiveVolumeCount := float64(disk.DiskInfo.VolumeCount) + float64(disk.LoadCount) utilization := effectiveVolumeCount / float64(disk.DiskInfo.MaxVolumeCount) - score += (1.0 - utilization) * 40.0 // Up to 40 points for low utilization + score += (1.0 - utilization) * 50.0 // Up to 50 points for low utilization } // Prefer different racks for better distribution @@ -387,8 +389,5 @@ func calculateBalanceScore(disk *topology.DiskInfo, sourceRack, sourceDC string, score += 20.0 } - // Prefer disks with lower current load - score += (10.0 - float64(disk.LoadCount)) // Up to 10 points for low load - return score }