Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

konnectivity-client: ensure Close() is called for grpc.ClientConn in CreateSingleUseGrpcTunnel #328

Merged
merged 1 commit into from Feb 23, 2022

Conversation

andrewsykim
Copy link
Member

As part of the on-going investigation in #276.

If grpcClient.Proxy(ctx) from CreateSingleUseGrpcTunnel errors, then we never call Close() on the client connection.

Signed-off-by: Andrew Sy Kim andrewsy@google.com

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Feb 23, 2022
@k8s-ci-robot k8s-ci-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Feb 23, 2022
@@ -151,6 +152,15 @@ func TestClose(t *testing.T) {
}
}

func TestCreateSingleUseGrpcTunnel_NoLeakOnFailure(t *testing.T) {
Copy link
Member Author

Choose a reason for hiding this comment

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

I removed this test to avoid changing our go modules for now, but here's the test that reproduces the goroutine leak without the fix:

func TestCreateSingleUseGrpcTunnel_NoLeakOnFailure(t *testing.T) {
    defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
    
     _, err := CreateSingleUseGrpcTunnel(context.Background(), "127.0.0.1:12345", grpc.WithInsecure())
    if err == nil {
        t.Fatal("expected error when calling CreateSingleUseGrpcTunnel")
    }
}

$ go test ./...
I0223 02:03:46.766980   27663 client.go:104] "stream read failure"
I0223 02:03:46.767325   27663 client.go:104] "stream read failure"
--- FAIL: TestCreateSingleUseGrpcTunnel_NoLeakOnFailure (0.45s)
    leaks.go:78: found unexpected goroutines:
        [Goroutine 25 in state select, with google.golang.org/grpc.(*ccBalancerWrapper).watcher on top of the stack:
        goroutine 25 [select]:
        google.golang.org/grpc.(*ccBalancerWrapper).watcher(0xc0001ae4c0)
                /....pkg/mod/google.golang.org/grpc@v1.27.1/balancer_conn_wrappers.go:69 +0x8f
        created by google.golang.org/grpc.newCCBalancerWrapper
                /.../pkg/mod/google.golang.org/grpc@v1.27.1/balancer_conn_wrappers.go:60 +0x1ca
        
         Goroutine 26 in state select, with google.golang.org/grpc.(*addrConn).resetTransport on top of the stack:
        goroutine 26 [select]:
        google.golang.org/grpc.(*addrConn).resetTransport(0xc0001fe000)
                /.../pkg/mod/google.golang.org/grpc@v1.27.1/clientconn.go:1149 +0x5f7
        created by google.golang.org/grpc.(*addrConn).connect
                /.../pkg/mod/google.golang.org/grpc@v1.27.1/clientconn.go:815 +0x145
        ]
FAIL
FAIL    sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client      0.496s
FAIL

Copy link
Member Author

Choose a reason for hiding this comment

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

^ consistent with pprof data collected here kubernetes/kubernetes#108215 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

@andrewsykim IMHO it will be great to add this test back. We had a bunch of fixes in the konnectivity-client and each fix there means we need to backport it to k8s, which is painful and slow to rollout to customers.

IMHO, it seems nice to keep it, the deps didn't seem like so many. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah I'll look into adding it back, it'll mostly depend on how it effects deps which I can look into

Copy link
Contributor

Choose a reason for hiding this comment

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

@andrewsykim it seems it might not be an issue with go 1.17 if we just use it in tests? See the last paragraph in the selected answer: https://stackoverflow.com/questions/64071364/best-way-to-use-test-dependencies-in-go-but-prevent-export-them

Not sure if that will do the trick. Also, kubernetes 1.21 to 1.23 is using go 1.16 so, even if it does help, not right now. The other option might be to move the tests to another pkg, but it is not great either :(

Copy link
Member Author

Choose a reason for hiding this comment

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

Created #333 to follow-up, I'll open a PR to add these back after I test the module update in k/k

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks!

…CreateSingleUseGrpcTunnel

Signed-off-by: Andrew Sy Kim <andrewsy@google.com>
@andrewsykim
Copy link
Member Author

/assign @cheftako

@andrewsykim
Copy link
Member Author

/retest

@@ -76,6 +76,7 @@ func CreateSingleUseGrpcTunnel(ctx context.Context, address string, opts ...grpc

stream, err := grpcClient.Proxy(ctx)
if err != nil {
c.Close()
Copy link
Member Author

Choose a reason for hiding this comment

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

c.Close() was only called from tunnel.serve() below. If grpc.Client.Proxy() errors, which is possible when there are no client connections available, we would never call c.Close()

Choose a reason for hiding this comment

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

good catch

@andrewsykim
Copy link
Member Author

/hold

(for reviews)

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Feb 23, 2022
@k8s-ci-robot k8s-ci-robot added size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Feb 23, 2022
@cheftako
Copy link
Contributor

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Feb 23, 2022
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: andrewsykim, cheftako

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

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [andrewsykim,cheftako]

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

@andrewsykim
Copy link
Member Author

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Feb 23, 2022
@k8s-ci-robot k8s-ci-robot merged commit d2eec1e into kubernetes-sigs:master Feb 23, 2022
This was referenced Feb 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants