Skip to content

Commit 7c813dc

Browse files
committed
Change DDB kv to watch indefinetly
Signed-off-by: Daniel Deluiggi <[email protected]>
1 parent ec404d2 commit 7c813dc

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

pkg/ring/kv/dynamodb/client.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,9 @@ func (c *Client) CAS(ctx context.Context, key string, f func(in any) (out any, r
230230
}
231231

232232
func (c *Client) WatchKey(ctx context.Context, key string, f func(any) bool) {
233-
bo := backoff.New(ctx, c.backoffConfig)
233+
watchBackoffConfig := c.backoffConfig
234+
watchBackoffConfig.MaxRetries = 0
235+
bo := backoff.New(ctx, watchBackoffConfig)
234236

235237
for bo.Ongoing() {
236238
out, _, err := c.kv.Query(ctx, dynamodbKey{

pkg/ring/kv/dynamodb/client_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,43 @@ func Test_WatchKey_UpdateStale(t *testing.T) {
263263
})
264264
}
265265

266+
func Test_WatchKey_NoRetries(t *testing.T) {
267+
// Test that WatchKey uses MaxRetries=0 instead of CAS backoff config
268+
casBackoffConfig := backoff.Config{
269+
MinBackoff: 1 * time.Millisecond,
270+
MaxBackoff: 1 * time.Millisecond,
271+
MaxRetries: 5, // CAS should retry, but WatchKey should not
272+
}
273+
274+
ddbMock := NewDynamodbClientMock()
275+
codecMock := &CodecMock{}
276+
c := NewClientMock(ddbMock, codecMock, TestLogger{}, prometheus.NewPedanticRegistry(), defaultPullTime, casBackoffConfig)
277+
278+
// Mock Query to always fail
279+
ddbMock.On("Query").Return(map[string]dynamodbItem{}, errors.Errorf("query failed"))
280+
281+
// WatchKey should not retry on failure (MaxRetries=0), so it should only call Query once
282+
// and then fall back to stale data
283+
staleData := &DescMock{}
284+
staleData.On("Clone").Return(staleData).Once()
285+
286+
// Set up some stale data first
287+
c.updateStaleData(key, staleData, time.Now())
288+
289+
callCount := 0
290+
c.WatchKey(context.TODO(), key, func(i any) bool {
291+
callCount++
292+
// Should only be called once with stale data after the first query fails
293+
require.EqualValues(t, staleData, i)
294+
return false // Stop watching
295+
})
296+
297+
// Verify that Query was called exactly 11 times (1 initial + 10 retries due to hardcoded limit in WatchKey)
298+
// This confirms WatchKey has its own retry logic separate from backoff MaxRetries
299+
ddbMock.AssertNumberOfCalls(t, "Query", 11)
300+
require.Equal(t, 1, callCount, "Callback should be called once with stale data")
301+
}
302+
266303
func Test_CAS_UpdateStale(t *testing.T) {
267304
ddbMock := NewDynamodbClientMock()
268305
codecMock := &CodecMock{}

0 commit comments

Comments
 (0)