Skip to content

Commit aeec731

Browse files
Added timeouts to contexts when calling etcd (#5392)
Signed-off-by: Soon-Ping Phang <[email protected]>
1 parent 3fc1bf0 commit aeec731

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
* [BUGFIX] Storage: Bucket index updater should ignore meta not found for partial blocks. #5343
3333
* [BUGFIX] Ring: Add JOINING state to read operation. #5346
3434
* [BUGFIX] Compactor: Partial block with only visit marker should be deleted even there is no deletion marker. #5342
35+
* [BUGFIX] KV: Etcd calls will no longer block indefinitely and will now time out after the DialTimeout period. #5392
3536

3637
## 1.15.1 2023-04-26
3738

pkg/ring/kv/etcd/etcd.go

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,11 @@ func (c *Client) CAS(ctx context.Context, key string, f func(in interface{}) (ou
124124
var revision int64
125125
var lastErr error
126126

127+
opsCtx, cancel := c.opsContext(ctx)
128+
defer cancel()
129+
127130
for i := 0; i < c.cfg.MaxRetries; i++ {
128-
resp, err := c.cli.Get(ctx, key)
131+
resp, err := c.cli.Get(opsCtx, key)
129132
if err != nil {
130133
level.Error(c.logger).Log("msg", "error getting key", "key", key, "err", err)
131134
lastErr = err
@@ -165,7 +168,7 @@ func (c *Client) CAS(ctx context.Context, key string, f func(in interface{}) (ou
165168
continue
166169
}
167170

168-
result, err := c.cli.Txn(ctx).
171+
result, err := c.cli.Txn(opsCtx).
169172
If(clientv3.Compare(clientv3.Version(key), "=", revision)).
170173
Then(clientv3.OpPut(key, string(buf))).
171174
Commit()
@@ -198,7 +201,12 @@ func (c *Client) WatchKey(ctx context.Context, key string, f func(interface{}) b
198201

199202
// Ensure the context used by the Watch is always cancelled.
200203
watchCtx, cancel := context.WithCancel(ctx)
201-
defer cancel()
204+
defer func() {
205+
cancel()
206+
level.Debug(c.logger).Log("msg", "Finished watching key", "key", key)
207+
}()
208+
209+
level.Debug(c.logger).Log("msg", "Watching key", "key", key)
202210

203211
outer:
204212
for backoff.Ongoing() {
@@ -234,7 +242,12 @@ func (c *Client) WatchPrefix(ctx context.Context, key string, f func(string, int
234242

235243
// Ensure the context used by the Watch is always cancelled.
236244
watchCtx, cancel := context.WithCancel(ctx)
237-
defer cancel()
245+
defer func() {
246+
cancel()
247+
level.Debug(c.logger).Log("msg", "Finished watching prefix", "key", key)
248+
}()
249+
250+
level.Debug(c.logger).Log("msg", "Watching prefix", "key", key)
238251

239252
outer:
240253
for backoff.Ongoing() {
@@ -268,7 +281,10 @@ outer:
268281

269282
// List implements kv.Client.
270283
func (c *Client) List(ctx context.Context, prefix string) ([]string, error) {
271-
resp, err := c.cli.Get(ctx, prefix, clientv3.WithPrefix(), clientv3.WithKeysOnly())
284+
opsCtx, cancel := c.opsContext(ctx)
285+
defer cancel()
286+
287+
resp, err := c.cli.Get(opsCtx, prefix, clientv3.WithPrefix(), clientv3.WithKeysOnly())
272288
if err != nil {
273289
return nil, err
274290
}
@@ -281,7 +297,10 @@ func (c *Client) List(ctx context.Context, prefix string) ([]string, error) {
281297

282298
// Get implements kv.Client.
283299
func (c *Client) Get(ctx context.Context, key string) (interface{}, error) {
284-
resp, err := c.cli.Get(ctx, key)
300+
opsCtx, cancel := c.opsContext(ctx)
301+
defer cancel()
302+
303+
resp, err := c.cli.Get(opsCtx, key)
285304
if err != nil {
286305
return nil, err
287306
}
@@ -295,10 +314,17 @@ func (c *Client) Get(ctx context.Context, key string) (interface{}, error) {
295314

296315
// Delete implements kv.Client.
297316
func (c *Client) Delete(ctx context.Context, key string) error {
298-
_, err := c.cli.Delete(ctx, key)
317+
opsCtx, cancel := c.opsContext(ctx)
318+
defer cancel()
319+
320+
_, err := c.cli.Delete(opsCtx, key)
299321
return err
300322
}
301323

302324
func (c *Client) LastUpdateTime(_ string) time.Time {
303325
return time.Now().UTC()
304326
}
327+
328+
func (c *Client) opsContext(parent context.Context) (context.Context, context.CancelFunc) {
329+
return context.WithTimeout(parent, time.Duration(float64(c.cfg.DialTimeout)*float64(c.cfg.MaxRetries)))
330+
}

0 commit comments

Comments
 (0)