From 41b7cd8221b718a770a252d0fb0204e8cdce482f Mon Sep 17 00:00:00 2001 From: madhoshyagnik Date: Sun, 23 Aug 2026 15:32:03 +0530 Subject: [PATCH] fix(compose): resolve multiple epic #14074 findings - Fix bug where success boolean in bus.Done was inverted in pkg/compose/progress.go - Move Watcher mutex from package-level to struct-level in pkg/compose/watch.go - Fix state machine leak in Watcher.Start on failed start - Add AI_AGENT_DISCLOSURE.md Ref #14074 Signed-off-by: madhoshyagnik --- AI_AGENT_DISCLOSURE.md | 3 +++ pkg/compose/progress.go | 2 +- pkg/compose/watch.go | 18 +++++++----------- 3 files changed, 11 insertions(+), 12 deletions(-) create mode 100644 AI_AGENT_DISCLOSURE.md diff --git a/AI_AGENT_DISCLOSURE.md b/AI_AGENT_DISCLOSURE.md new file mode 100644 index 00000000000..bbab707f3c8 --- /dev/null +++ b/AI_AGENT_DISCLOSURE.md @@ -0,0 +1,3 @@ +This contribution was prepared by an AI agent acting on a human's behalf. +The human submitter may not have independently reviewed or tested the change. +2026-08-23 diff --git a/pkg/compose/progress.go b/pkg/compose/progress.go index 7defdf2e55d..cff5613b711 100644 --- a/pkg/compose/progress.go +++ b/pkg/compose/progress.go @@ -28,7 +28,7 @@ type progressFunc func(context.Context) error func Run(ctx context.Context, pf progressFunc, operation string, bus api.EventProcessor) error { bus.Start(ctx, operation) err := pf(ctx) - bus.Done(operation, err != nil) + bus.Done(operation, err == nil) return err } diff --git a/pkg/compose/watch.go b/pkg/compose/watch.go index 71af227f3f6..a8673049aba 100644 --- a/pkg/compose/watch.go +++ b/pkg/compose/watch.go @@ -50,6 +50,7 @@ import ( type WatchFunc func(ctx context.Context, project *types.Project, options api.WatchOptions) (func() error, error) type Watcher struct { + mx gsync.Mutex project *types.Project options api.WatchOptions watchFn WatchFunc @@ -78,21 +79,16 @@ func NewWatcher(project *types.Project, options api.UpOptions, w WatchFunc, cons return nil, fmt.Errorf("none of the selected services is configured for watch, see https://docs.docker.com/compose/how-tos/file-watch/") } -// ensure state changes are atomic -var mx gsync.Mutex - func (w *Watcher) Start(ctx context.Context) error { - mx.Lock() - defer mx.Unlock() + w.mx.Lock() + defer w.mx.Unlock() ctx, cancelFunc := context.WithCancel(ctx) - w.stopFn = cancelFunc wait, err := w.watchFn(ctx, w.project, w.options) if err != nil { - go func() { - w.errCh <- err - }() + cancelFunc() return err } + w.stopFn = cancelFunc go func() { w.errCh <- wait() }() @@ -100,8 +96,8 @@ func (w *Watcher) Start(ctx context.Context) error { } func (w *Watcher) Stop() error { - mx.Lock() - defer mx.Unlock() + w.mx.Lock() + defer w.mx.Unlock() if w.stopFn == nil { return nil }