diff --git a/cmd/promtool/tsdb.go b/cmd/promtool/tsdb.go index ebde18489c..cc34f70da4 100644 --- a/cmd/promtool/tsdb.go +++ b/cmd/promtool/tsdb.go @@ -433,7 +433,7 @@ func analyzeBlock(ctx context.Context, path, blockID string, limit int, runExten } defer ir.Close() - allLabelNames, err := ir.LabelNames() + allLabelNames, err := ir.LabelNames(ctx) if err != nil { return err } diff --git a/promql/engine_test.go b/promql/engine_test.go index 3c6d30e470..d63e90069b 100644 --- a/promql/engine_test.go +++ b/promql/engine_test.go @@ -202,7 +202,7 @@ func (*errQuerier) LabelValues(string, ...*labels.Matcher) ([]string, storage.Wa return nil, nil, nil } -func (*errQuerier) LabelNames(...*labels.Matcher) ([]string, storage.Warnings, error) { +func (*errQuerier) LabelNames(context.Context, ...*labels.Matcher) ([]string, storage.Warnings, error) { return nil, nil, nil } func (*errQuerier) Close() error { return nil } diff --git a/storage/fanout_test.go b/storage/fanout_test.go index eeae01670f..de21485a3b 100644 --- a/storage/fanout_test.go +++ b/storage/fanout_test.go @@ -237,7 +237,7 @@ func (errQuerier) LabelValues(string, ...*labels.Matcher) ([]string, storage.War return nil, nil, errors.New("label values error") } -func (errQuerier) LabelNames(...*labels.Matcher) ([]string, storage.Warnings, error) { +func (errQuerier) LabelNames(context.Context, ...*labels.Matcher) ([]string, storage.Warnings, error) { return nil, nil, errors.New("label names error") } diff --git a/storage/interface.go b/storage/interface.go index 36e15d4ba1..638aea007d 100644 --- a/storage/interface.go +++ b/storage/interface.go @@ -122,7 +122,7 @@ func (q *MockQuerier) LabelValues(string, ...*labels.Matcher) ([]string, Warning return nil, nil, nil } -func (q *MockQuerier) LabelNames(...*labels.Matcher) ([]string, Warnings, error) { +func (q *MockQuerier) LabelNames(context.Context, ...*labels.Matcher) ([]string, Warnings, error) { return nil, nil, nil } @@ -162,7 +162,7 @@ type LabelQuerier interface { // LabelNames returns all the unique label names present in the block in sorted order. // If matchers are specified the returned result set is reduced // to label names of metrics matching the matchers. - LabelNames(matchers ...*labels.Matcher) ([]string, Warnings, error) + LabelNames(ctx context.Context, matchers ...*labels.Matcher) ([]string, Warnings, error) // Close releases the resources of the Querier. Close() error diff --git a/storage/merge.go b/storage/merge.go index 4e76a99364..a19e8d3a16 100644 --- a/storage/merge.go +++ b/storage/merge.go @@ -218,13 +218,13 @@ func mergeStrings(a, b []string) []string { } // LabelNames returns all the unique label names present in all queriers in sorted order. -func (q *mergeGenericQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, Warnings, error) { +func (q *mergeGenericQuerier) LabelNames(ctx context.Context, matchers ...*labels.Matcher) ([]string, Warnings, error) { var ( labelNamesMap = make(map[string]struct{}) warnings Warnings ) for _, querier := range q.queriers { - names, wrn, err := querier.LabelNames(matchers...) + names, wrn, err := querier.LabelNames(ctx, matchers...) if wrn != nil { // TODO(bwplotka): We could potentially wrap warnings. warnings = append(warnings, wrn...) diff --git a/storage/merge_test.go b/storage/merge_test.go index 3408b16b9c..7afe62a1d6 100644 --- a/storage/merge_test.go +++ b/storage/merge_test.go @@ -1000,7 +1000,7 @@ func (m *mockGenericQuerier) LabelValues(name string, matchers ...*labels.Matche return m.resp, m.warnings, m.err } -func (m *mockGenericQuerier) LabelNames(...*labels.Matcher) ([]string, Warnings, error) { +func (m *mockGenericQuerier) LabelNames(context.Context, ...*labels.Matcher) ([]string, Warnings, error) { m.mtx.Lock() m.labelNamesCalls++ m.mtx.Unlock() @@ -1059,6 +1059,7 @@ func TestMergeGenericQuerierWithSecondaries_ErrorHandling(t *testing.T) { var ( errStorage = errors.New("storage error") warnStorage = errors.New("storage warning") + ctx = context.Background() ) for _, tcase := range []struct { name string @@ -1199,7 +1200,7 @@ func TestMergeGenericQuerierWithSecondaries_ErrorHandling(t *testing.T) { } }) t.Run("LabelNames", func(t *testing.T) { - res, w, err := q.LabelNames() + res, w, err := q.LabelNames(ctx) require.Equal(t, tcase.expectedWarnings[1], w) require.True(t, errors.Is(err, tcase.expectedErrs[1]), "expected error doesn't match") require.Equal(t, tcase.expectedLabels, res) diff --git a/storage/noop.go b/storage/noop.go index 9a7c68ec7d..c5dbffab0b 100644 --- a/storage/noop.go +++ b/storage/noop.go @@ -34,7 +34,7 @@ func (noopQuerier) LabelValues(string, ...*labels.Matcher) ([]string, Warnings, return nil, nil, nil } -func (noopQuerier) LabelNames(...*labels.Matcher) ([]string, Warnings, error) { +func (noopQuerier) LabelNames(context.Context, ...*labels.Matcher) ([]string, Warnings, error) { return nil, nil, nil } @@ -57,7 +57,7 @@ func (noopChunkQuerier) LabelValues(string, ...*labels.Matcher) ([]string, Warni return nil, nil, nil } -func (noopChunkQuerier) LabelNames(...*labels.Matcher) ([]string, Warnings, error) { +func (noopChunkQuerier) LabelNames(context.Context, ...*labels.Matcher) ([]string, Warnings, error) { return nil, nil, nil } diff --git a/storage/remote/read.go b/storage/remote/read.go index c7643b6eac..2976b381a2 100644 --- a/storage/remote/read.go +++ b/storage/remote/read.go @@ -215,7 +215,7 @@ func (q *querier) LabelValues(string, ...*labels.Matcher) ([]string, storage.War } // LabelNames implements storage.Querier and is a noop. -func (q *querier) LabelNames(...*labels.Matcher) ([]string, storage.Warnings, error) { +func (q *querier) LabelNames(context.Context, ...*labels.Matcher) ([]string, storage.Warnings, error) { // TODO: Implement: https://github.com/prometheus/prometheus/issues/3351 return nil, nil, errors.New("not implemented") } diff --git a/storage/secondary.go b/storage/secondary.go index 16740baafe..0b402322a2 100644 --- a/storage/secondary.go +++ b/storage/secondary.go @@ -56,8 +56,8 @@ func (s *secondaryQuerier) LabelValues(name string, matchers ...*labels.Matcher) return vals, w, nil } -func (s *secondaryQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, Warnings, error) { - names, w, err := s.genericQuerier.LabelNames(matchers...) +func (s *secondaryQuerier) LabelNames(ctx context.Context, matchers ...*labels.Matcher) ([]string, Warnings, error) { + names, w, err := s.genericQuerier.LabelNames(ctx, matchers...) if err != nil { return nil, append([]error{err}, w...), nil } diff --git a/tsdb/block.go b/tsdb/block.go index f635b10414..96576dfad3 100644 --- a/tsdb/block.go +++ b/tsdb/block.go @@ -86,7 +86,7 @@ type IndexReader interface { Series(ref storage.SeriesRef, builder *labels.ScratchBuilder, chks *[]chunks.Meta) error // LabelNames returns all the unique label names present in the index in sorted order. - LabelNames(matchers ...*labels.Matcher) ([]string, error) + LabelNames(ctx context.Context, matchers ...*labels.Matcher) ([]string, error) // LabelValueFor returns label value for the given label name in the series referred to by ID. // If the series couldn't be found or the series doesn't have the requested label a @@ -95,7 +95,7 @@ type IndexReader interface { // LabelNamesFor returns all the label names for the series referred to by IDs. // The names returned are sorted. - LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) + LabelNamesFor(ctx context.Context, ids ...storage.SeriesRef) ([]string, error) // Close releases the underlying resources of the reader. Close() error @@ -480,12 +480,12 @@ func (r blockIndexReader) LabelValues(name string, matchers ...*labels.Matcher) return labelValuesWithMatchers(r.ir, name, matchers...) } -func (r blockIndexReader) LabelNames(matchers ...*labels.Matcher) ([]string, error) { +func (r blockIndexReader) LabelNames(ctx context.Context, matchers ...*labels.Matcher) ([]string, error) { if len(matchers) == 0 { - return r.b.LabelNames() + return r.b.LabelNames(ctx) } - return labelNamesWithMatchers(r.ir, matchers...) + return labelNamesWithMatchers(ctx, r.ir, matchers...) } func (r blockIndexReader) Postings(ctx context.Context, name string, values ...string) (index.Postings, error) { @@ -519,8 +519,8 @@ func (r blockIndexReader) LabelValueFor(id storage.SeriesRef, label string) (str // LabelNamesFor returns all the label names for the series referred to by IDs. // The names returned are sorted. -func (r blockIndexReader) LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) { - return r.ir.LabelNamesFor(ids...) +func (r blockIndexReader) LabelNamesFor(ctx context.Context, ids ...storage.SeriesRef) ([]string, error) { + return r.ir.LabelNamesFor(ctx, ids...) } type blockTombstoneReader struct { @@ -686,8 +686,8 @@ func (pb *Block) OverlapsClosedInterval(mint, maxt int64) bool { } // LabelNames returns all the unique label names present in the Block in sorted order. -func (pb *Block) LabelNames() ([]string, error) { - return pb.indexr.LabelNames() +func (pb *Block) LabelNames(ctx context.Context) ([]string, error) { + return pb.indexr.LabelNames(ctx) } func clampInterval(a, b, mint, maxt int64) (int64, int64) { diff --git a/tsdb/block_test.go b/tsdb/block_test.go index 5687637d08..fc1fe719e7 100644 --- a/tsdb/block_test.go +++ b/tsdb/block_test.go @@ -406,6 +406,7 @@ func BenchmarkLabelValuesWithMatchers(b *testing.B) { func TestLabelNamesWithMatchers(t *testing.T) { tmpdir := t.TempDir() + ctx := context.Background() var seriesEntries []storage.Series for i := 0; i < 100; i++ { @@ -471,7 +472,7 @@ func TestLabelNamesWithMatchers(t *testing.T) { for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - actualNames, err := indexReader.LabelNames(tt.matchers...) + actualNames, err := indexReader.LabelNames(ctx, tt.matchers...) require.NoError(t, err) require.Equal(t, tt.expectedNames, actualNames) }) diff --git a/tsdb/db_test.go b/tsdb/db_test.go index 233ad2e909..942ff94a0b 100644 --- a/tsdb/db_test.go +++ b/tsdb/db_test.go @@ -2142,6 +2142,7 @@ func TestNoEmptyBlocks(t *testing.T) { } func TestDB_LabelNames(t *testing.T) { + ctx := context.Background() tests := []struct { // Add 'sampleLabels1' -> Test Head -> Compact -> Test Disk -> // -> Add 'sampleLabels2' -> Test Head+Disk @@ -2185,7 +2186,6 @@ func TestDB_LabelNames(t *testing.T) { // Appends samples into the database. appendSamples := func(db *DB, mint, maxt int64, sampleLabels [][2]string) { t.Helper() - ctx := context.Background() app := db.Appender(ctx) for i := mint; i <= maxt; i++ { for _, tuple := range sampleLabels { @@ -2209,7 +2209,7 @@ func TestDB_LabelNames(t *testing.T) { // Testing head. headIndexr, err := db.head.Index() require.NoError(t, err) - labelNames, err := headIndexr.LabelNames() + labelNames, err := headIndexr.LabelNames(ctx) require.NoError(t, err) require.Equal(t, tst.exp1, labelNames) require.NoError(t, headIndexr.Close()) @@ -2222,21 +2222,21 @@ func TestDB_LabelNames(t *testing.T) { for _, b := range db.Blocks() { blockIndexr, err := b.Index() require.NoError(t, err) - labelNames, err = blockIndexr.LabelNames() + labelNames, err = blockIndexr.LabelNames(ctx) require.NoError(t, err) require.Equal(t, tst.exp1, labelNames) require.NoError(t, blockIndexr.Close()) } // Adding more samples to head with new label names - // so that we can test (head+disk).LabelNames() (the union). + // so that we can test (head+disk).LabelNames(ctx) (the union). appendSamples(db, 5, 9, tst.sampleLabels2) // Testing DB (union). q, err := db.Querier(math.MinInt64, math.MaxInt64) require.NoError(t, err) var ws storage.Warnings - labelNames, ws, err = q.LabelNames() + labelNames, ws, err = q.LabelNames(ctx) require.NoError(t, err) require.Equal(t, 0, len(ws)) require.NoError(t, q.Close()) diff --git a/tsdb/head_read.go b/tsdb/head_read.go index 410f4f0937..dfbe43998e 100644 --- a/tsdb/head_read.go +++ b/tsdb/head_read.go @@ -88,7 +88,7 @@ func (h *headIndexReader) LabelValues(name string, matchers ...*labels.Matcher) // LabelNames returns all the unique label names present in the head // that are within the time range mint to maxt. -func (h *headIndexReader) LabelNames(matchers ...*labels.Matcher) ([]string, error) { +func (h *headIndexReader) LabelNames(ctx context.Context, matchers ...*labels.Matcher) ([]string, error) { if h.maxt < h.head.MinTime() || h.mint > h.head.MaxTime() { return []string{}, nil } @@ -99,7 +99,7 @@ func (h *headIndexReader) LabelNames(matchers ...*labels.Matcher) ([]string, err return labelNames, nil } - return labelNamesWithMatchers(h, matchers...) + return labelNamesWithMatchers(ctx, h, matchers...) } // Postings returns the postings list iterator for the label pairs. @@ -232,9 +232,12 @@ func (h *headIndexReader) LabelValueFor(id storage.SeriesRef, label string) (str // LabelNamesFor returns all the label names for the series referred to by IDs. // The names returned are sorted. -func (h *headIndexReader) LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) { +func (h *headIndexReader) LabelNamesFor(ctx context.Context, ids ...storage.SeriesRef) ([]string, error) { namesMap := make(map[string]struct{}) for _, id := range ids { + if ctx.Err() != nil { + return nil, ctx.Err() + } memSeries := h.head.series.getByID(chunks.HeadSeriesRef(id)) if memSeries == nil { return nil, storage.ErrNotFound diff --git a/tsdb/head_test.go b/tsdb/head_test.go index 69eb622d18..5e0857d1c0 100644 --- a/tsdb/head_test.go +++ b/tsdb/head_test.go @@ -2637,6 +2637,7 @@ func TestHeadLabelNamesValuesWithMinMaxRange(t *testing.T) { } expectedLabelNames = []string{"a", "b", "c"} expectedLabelValues = []string{"d", "e", "f"} + ctx = context.Background() ) app := head.Appender(context.Background()) @@ -2664,7 +2665,7 @@ func TestHeadLabelNamesValuesWithMinMaxRange(t *testing.T) { for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { headIdxReader := head.indexRange(tt.mint, tt.maxt) - actualLabelNames, err := headIdxReader.LabelNames() + actualLabelNames, err := headIdxReader.LabelNames(ctx) require.NoError(t, err) require.Equal(t, tt.expectedNames, actualLabelNames) if len(tt.expectedValues) > 0 { @@ -2798,7 +2799,7 @@ func TestHeadLabelNamesWithMatchers(t *testing.T) { t.Run(tt.name, func(t *testing.T) { headIdxReader := head.indexRange(0, 200) - actualNames, err := headIdxReader.LabelNames(tt.matchers...) + actualNames, err := headIdxReader.LabelNames(context.Background(), tt.matchers...) require.NoError(t, err) require.Equal(t, tt.expectedNames, actualNames) }) diff --git a/tsdb/index/index.go b/tsdb/index/index.go index 3f19de7dc0..1603c38be0 100644 --- a/tsdb/index/index.go +++ b/tsdb/index/index.go @@ -923,7 +923,7 @@ func (w *Writer) writePostingsToTmpFiles() error { // Symbol numbers are in order, so the strings will also be in order. slices.Sort(values) for _, v := range values { - value, err := w.symbols.Lookup(v) + value, err := w.symbols.Lookup(w.ctx, v) if err != nil { return err } @@ -1295,7 +1295,7 @@ func NewSymbols(bs ByteSlice, version, off int) (*Symbols, error) { return s, nil } -func (s Symbols) Lookup(o uint32) (string, error) { +func (s Symbols) Lookup(ctx context.Context, o uint32) (string, error) { d := encoding.Decbuf{ B: s.bs.Range(0, s.bs.Len()), } @@ -1307,6 +1307,9 @@ func (s Symbols) Lookup(o uint32) (string, error) { d.Skip(s.offsets[int(o/symbolFactor)]) // Walk until we find the one we want. for i := o - (o / symbolFactor * symbolFactor); i > 0; i-- { + if ctx.Err() != nil { + return "", ctx.Err() + } d.UvarintBytes() } } else { @@ -1434,11 +1437,11 @@ func (r *Reader) Close() error { return r.c.Close() } -func (r *Reader) lookupSymbol(o uint32) (string, error) { +func (r *Reader) lookupSymbol(ctx context.Context, o uint32) (string, error) { if s, ok := r.nameSymbols[o]; ok { return s, nil } - return r.symbols.Lookup(o) + return r.symbols.Lookup(ctx, o) } // Symbols returns an iterator over the symbols that exist within the index. @@ -1523,10 +1526,14 @@ func (r *Reader) LabelValues(name string, matchers ...*labels.Matcher) ([]string // LabelNamesFor returns all the label names for the series referred to by IDs. // The names returned are sorted. -func (r *Reader) LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) { +func (r *Reader) LabelNamesFor(ctx context.Context, ids ...storage.SeriesRef) ([]string, error) { // Gather offsetsMap the name offsetsMap in the symbol table first offsetsMap := make(map[uint32]struct{}) for _, id := range ids { + if ctx.Err() != nil { + return nil, ctx.Err() + } + offset := id // In version 2 series IDs are no longer exact references but series are 16-byte padded // and the ID is the multiple of 16 of the actual position. @@ -1552,7 +1559,7 @@ func (r *Reader) LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) { // Lookup the unique symbols. names := make([]string, 0, len(offsetsMap)) for off := range offsetsMap { - name, err := r.lookupSymbol(off) + name, err := r.lookupSymbol(ctx, off) if err != nil { return nil, errors.Wrap(err, "lookup symbol in LabelNamesFor") } @@ -1722,7 +1729,7 @@ func (r *Reader) Size() int64 { // LabelNames returns all the unique label names present in the index. // TODO(twilkie) implement support for matchers -func (r *Reader) LabelNames(matchers ...*labels.Matcher) ([]string, error) { +func (r *Reader) LabelNames(_ context.Context, matchers ...*labels.Matcher) ([]string, error) { if len(matchers) > 0 { return nil, errors.Errorf("matchers parameter is not implemented: %+v", matchers) } @@ -1766,7 +1773,7 @@ func (s stringListIter) Err() error { return nil } // It currently does not contain decoding methods for all entry types but can be extended // by them if there's demand. type Decoder struct { - LookupSymbol func(uint32) (string, error) + LookupSymbol func(context.Context, uint32) (string, error) } // Postings returns a postings list for b and its number of elements. @@ -1815,13 +1822,13 @@ func (dec *Decoder) LabelValueFor(b []byte, label string) (string, error) { return "", errors.Wrap(d.Err(), "read series label offsets") } - ln, err := dec.LookupSymbol(lno) + ln, err := dec.LookupSymbol(context.TODO(), lno) if err != nil { return "", errors.Wrap(err, "lookup label name") } if ln == label { - lv, err := dec.LookupSymbol(lvo) + lv, err := dec.LookupSymbol(context.TODO(), lvo) if err != nil { return "", errors.Wrap(err, "lookup label value") } @@ -1851,11 +1858,11 @@ func (dec *Decoder) Series(b []byte, builder *labels.ScratchBuilder, chks *[]chu return errors.Wrap(d.Err(), "read series label offsets") } - ln, err := dec.LookupSymbol(lno) + ln, err := dec.LookupSymbol(context.TODO(), lno) if err != nil { return errors.Wrap(err, "lookup label name") } - lv, err := dec.LookupSymbol(lvo) + lv, err := dec.LookupSymbol(context.TODO(), lvo) if err != nil { return errors.Wrap(err, "lookup label value") } diff --git a/tsdb/index/index_test.go b/tsdb/index/index_test.go index cca7e48ef5..e244e9c2f3 100644 --- a/tsdb/index/index_test.go +++ b/tsdb/index/index_test.go @@ -229,7 +229,7 @@ func TestIndexRW_Postings(t *testing.T) { d := encoding.NewDecbufAt(ir.b, int(off), castagnoliTable) require.Equal(t, 1, d.Be32int(), "Unexpected number of label indices table names") for i := d.Be32(); i > 0 && d.Err() == nil; i-- { - v, err := ir.lookupSymbol(d.Be32()) + v, err := ir.lookupSymbol(ctx, d.Be32()) require.NoError(t, err) labelIndices[lbl] = append(labelIndices[lbl], v) } @@ -519,6 +519,7 @@ func TestNewFileReaderErrorNoOpenFiles(t *testing.T) { } func TestSymbols(t *testing.T) { + ctx := context.Background() buf := encoding.Encbuf{} // Add prefix to the buffer to simulate symbols as part of larger buffer. @@ -541,11 +542,11 @@ func TestSymbols(t *testing.T) { require.Equal(t, 32, s.Size()) for i := 99; i >= 0; i-- { - s, err := s.Lookup(uint32(i)) + s, err := s.Lookup(ctx, uint32(i)) require.NoError(t, err) require.Equal(t, string(rune(i)), s) } - _, err = s.Lookup(100) + _, err = s.Lookup(ctx, 100) require.Error(t, err) for i := 99; i >= 0; i-- { diff --git a/tsdb/ooo_head_read.go b/tsdb/ooo_head_read.go index c99029d1eb..9eb99e5fdb 100644 --- a/tsdb/ooo_head_read.go +++ b/tsdb/ooo_head_read.go @@ -426,7 +426,7 @@ func (ir *OOOCompactionHeadIndexReader) PostingsForMatchers(concurrent bool, ms return nil, errors.New("not implemented") } -func (ir *OOOCompactionHeadIndexReader) LabelNames(matchers ...*labels.Matcher) ([]string, error) { +func (ir *OOOCompactionHeadIndexReader) LabelNames(context.Context, ...*labels.Matcher) ([]string, error) { return nil, errors.New("not implemented") } @@ -434,7 +434,7 @@ func (ir *OOOCompactionHeadIndexReader) LabelValueFor(id storage.SeriesRef, labe return "", errors.New("not implemented") } -func (ir *OOOCompactionHeadIndexReader) LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) { +func (ir *OOOCompactionHeadIndexReader) LabelNamesFor(ctx context.Context, ids ...storage.SeriesRef) ([]string, error) { return nil, errors.New("not implemented") } diff --git a/tsdb/querier.go b/tsdb/querier.go index 836647d235..a6bb9cd99a 100644 --- a/tsdb/querier.go +++ b/tsdb/querier.go @@ -94,8 +94,8 @@ func (q *blockBaseQuerier) LabelValues(name string, matchers ...*labels.Matcher) return res, nil, err } -func (q *blockBaseQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { - res, err := q.index.LabelNames(matchers...) +func (q *blockBaseQuerier) LabelNames(ctx context.Context, matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { + res, err := q.index.LabelNames(ctx, matchers...) return res, nil, err } @@ -481,7 +481,7 @@ func labelValuesWithMatchers(r IndexReader, name string, matchers ...*labels.Mat return values, nil } -func labelNamesWithMatchers(r IndexReader, matchers ...*labels.Matcher) ([]string, error) { +func labelNamesWithMatchers(ctx context.Context, r IndexReader, matchers ...*labels.Matcher) ([]string, error) { p, err := PostingsForMatchers(r, matchers...) if err != nil { return nil, err @@ -495,7 +495,7 @@ func labelNamesWithMatchers(r IndexReader, matchers ...*labels.Matcher) ([]strin return nil, errors.Wrapf(p.Err(), "postings for label names with matchers") } - return r.LabelNamesFor(postings...) + return r.LabelNamesFor(ctx, postings...) } // seriesData, used inside other iterators, are updated when we move from one series to another. diff --git a/tsdb/querier_test.go b/tsdb/querier_test.go index ffac2bf3bb..3c3c47e4d9 100644 --- a/tsdb/querier_test.go +++ b/tsdb/querier_test.go @@ -1487,7 +1487,7 @@ func (m mockIndex) LabelValueFor(id storage.SeriesRef, label string) (string, er return m.series[id].l.Get(label), nil } -func (m mockIndex) LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) { +func (m mockIndex) LabelNamesFor(ctx context.Context, ids ...storage.SeriesRef) ([]string, error) { namesMap := make(map[string]bool) for _, id := range ids { m.series[id].l.Range(func(lbl labels.Label) { @@ -1533,7 +1533,7 @@ func (m mockIndex) Series(ref storage.SeriesRef, builder *labels.ScratchBuilder, return nil } -func (m mockIndex) LabelNames(matchers ...*labels.Matcher) ([]string, error) { +func (m mockIndex) LabelNames(_ context.Context, matchers ...*labels.Matcher) ([]string, error) { names := map[string]struct{}{} if len(matchers) == 0 { for l := range m.postings { @@ -2449,7 +2449,7 @@ func (m mockMatcherIndex) LabelValueFor(id storage.SeriesRef, label string) (str return "", errors.New("label value for called") } -func (m mockMatcherIndex) LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) { +func (m mockMatcherIndex) LabelNamesFor(ctx context.Context, ids ...storage.SeriesRef) ([]string, error) { return nil, errors.New("label names for for called") } @@ -2465,7 +2465,7 @@ func (m mockMatcherIndex) Series(ref storage.SeriesRef, builder *labels.ScratchB return nil } -func (m mockMatcherIndex) LabelNames(...*labels.Matcher) ([]string, error) { +func (m mockMatcherIndex) LabelNames(context.Context, ...*labels.Matcher) ([]string, error) { return []string{}, nil } diff --git a/web/api/v1/api.go b/web/api/v1/api.go index cd9ba5b89a..d95eb7488e 100644 --- a/web/api/v1/api.go +++ b/web/api/v1/api.go @@ -673,7 +673,7 @@ func (api *API) labelNames(r *http.Request) apiFuncResult { labelNamesSet := make(map[string]struct{}) for _, matchers := range matcherSets { - vals, callWarnings, err := q.LabelNames(matchers...) + vals, callWarnings, err := q.LabelNames(r.Context(), matchers...) if err != nil { return apiFuncResult{nil, returnAPIError(err), warnings, nil} } @@ -691,7 +691,7 @@ func (api *API) labelNames(r *http.Request) apiFuncResult { } slices.Sort(names) } else { - names, warnings, err = q.LabelNames() + names, warnings, err = q.LabelNames(r.Context()) if err != nil { return apiFuncResult{nil, &apiError{errorExec, err}, warnings, nil} } diff --git a/web/api/v1/errors_test.go b/web/api/v1/errors_test.go index 6bafc4caad..1d60679af2 100644 --- a/web/api/v1/errors_test.go +++ b/web/api/v1/errors_test.go @@ -174,7 +174,7 @@ func (t errorTestQuerier) LabelValues(name string, matchers ...*labels.Matcher) return nil, nil, t.err } -func (t errorTestQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) { +func (t errorTestQuerier) LabelNames(context.Context, ...*labels.Matcher) ([]string, storage.Warnings, error) { return nil, nil, t.err }