Skip to content

refactor(compose): drop the timeout parameter of waitDependencies - #14400

Merged
ndeloof merged 3 commits into
docker:mainfrom
ndeloof:chore/drop-wait-dependencies-timeout
Oct 27, 2026
Merged

ndeloof merged 3 commits into
docker:mainfrom
ndeloof:chore/drop-wait-dependencies-timeout

Conversation

@ndeloof

@ndeloof ndeloof commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

What this PR does, in one sentence

Removes the timeout parameter of waitDependencies, which every caller sets to 0, and moves the tests that used it onto the paths that really bound a wait.

Context

waitDependencies wraps its context in context.WithTimeout when timeout > 0. All four callers outside the tests — up --wait, start --wait, run and restart — pass a literal 0, and nothing else can reach this unexported method. So the wrapper is dead. The two ways a wait really gets a deadline do not use it: up and start --wait wrap the context themselves before the call, and the plan's OpWaitCondition nodes are bounded by exec.waitTimeout in execBoundedWaitCondition, which calls waitDependencyReached directly.

That dead parameter is what the unit tests of the dependency waits were built on, which hides where the semantics they lock actually live.

What the PR brings

  • waitDependencies loses its timeout parameter and the dead branch; its callers drop the 0. Nothing else changes in the production code, apart from two comments that said who gives a wait a timeout of its own.
  • The tests that passed a timeout exercise the same semantics through the live paths: a deadline on the caller's context for waitDependencies (the --wait route), and execBoundedWaitCondition with exec.waitTimeout for the wait's own timeout, tolerated on an optional dependency and an error on a required one.

Why this is no functional change

  • A repo-wide search finds no other route to waitDependencies (method value, interface, reflection, other package), and the four callers passed a literal 0.
  • Built from main and from this branch, the binaries have the same symbols; only waitDependencies changes size (1552 → 1280 bytes), next to the usual line tables and build info.
  • The standalone e2e suite, run with the same environment on both binaries: 332 results each, no difference (318 pass, 3 skipped, and the same 11 failures on both sides: the provider scenarios cannot find example-provider in the PATH, and TestComposeModel).
  • go vet, gofmt, the linter (only the known findings) and go test ./pkg/... -race pass, except pkg/watch, which fails the same way on main on macOS.

No coverage lost

Seven mutations of waitDependencyReached, waitDependencies and execBoundedWaitCondition, run against TestWaitDependencyDeadline and TestOptionalDependencyInspectFailure:

Mutation before after
own timeout tolerated for any deadline, an inherited one included caught caught
own timeout never tolerated on an optional dependency caught caught
deadline of a required dependency swallowed caught caught
plain cancellation not silent caught caught
waitDependencies no longer reports "timeout waiting for dependencies" caught caught
execBoundedWaitCondition ignores exec.waitTimeout survives caught
execBoundedWaitCondition no longer marks errWaitTimeout survives caught

The last two were only caught by the executor tests; they now are by these as well.

Part of #14081 (Lot 3).

🤖 Generated with Claude Code

Its four callers (up --wait, start --wait, run, restart) all pass 0, so the
wrapper it built around the context was dead: a wait only gets a timeout of
its own through the plan's OpWaitCondition nodes, which bound it with
exec.waitTimeout in execBoundedWaitCondition and never go through
waitDependencies. A deadline on the caller's context, which is how up and
start --wait bound their wait, is untouched.

The tests that passed a timeout now exercise the same semantics through
the live paths: a deadline on the caller's context for waitDependencies,
and execBoundedWaitCondition with exec.waitTimeout for the wait's own
timeout (tolerated on an optional dependency, an error on a required one).

Part of docker#14081

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Now that waitDependencies has no timeout parameter, the plan's wait nodes
are the only ones to wrap the context of a wait: tell so in the comment of
waitDependency, which compares the wrapped context with the original.

Comments only.

Part of docker#14081

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
…line class

Review follow-ups of the removal of waitDependencies' timeout parameter:
the unsupported-condition test lost the 2s bound the parameter gave it, so
a regression that waits would hang instead of failing; and the test
comparing a timeout that expires during the inspection with one that
expires between polls now also compares whether they are a deadline.
Also reword the comment of execWaitCondition, which still said that
waitDependencies threads a timeout through its waits.

Part of docker#14081

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
@ndeloof
ndeloof requested review from a team as code owners October 27, 2026 10:30

@docker-agent docker-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟢 APPROVE

@codecov

codecov Bot commented Oct 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 60.00000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/compose/run.go 0.00% 0 Missing and 1 partial ⚠️
pkg/compose/start.go 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@ndeloof
ndeloof merged commit 27fbcae into docker:main Oct 27, 2026
63 of 66 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants