From a1c90de8f333936f521bb5cf2064ce06b166798b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 00:15:53 +0000 Subject: [PATCH] fix: improve comment wording and strengthen race test start barrier Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/9e4d6f4f-cdc1-4e9e-bdc6-81061ebc1dcc Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> --- pkg/state/chart_dependencies_rewrite_test.go | 11 ++++++++--- pkg/state/state.go | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/state/chart_dependencies_rewrite_test.go b/pkg/state/chart_dependencies_rewrite_test.go index 2cc11868..fda69c33 100644 --- a/pkg/state/chart_dependencies_rewrite_test.go +++ b/pkg/state/chart_dependencies_rewrite_test.go @@ -528,18 +528,22 @@ dependencies: } // Run multiple goroutines concurrently on the same chart path. - // A start barrier ensures all goroutines attempt rewriteChartDependencies simultaneously. + // A readiness WaitGroup ensures all goroutines are blocked before the start barrier is released, + // so calls to rewriteChartDependencies overlap as much as possible. numGoroutines := 10 var wg sync.WaitGroup + var readyWg sync.WaitGroup errCh := make(chan error, numGoroutines) ready := make(chan struct{}) for i := 0; i < numGoroutines; i++ { wg.Add(1) + readyWg.Add(1) go func() { defer wg.Done() - // Wait until all goroutines are ready so they start simultaneously. + // Signal that this goroutine is ready, then wait for the start signal. + readyWg.Done() <-ready logger := zap.NewNop().Sugar() @@ -557,7 +561,8 @@ dependencies: }() } - // Release all goroutines at once to maximize contention. + // Wait until all goroutines are ready, then release them simultaneously. + readyWg.Wait() close(ready) wg.Wait() diff --git a/pkg/state/state.go b/pkg/state/state.go index 6bbfef2f..c1f20282 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -1473,7 +1473,8 @@ func (st *HelmState) rewriteChartDependencies(chartPath string) (func(), error) } } - // If nothing changed, release the lock immediately – no file I/O or lock held by caller needed. + // If nothing changed, release the lock immediately. Chart.yaml has already been read and + // unmarshaled above, but no file write is needed and the lock is not held beyond this function. if !modified { mu.Unlock() return func() {}, nil