-
Notifications
You must be signed in to change notification settings - Fork 584
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
otelgrpc: fix goroutine leak after context cancellation #840
Conversation
|
@vadimberezniker @tonistiigi |
return | ||
} | ||
|
||
case <-s.Context().Done(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disclaimer: I'm not a maintainer on this project but I have been looking at this code recently.
If we trust the ClientStream.Context() docs then it's not safe to use the Context() call here:
// Context returns the context for this stream.
//
// It should not be called until after Header or RecvMsg has returned. Once
// called, subsequent client-side retries are disabled.
Context() context.Context
Edit: I just double checked the gRPC code and Context() does have side-effects.
The alternative is to pass the parent context and check that.
Thanks for fixing this, I noticed this while fixing the other issue and this was next on my plate.
Does |
If the client properly handles the stream, the ctx.Done() case should not be reached. That should be handled by the event for loop. |
@vadimberezniker I understand that. The canceling flow should be 1) context client passed gets canceled 2) cancellation is passed to the server-side 3) server closes either cleanly or with an error 4) client receives the close and stream is finished. Just cancelling the context is just a signal and doesn't atomically close the stream by itself. I'm not sure about the internals, therefore it may be possible that |
2a635b9
to
27590c1
Compare
@vadimberezniker |
@tonistiigi
ClientStream is keeping track context closing. And does not notify about it. |
Based on my understanding when the context is cancelled, gRPC automatically closes the underlying HTTP2 stream so there's no opportunity for the server to send anything after that. |
I did some tests and indeed the server-side graceful cancel does not happen as I described before. I had forgotten that in the code where I use it I actually need to do two requests and only cancel one of them (that forces another to close cleanly) to achieve this behavior. But it is still possible that |
@Aneurysm9 @dashpole @evantorrie @jmacd @MadVikingGod @MrAlias @paivagustavo @XSAM |
The approach seems sane. Please fix the linting issue. |
Signed-off-by: Artem Glazychev <[email protected]>
@Aneurysm9 |
Codecov Report
@@ Coverage Diff @@
## main #840 +/- ##
=======================================
+ Coverage 79.2% 79.4% +0.2%
=======================================
Files 62 62
Lines 2750 2755 +5
=======================================
+ Hits 2178 2188 +10
+ Misses 440 437 -3
+ Partials 132 130 -2
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall.
instrumentation/google.golang.org/grpc/otelgrpc/interceptor_test.go
Outdated
Show resolved
Hide resolved
Signed-off-by: Artem Glazychev <[email protected]>
@pellared Pardon my ignorance of the process... but what else has to be done before this fix can be merged? |
@Aneurysm9 @MrAlias PTAL |
Yay! |
This PR is related to this issue: #839