MCPcopy
hub / github.com/docker/compose / waitPreStart

Function waitPreStart

pkg/compose/pre_start.go:212–247  ·  pkg/compose/pre_start.go::waitPreStart
(ctx context.Context, serviceName string, index int, waitRes client.ContainerWaitResult)

Source from the content-addressed store, hash-verified

210}
211
212func waitPreStart(ctx context.Context, serviceName string, index int, waitRes client.ContainerWaitResult) error {
213 // ContainerWait can deliver on Result and Error at the same instant. Two
214 // races have to be closed deterministically here:
215 // 1. The daemon closing a successful stream cleanly sends nil on Error
216 // AND the exit code on Result — a plain 3-case select would let Go
217 // pick the Error branch and report a spurious "wait ended" failure.
218 // 2. A real transport error on Error can race with a stale Result — if
219 // the scheduler picks Result, we would silently drop the error and
220 // let the service start.
221 // Loop until Result is delivered, nil-ing the Error channel after a nil
222 // receive so a closed channel cannot busy-loop. After Result lands, do a
223 // non-blocking check on Error so a real error still wins over Result.
224 errCh := waitRes.Error
225 for {
226 select {
227 case <-ctx.Done():
228 return ctx.Err()
229 case res := <-waitRes.Result:
230 select {
231 case err := <-errCh:
232 if err != nil {
233 return err
234 }
235 default:
236 }
237 return preStartResultErr(serviceName, index, res)
238 case err := <-errCh:
239 if err != nil {
240 return err
241 }
242 // nil on Error: stream closed cleanly. Disable this case so a
243 // closed channel can't fire repeatedly.
244 errCh = nil
245 }
246 }
247}
248
249func preStartResultErr(serviceName string, index int, res container.WaitResponse) error {
250 if res.Error != nil {

Calls 3

preStartResultErrFunction · 0.85
DoneMethod · 0.65
ErrMethod · 0.65