Skip to content

Commit 86e4009

Browse files
authored
fix: user Timers over time.After (#1802)
Can reduce memory usuage for stacking timers that are not gc'ed in retry loops. Fixes: #1761
1 parent bcc345c commit 86e4009

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

internal/gensupport/resumable.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,22 +193,28 @@ func (rx *ResumableUpload) Upload(ctx context.Context) (resp *http.Response, err
193193

194194
// Each chunk gets its own initialized-at-zero backoff and invocation ID.
195195
bo := rx.Retry.backoff()
196-
quitAfter := time.After(retryDeadline)
196+
quitAfterTimer := time.NewTimer(retryDeadline)
197197
rx.attempts = 1
198198
rx.invocationID = uuid.New().String()
199199

200200
// Retry loop for a single chunk.
201201
for {
202+
pauseTimer := time.NewTimer(pause)
202203
select {
203204
case <-ctx.Done():
205+
quitAfterTimer.Stop()
206+
pauseTimer.Stop()
204207
if err == nil {
205208
err = ctx.Err()
206209
}
207210
return prepareReturn(resp, err)
208-
case <-time.After(pause):
209-
case <-quitAfter:
211+
case <-pauseTimer.C:
212+
quitAfterTimer.Stop()
213+
case <-quitAfterTimer.C:
214+
pauseTimer.Stop()
210215
return prepareReturn(resp, err)
211216
}
217+
pauseTimer.Stop()
212218

213219
// Check for context cancellation or timeout once more. If more than one
214220
// case in the select statement above was satisfied at the same time, Go
@@ -217,13 +223,15 @@ func (rx *ResumableUpload) Upload(ctx context.Context) (resp *http.Response, err
217223
// canceled before or the timeout was reached.
218224
select {
219225
case <-ctx.Done():
226+
quitAfterTimer.Stop()
220227
if err == nil {
221228
err = ctx.Err()
222229
}
223230
return prepareReturn(resp, err)
224-
case <-quitAfter:
231+
case <-quitAfterTimer.C:
225232
return prepareReturn(resp, err)
226233
default:
234+
quitAfterTimer.Stop()
227235
}
228236

229237
resp, err = rx.transferChunk(ctx)

internal/gensupport/send.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,17 @@ func sendAndRetry(ctx context.Context, client *http.Client, req *http.Request, r
115115
var errorFunc = retry.errorFunc()
116116

117117
for {
118+
t := time.NewTimer(pause)
118119
select {
119120
case <-ctx.Done():
121+
t.Stop()
120122
// If we got an error and the context has been canceled, return an error acknowledging
121123
// both the context cancelation and the service error.
122124
if err != nil {
123125
return resp, wrappedCallErr{ctx.Err(), err}
124126
}
125127
return resp, ctx.Err()
126-
case <-time.After(pause):
128+
case <-t.C:
127129
}
128130

129131
if ctx.Err() != nil {

transport/bytestream/client.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,11 @@ func (r *Reader) Read(p []byte) (int, error) {
8989
if backoffDelay > backoffMax {
9090
backoffDelay = backoffMax
9191
}
92+
t := time.NewTimer(backoffDelay)
9293
select {
93-
case <-time.After(backoffDelay):
94+
case <-t.C:
9495
case <-r.ctx.Done():
96+
t.Stop()
9597
if err := r.ctx.Err(); err != nil {
9698
r.err = err
9799
}

0 commit comments

Comments
 (0)