Skip to content

Commit 2342f8d

Browse files
committed
Handle not found metas gracefully
There is a time window between between listing metas and fetching them from object storage which could lead to a race condition that the meta is not found in object storage, because it was deleted and superseded by a newer meta. This can happen when querying recent bloom data, that is still subject to updates. Signed-off-by: Christian Haudum <[email protected]>
1 parent 48bbf98 commit 2342f8d

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

pkg/storage/stores/shipper/bloomshipper/client.go

+11-8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"time"
1313

1414
"github.com/go-kit/log"
15+
"github.com/go-kit/log/level"
1516
"github.com/grafana/dskit/concurrency"
1617
"github.com/pkg/errors"
1718
"github.com/prometheus/common/model"
@@ -385,31 +386,33 @@ func (b *BloomClient) Stop() {
385386

386387
func (b *BloomClient) GetMetas(ctx context.Context, refs []MetaRef) ([]Meta, error) {
387388
results := make([]Meta, len(refs))
388-
err := concurrency.ForEachJob(ctx, len(refs), b.concurrency, func(ctx context.Context, idx int) error {
389+
_ = concurrency.ForEachJob(ctx, len(refs), b.concurrency, func(ctx context.Context, idx int) error {
389390
meta, err := b.GetMeta(ctx, refs[idx])
390391
if err != nil {
391-
return err
392+
level.Error(b.logger).Log("msg", "failed to get meta", "err", err)
392393
}
393394
results[idx] = meta
394395
return nil
395396
})
396-
return results, err
397+
return results, nil
397398
}
398399

400+
// GetMeta fetches the meta file for given MetaRef from object storage and
401+
// decodes the JSON data into a Meta.
402+
// If the meta file is not found in storage or decoding fails, the empty Meta
403+
// is returned along with the error.
399404
func (b *BloomClient) GetMeta(ctx context.Context, ref MetaRef) (Meta, error) {
400-
meta := Meta{
401-
MetaRef: ref,
402-
}
405+
meta := Meta{MetaRef: ref}
403406
key := b.KeyResolver.Meta(ref).Addr()
404407
reader, _, err := b.client.GetObject(ctx, key)
405408
if err != nil {
406-
return Meta{}, fmt.Errorf("failed to get meta file%s: %w", key, err)
409+
return meta, fmt.Errorf("failed to fetch meta file %s: %w", key, err)
407410
}
408411
defer reader.Close()
409412

410413
err = json.NewDecoder(reader).Decode(&meta)
411414
if err != nil {
412-
return Meta{}, fmt.Errorf("failed to decode meta file %s: %w", key, err)
415+
return meta, fmt.Errorf("failed to decode meta file %s: %w", key, err)
413416
}
414417
return meta, nil
415418
}

pkg/storage/stores/shipper/bloomshipper/client_test.go

+14-5
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,20 @@ func TestBloomClient_GetMetas(t *testing.T) {
107107
require.Equal(t, metas, []Meta{m1, m2})
108108
})
109109

110-
t.Run("does not exist", func(t *testing.T) {
111-
metas, err := c.GetMetas(ctx, []MetaRef{{}})
112-
require.Error(t, err)
113-
require.True(t, c.client.IsObjectNotFoundErr(err))
114-
require.Equal(t, metas, []Meta{{}})
110+
t.Run("does not exist - yields empty meta", func(t *testing.T) {
111+
ref := MetaRef{
112+
Ref: Ref{
113+
TenantID: "tenant",
114+
TableName: "table",
115+
Bounds: v1.FingerprintBounds{},
116+
StartTimestamp: 1000,
117+
EndTimestamp: 2000,
118+
Checksum: 1234,
119+
},
120+
}
121+
metas, err := c.GetMetas(ctx, []MetaRef{ref})
122+
require.NoError(t, err)
123+
require.Equal(t, metas, []Meta{{MetaRef: ref}})
115124
})
116125
}
117126

0 commit comments

Comments
 (0)