Skip to content

Commit 22add55

Browse files
committed
fix: prevent race condition by ensuring reader goroutine starts before container output
1 parent 2680444 commit 22add55

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

src/environment/docker/container.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ func (e *Environment) Attach(ctx context.Context) error {
6464
e.SetStream(&st)
6565
}
6666

67+
// Create a channel to signal when the reader goroutine has started.
68+
// This prevents a race condition where the container starts producing output
69+
// before the goroutine begins reading, causing initial console output to be lost.
70+
readerStarted := make(chan struct{})
71+
6772
go func() {
6873
// Don't use the context provided to the function, that'll cause the polling to
6974
// exit unexpectedly. We want a custom context for this, the one passed to the
@@ -86,6 +91,10 @@ func (e *Environment) Attach(ctx context.Context) error {
8691
}
8792
}()
8893

94+
// Signal that the reader goroutine has started and is about to begin reading.
95+
// This must be done before ScanReader is called to ensure proper synchronization.
96+
close(readerStarted)
97+
8998
if err := system.ScanReader(e.stream.Reader, func(v []byte) {
9099
e.logCallbackMx.Lock()
91100
defer e.logCallbackMx.Unlock()
@@ -96,7 +105,17 @@ func (e *Environment) Attach(ctx context.Context) error {
96105
}
97106
}()
98107

99-
return nil
108+
// Wait for the reader goroutine to start before returning. This ensures that
109+
// when the container starts immediately after this function returns, the output
110+
// reader is already active and won't miss any initial console output.
111+
//
112+
// Use a select with the context to avoid hanging indefinitely if something goes wrong.
113+
select {
114+
case <-readerStarted:
115+
return nil
116+
case <-ctx.Done():
117+
return errors.WrapIf(ctx.Err(), "environment/docker: context canceled while waiting for reader to start")
118+
}
100119
}
101120

102121
// InSituUpdate performs an in-place update of the Docker container's resource

0 commit comments

Comments
 (0)