Skip to content

fix(knative): fix goroutine leak in Deploy - #3808

Merged
knative-prow[bot] merged 3 commits into
knative:mainfrom
Elvand-Lie:fix/knative-goroutine-leak-only
Oct 30, 2026
Merged

knative-prow[bot] merged 3 commits into
knative:mainfrom
Elvand-Lie:fix/knative-goroutine-leak-only

Conversation

@Elvand-Lie

Copy link
Copy Markdown
Contributor

Problem

The Deploy function (new-service creation path) starts a background goroutine that polls isImageInPrivateRegistry every 5 seconds and sends results on an unbuffered chprivate channel.

If WaitForService completes first (via cherr), the main function returns and the poller goroutine blocks forever on the channel send with no receiver, leaking the goroutine and captured context.

Fix

Fixed by adding a done channel that the main select loop closes when it exits. The poller goroutine now selects on done alongside its timer and channel send, so it always exits promptly.

Fixes #3797

@knative-prow
knative-prow Bot requested review from dsimansk and jrangelramos May 20, 2026 19:55
@knative-prow knative-prow Bot added size/S 🤖 PR changes 10-29 lines, ignoring generated files. needs-ok-to-test 🤖 Needs an org member to approve testing labels May 20, 2026
@knative-prow

knative-prow Bot commented May 20, 2026

Copy link
Copy Markdown

Hi @Elvand-Lie. Thanks for your PR.

I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@codecov

codecov Bot commented May 20, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.06%. Comparing base (d7b93f6) to head (a4df2f7).
⚠️ Report is 93 commits behind head on main.

Files with missing lines Patch % Lines
pkg/knative/deployer.go 85.71% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3808      +/-   ##
==========================================
- Coverage   54.00%   53.06%   -0.94%     
==========================================
  Files         200      200              
  Lines       23687    23694       +7     
==========================================
- Hits        12792    12574     -218     
- Misses       9660     9898     +238     
+ Partials     1235     1222      -13     
Flag Coverage Δ
e2e 21.62% <74.28%> (-12.44%) ⬇️
e2e go 29.41% <76.66%> (+0.01%) ⬆️
e2e node 25.73% <76.66%> (+0.01%) ⬆️
e2e python 29.74% <76.66%> (+0.01%) ⬆️
e2e quarkus 25.86% <76.66%> (+0.03%) ⬆️
e2e rust 25.32% <76.66%> (+<0.01%) ⬆️
e2e springboot 24.02% <76.66%> (+0.01%) ⬆️
e2e typescript 25.85% <76.66%> (+0.01%) ⬆️
e2e-config-ci 26.91% <76.66%> (+0.01%) ⬆️
integration 15.70% <76.66%> (+0.02%) ⬆️
unit macos-14 43.14% <60.00%> (+0.09%) ⬆️
unit macos-latest 43.14% <60.00%> (+0.09%) ⬆️
unit ubuntu-24.04-arm 43.45% <62.85%> (+0.08%) ⬆️
unit ubuntu-latest 44.00% <60.00%> (+0.09%) ⬆️
unit windows-latest 43.21% <60.00%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gauron99 gauron99 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.

Thanks for the PR, I think there is the same issue in the waiter goroutine. Couldn't cherr also be blocked forever? We could make cherr buffered make(chan error, 1) or add the same done check in select as you did above.

@Elvand-Lie
Elvand-Lie force-pushed the fix/knative-goroutine-leak-only branch 2 times, most recently from 677fc36 to e4b4df8 Compare May 21, 2026 06:45
@Elvand-Lie

Elvand-Lie commented May 21, 2026 •

Copy link
Copy Markdown
Contributor Author

didn't think about the waiter goroutine blocking on cherr if the main loop exits early. I've updated cherr to be buffered as you suggested and pushed the fix. Thank you @gauron99

@Elvand-Lie
Elvand-Lie force-pushed the fix/knative-goroutine-leak-only branch from e4b4df8 to 38096f9 Compare May 21, 2026 07:15
@knative-prow knative-prow Bot added size/L 🤖 PR changes 100-499 lines, ignoring generated files. and removed size/S 🤖 PR changes 10-29 lines, ignoring generated files. labels May 21, 2026
@Elvand-Lie
Elvand-Lie force-pushed the fix/knative-goroutine-leak-only branch from 38096f9 to ee1737b Compare May 21, 2026 07:32
@lkingland lkingland added ok-to-test 🤖 Non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test 🤖 Needs an org member to approve testing labels May 21, 2026
@matejvasek
matejvasek requested a review from Copilot June 12, 2026 15:55

Copilot AI 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.

Pull request overview

Fixes a goroutine leak in the Knative deployer’s new-service Deploy path by ensuring the private-registry polling goroutine can always exit when the main wait logic finishes.

Changes:

  • Introduces a sentinel errPrivateRegistry and refactors the readiness/private-registry wait logic into waitForReadyOrPrivateRegistry.
  • Prevents the private-registry polling goroutine from blocking forever by adding a done signal and buffering the service-wait error channel.
  • Adds focused unit tests for waitForReadyOrPrivateRegistry.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
pkg/knative/deployer.go Refactors Deploy wait logic into a helper and adds cancellation signaling to avoid goroutine leaks.
pkg/knative/deployer_test.go Adds unit tests covering success, wait error, private-registry detection, and delayed success scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/knative/deployer.go Outdated
Comment on lines 237 to 245
waitForService := func() error {
err, _ := client.WaitForService(ctx, f.Name,
clientservingv1.WaitConfig{Timeout: k8s.DefaultWaitingTimeout, ErrorWindow: k8s.DefaultErrorWindowTimeout},
wait.NoopMessageCallback())
cherr <- err
close(cherr)
}()

presumePrivate := false
main:
// Wait for either a timeout or a container condition signaling the image is unreachable
for {
select {
case private := <-chprivate:
if private {
presumePrivate = true
break main
}
case err = <-cherr:
break main
}
return err
}
if presumePrivate {
err := fmt.Errorf("your function image is unreachable. It is possible that your docker registry is private. If so, make sure you have set up pull secrets https://knative.dev/docs/developer/serving/deploying-from-private-registry")
return fn.DeploymentResult{}, err
isPrivateRegistry := func() bool {
return d.isImageInPrivateRegistry(ctx, client, f)
}
@Elvand-Lie
Elvand-Lie force-pushed the fix/knative-goroutine-leak-only branch from ee1737b to a4df2f7 Compare June 26, 2026 13:36
@knative-prow-robot knative-prow-robot added the needs-rebase Cannot be merged due to conflicts with HEAD. label Aug 24, 2026
Elvand-Lie and others added 3 commits October 29, 2026 21:34
The Deploy function (new-service creation path) starts a background
goroutine that polls isImageInPrivateRegistry every 5 seconds and
sends results on an unbuffered chprivate channel.

If WaitForService completes first (via cherr), the main function
returns and the poller goroutine blocks forever on the channel send
with no receiver, leaking the goroutine and captured context.

Fixed by adding a done channel that the main select loop closes when it
exits. The poller goroutine now selects on done alongside its timer and
channel send, so it always exits promptly.

Fixes knative#3797
Cancel alone leaves WaitForService and the log follower running
until they notice. Deploy returned in that window, so a
private-registry exit could leave the waiter alive until its
own timeout.

Cancel, then wait for each goroutine to finish. Waiting without
cancelling first deadlocks: both block until the context ends.
@lkingland
lkingland force-pushed the fix/knative-goroutine-leak-only branch from a4df2f7 to 8ffb670 Compare October 30, 2026 09:55
@knative-prow-robot knative-prow-robot removed the needs-rebase Cannot be merged due to conflicts with HEAD. label Oct 30, 2026
@lkingland

Copy link
Copy Markdown
Member

Thanks @Elvand-Lie! Rebased onto main and added a commit on top that cancels and then joins the waiter and log-follower goroutines on every return path (addressing the Copilot note), with tests for the private-registry and caller-cancel exits.

/lgtm
/approve

@knative-prow knative-prow Bot added the lgtm 🤖 PR is ready to be merged. label Oct 30, 2026
@knative-prow

knative-prow Bot commented Oct 30, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Elvand-Lie, lkingland

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@knative-prow knative-prow Bot added the approved 🤖 PR has been approved by an approver from all required OWNERS files. label Oct 30, 2026
@knative-prow
knative-prow Bot merged commit 2b42e06 into knative:main Oct 30, 2026
45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved 🤖 PR has been approved by an approver from all required OWNERS files. lgtm 🤖 PR is ready to be merged. ok-to-test 🤖 Non-member PR verified by an org member that is safe to test. size/L 🤖 PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

knative: goroutine leak in Deploy when service becomes ready before private-registry check

5 participants