-
Notifications
You must be signed in to change notification settings - Fork 4.5k
transport: Send RST stream from the server when deadline expires #8071
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
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #8071 +/- ##
==========================================
+ Coverage 82.32% 82.35% +0.02%
==========================================
Files 388 389 +1
Lines 39016 39098 +82
==========================================
+ Hits 32121 32199 +78
- Misses 5574 5577 +3
- Partials 1321 1322 +1
|
805939c
to
6dda22e
Compare
806c418
to
fca2350
Compare
fca2350
to
a97949e
Compare
internal/grpctest/grpctest.go
Outdated
} | ||
|
||
// Teardown performs a leak check. | ||
func (Tester) Teardown(t *testing.T) { | ||
leakcheck.CheckTrackingBufferPool() | ||
leakcheck.CheckTimers(5 * time.Second) |
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.
This is additive with the 10s for checking goroutines. It might be nice to pass a context (or timer) to both of these instead, so they can share the 10s timeout?
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.
Nice idea, changed.
internal/leakcheck/leakcheck.go
Outdated
|
||
originalTimeAfterFunc func(time.Duration, func()) internal.Timer | ||
mu sync.Mutex | ||
bufferCount int |
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.
Delete
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.
Oops, removed.
internal/leakcheck/leakcheck.go
Outdated
type timerFactory struct { | ||
logger Logger | ||
|
||
originalTimeAfterFunc func(time.Duration, func()) internal.Timer |
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.
Is there any need for this? As opposed to just directly calling time.AfterFunc
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.
I was thinking about a future scenarios when subtests and outer tests both start leak checks. Having the previously set function would allow wrapping the outer tests function. The global globalTimerTracker
would still prevent this from working.
Removed this field. This use case can be addressed if/when it arises.
internal/leakcheck/leakcheck.go
Outdated
// not all timers were cancelled or executed. It is invalid to invoke this | ||
// function without previously having invoked SetTimerTracker. | ||
func CheckTimers(timeout time.Duration) { | ||
// Reset the internal function. |
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.
This happens at the end?
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.
Yes, moved the comment to the end.
internal/transport/http2_client.go
Outdated
// of this cancellation. Alter the status code accordingly. | ||
// of this cancellation. Alter the status code accordingly. |
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.
Please revert.
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.
It seemed like a harmless typo fix, but I’ve reverted it as requested.
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.
It's not a typo. :)
"Two spaces after periods" was recommended when typewriters were used, because they were fixed-width, and it helped with readability:
https://graphicdesign.stackexchange.com/questions/2160/typesetting-two-spaces-after-the-period
I prefer continuing the tradition with source code since it isn't rendered in a variable-width font (also it's a habit), but I am fine with people wanting to use one space. We shouldn't go around changing it from one way to the other, though, as it creates churn and is just a preference, not a typo.
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.
Thanks for sharing, wasn't aware of this.
internal/leakcheck/leakcheck.go
Outdated
// SetTimerTracker replaces internal.TimerAfterFunc with a one that tracks | ||
// timer creations. CheckTimers should then be invoked at the end of the test to | ||
// validate that all timers created have either executed or are cancelled. | ||
func SetTimerTracker(logger Logger) { |
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.
Can you add a test for this functionality?
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.
Didn't notice that there were tests for this file. Added a test now.
internal/transport/http2_server.go
Outdated
s.deadlineTimerCancel = func() { | ||
timer.Stop() | ||
} |
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.
s.deadlineTimerCancel = func() { | |
timer.Stop() | |
} | |
s.deadlineTimerCancel = timer.Stop |
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.
Changed to use the cancel
field on ServerStream
. cancel
is always set to a non-nil value, so this issue is solved.
internal/transport/http2_server.go
Outdated
if s.deadlineTimerCancel != nil { | ||
s.deadlineTimerCancel() | ||
} |
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.
Should we make sure this is always a valid function so we can just call it without the nil check?
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.
Changed to use the existing cancel
field.
internal/transport/server_stream.go
Outdated
cancel context.CancelFunc // invoked at the end of stream to cancel ctx. | ||
deadlineTimerCancel func() // Invoked at the end of stream. |
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.
Do we always call cancel
? Can we piggyback the timer cancellation with it if so?
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.
Yes we do, changed to use cancel
.
Co-authored-by: Doug Fawley <[email protected]>
Fixes: #2886
This PR makes the server cancel an RPC when it sees the deadline expiring instead of waiting forn the client to cancel the stream.
RELEASE NOTES: