github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/querier/lazyquery/lazyquery.go (about)

     1  package lazyquery
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/prometheus/common/model"
     8  	"github.com/prometheus/prometheus/pkg/labels"
     9  	"github.com/prometheus/prometheus/storage"
    10  
    11  	"github.com/cortexproject/cortex/pkg/chunk"
    12  	"github.com/cortexproject/cortex/pkg/querier/chunkstore"
    13  )
    14  
    15  // LazyQueryable wraps a storage.Queryable
    16  type LazyQueryable struct {
    17  	q storage.Queryable
    18  }
    19  
    20  // Querier implements storage.Queryable
    21  func (lq LazyQueryable) Querier(ctx context.Context, mint, maxt int64) (storage.Querier, error) {
    22  	q, err := lq.q.Querier(ctx, mint, maxt)
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  
    27  	return NewLazyQuerier(q), nil
    28  }
    29  
    30  // NewLazyQueryable returns a lazily wrapped queryable
    31  func NewLazyQueryable(q storage.Queryable) storage.Queryable {
    32  	return LazyQueryable{q}
    33  }
    34  
    35  // LazyQuerier is a lazy-loaded adapter for a storage.Querier
    36  type LazyQuerier struct {
    37  	next storage.Querier
    38  }
    39  
    40  // NewLazyQuerier wraps a storage.Querier, does the Select in the background.
    41  // Return value cannot be used from more than one goroutine simultaneously.
    42  func NewLazyQuerier(next storage.Querier) storage.Querier {
    43  	return LazyQuerier{next}
    44  }
    45  
    46  // Select implements Storage.Querier
    47  func (l LazyQuerier) Select(selectSorted bool, params *storage.SelectHints, matchers ...*labels.Matcher) storage.SeriesSet {
    48  	// make sure there is space in the buffer, to unblock the goroutine and let it die even if nobody is
    49  	// waiting for the result yet (or anymore).
    50  	future := make(chan storage.SeriesSet, 1)
    51  	go func() {
    52  		future <- l.next.Select(selectSorted, params, matchers...)
    53  	}()
    54  
    55  	return &lazySeriesSet{
    56  		future: future,
    57  	}
    58  }
    59  
    60  // LabelValues implements Storage.Querier
    61  func (l LazyQuerier) LabelValues(name string, matchers ...*labels.Matcher) ([]string, storage.Warnings, error) {
    62  	return l.next.LabelValues(name, matchers...)
    63  }
    64  
    65  // LabelNames implements Storage.Querier
    66  func (l LazyQuerier) LabelNames(matchers ...*labels.Matcher) ([]string, storage.Warnings, error) {
    67  	return l.next.LabelNames(matchers...)
    68  }
    69  
    70  // Close implements Storage.Querier
    71  func (l LazyQuerier) Close() error {
    72  	return l.next.Close()
    73  }
    74  
    75  // Get implements chunk.Store for the chunk tar HTTP handler.
    76  func (l LazyQuerier) Get(ctx context.Context, userID string, from, through model.Time, matchers ...*labels.Matcher) ([]chunk.Chunk, error) {
    77  	store, ok := l.next.(chunkstore.ChunkStore)
    78  	if !ok {
    79  		return nil, fmt.Errorf("not supported")
    80  	}
    81  
    82  	return store.Get(ctx, userID, from, through, matchers...)
    83  }
    84  
    85  type lazySeriesSet struct {
    86  	next   storage.SeriesSet
    87  	future chan storage.SeriesSet
    88  }
    89  
    90  // Next implements storage.SeriesSet.  NB not thread safe!
    91  func (s *lazySeriesSet) Next() bool {
    92  	if s.next == nil {
    93  		s.next = <-s.future
    94  	}
    95  	return s.next.Next()
    96  }
    97  
    98  // At implements storage.SeriesSet.
    99  func (s *lazySeriesSet) At() storage.Series {
   100  	if s.next == nil {
   101  		s.next = <-s.future
   102  	}
   103  	return s.next.At()
   104  }
   105  
   106  // Err implements storage.SeriesSet.
   107  func (s *lazySeriesSet) Err() error {
   108  	if s.next == nil {
   109  		s.next = <-s.future
   110  	}
   111  	return s.next.Err()
   112  }
   113  
   114  // Warnings implements storage.SeriesSet.
   115  func (s *lazySeriesSet) Warnings() storage.Warnings {
   116  	return nil
   117  }