Skip to content

Commit 42c8ae3

Browse files
authored
fix: avoid scheduling an instance refresh if the context is done (#491)
Fixes #493
1 parent ff5ca35 commit 42c8ae3

File tree

2 files changed

+15
-8
lines changed

2 files changed

+15
-8
lines changed

internal/alloydb/instance.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,11 @@ func (i *Instance) OpenConns() *uint64 {
189189
// Close closes the instance; it stops the refresh cycle and prevents it from
190190
// making additional calls to the AlloyDB Admin API.
191191
func (i *Instance) Close() error {
192+
i.resultGuard.Lock()
193+
defer i.resultGuard.Unlock()
192194
i.cancel()
195+
i.cur.cancel()
196+
i.next.cancel()
193197
return nil
194198
}
195199

@@ -230,6 +234,8 @@ func (i *Instance) result(ctx context.Context) (*refreshOperation, error) {
230234
err = res.err
231235
case <-ctx.Done():
232236
err = ctx.Err()
237+
case <-i.ctx.Done():
238+
err = i.ctx.Err()
233239
}
234240
if err != nil {
235241
return nil, err
@@ -260,6 +266,13 @@ func (i *Instance) scheduleRefresh(d time.Duration) *refreshOperation {
260266
r := &refreshOperation{}
261267
r.ready = make(chan struct{})
262268
r.timer = time.AfterFunc(d, func() {
269+
// instance has been closed, don't schedule anything
270+
if err := i.ctx.Err(); err != nil {
271+
r.err = err
272+
close(r.ready)
273+
return
274+
}
275+
263276
ctx, cancel := context.WithTimeout(i.ctx, i.refreshTimeout)
264277
defer cancel()
265278

@@ -280,6 +293,7 @@ func (i *Instance) scheduleRefresh(d time.Duration) *refreshOperation {
280293
// result and schedule a new refresh
281294
i.resultGuard.Lock()
282295
defer i.resultGuard.Unlock()
296+
283297
// if failed, scheduled the next refresh immediately
284298
if r.err != nil {
285299
i.next = i.scheduleRefresh(0)
@@ -297,12 +311,6 @@ func (i *Instance) scheduleRefresh(d time.Duration) *refreshOperation {
297311
// Update the current results, and schedule the next refresh in
298312
// the future
299313
i.cur = r
300-
select {
301-
case <-i.ctx.Done():
302-
// instance has been closed, don't schedule anything
303-
return
304-
default:
305-
}
306314
t := refreshDuration(time.Now(), i.cur.result.expiry)
307315
i.next = i.scheduleRefresh(t)
308316
})

internal/alloydb/instance_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"crypto/rand"
2020
"crypto/rsa"
2121
"errors"
22-
"strings"
2322
"testing"
2423
"time"
2524

@@ -216,7 +215,7 @@ func TestClose(t *testing.T) {
216215
i.Close()
217216

218217
_, _, err = i.ConnectInfo(ctx)
219-
if !strings.Contains(err.Error(), "context was canceled or expired") {
218+
if !errors.Is(err, context.Canceled) {
220219
t.Fatalf("failed to retrieve connect info: %v", err)
221220
}
222221
}

0 commit comments

Comments
 (0)