-
Notifications
You must be signed in to change notification settings - Fork 2k
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
cleanup: prevent leaks from time.After #11983
Conversation
@@ -177,15 +183,19 @@ func (s *execSession) startTransmit(ctx context.Context, conn *websocket.Conn) < | |||
|
|||
// send a heartbeat every 10 seconds | |||
go func() { | |||
t := time.NewTimer(heartbeatInterval) |
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.
helpers/
not available to api/
, so no helper function here
- make sure we call
t.Stop
- make sure the interval can never be non-positive
40c5e69
to
9826479
Compare
9826479
to
4b3c346
Compare
This PR replaces use of time.After with a safe helper function that creates a time.Timer to use instead. The new function returns both a time.Timer and a Stop function that the caller must handle. Unlike time.NewTimer, the helper function does not panic if the duration set is <= 0.
4b3c346
to
c1e033c
Compare
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.
LGTM 👍
// Returns the time.Timer and also a StopFunc, forcing the caller to deal | ||
// with stopping the time.Timer to avoid leaking a goroutine. | ||
func NewSafeTimer(duration time.Duration) (*time.Timer, StopFunc) { |
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 really like the API on this. It makes it really obvious if we're accidentally misusing it by ex. calling NewSafeTimer
inside the loop.
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 helper 👍
I used this semgrep rule and it find some other instance of this pattern:
rules:
- id: "time-after-leak"
patterns:
- pattern: |
select {
case <- time.After(...): ...
}
message: "Potential leak of timer"
languages:
- "go"
severity: "WARNING"
paths:
exclude:
- "testutil/*"
- "*testing.go"
- "*_test.go"
But I don't know if the are all valid or if there are any false positives.
I think that's a valid rule @lgfa29 in theory you don't need the |
Yeah, good idea, I will update the message 👍 |
I'm going to lock this pull request because it has been closed for 120 days ⏳. This helps our maintainers find and focus on the active contributions. |
This PR replaces use of time.After with a safe helper function
that creates a time.Timer to use instead. The new function returns
both a time.Timer and a Stop function that the caller must handle.
Unlike time.NewTimer, the helper function does not panic if the duration
set is <= 0.
Fixes #11982