|
|
|
@ -218,20 +218,25 @@ func contextDone(ctx context.Context, env string) error {
|
|
|
|
|
// Engine handles the lifetime of queries from beginning to end.
|
|
|
|
|
// It is connected to a querier.
|
|
|
|
|
type Engine struct {
|
|
|
|
|
// The querier on which the engine operates.
|
|
|
|
|
querier local.Querier
|
|
|
|
|
// A Querier constructor against an underlying storage.
|
|
|
|
|
queryable Queryable
|
|
|
|
|
// The gate limiting the maximum number of concurrent and waiting queries.
|
|
|
|
|
gate *queryGate
|
|
|
|
|
options *EngineOptions
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Queryable allows opening a storage querier.
|
|
|
|
|
type Queryable interface {
|
|
|
|
|
Querier() (local.Querier, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewEngine returns a new engine.
|
|
|
|
|
func NewEngine(querier local.Querier, o *EngineOptions) *Engine {
|
|
|
|
|
func NewEngine(queryable Queryable, o *EngineOptions) *Engine {
|
|
|
|
|
if o == nil {
|
|
|
|
|
o = DefaultEngineOptions
|
|
|
|
|
}
|
|
|
|
|
return &Engine{
|
|
|
|
|
querier: querier,
|
|
|
|
|
queryable: queryable,
|
|
|
|
|
gate: newQueryGate(o.MaxConcurrentQueries),
|
|
|
|
|
options: o,
|
|
|
|
|
}
|
|
|
|
@ -351,13 +356,18 @@ func (ng *Engine) exec(ctx context.Context, q *query) (model.Value, error) {
|
|
|
|
|
|
|
|
|
|
// execEvalStmt evaluates the expression of an evaluation statement for the given time range.
|
|
|
|
|
func (ng *Engine) execEvalStmt(ctx context.Context, query *query, s *EvalStmt) (model.Value, error) {
|
|
|
|
|
querier, err := ng.queryable.Querier()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer querier.Close()
|
|
|
|
|
|
|
|
|
|
prepareTimer := query.stats.GetTimer(stats.QueryPreparationTime).Start()
|
|
|
|
|
err := ng.populateIterators(ctx, s)
|
|
|
|
|
err = ng.populateIterators(ctx, querier, s)
|
|
|
|
|
prepareTimer.Stop()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defer ng.closeIterators(s)
|
|
|
|
|
|
|
|
|
|
evalTimer := query.stats.GetTimer(stats.InnerEvalTime).Start()
|
|
|
|
@ -463,20 +473,20 @@ func (ng *Engine) execEvalStmt(ctx context.Context, query *query, s *EvalStmt) (
|
|
|
|
|
return resMatrix, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ng *Engine) populateIterators(ctx context.Context, s *EvalStmt) error {
|
|
|
|
|
func (ng *Engine) populateIterators(ctx context.Context, querier local.Querier, s *EvalStmt) error {
|
|
|
|
|
var queryErr error
|
|
|
|
|
Inspect(s.Expr, func(node Node) bool {
|
|
|
|
|
switch n := node.(type) {
|
|
|
|
|
case *VectorSelector:
|
|
|
|
|
if s.Start.Equal(s.End) {
|
|
|
|
|
n.iterators, queryErr = ng.querier.QueryInstant(
|
|
|
|
|
n.iterators, queryErr = querier.QueryInstant(
|
|
|
|
|
ctx,
|
|
|
|
|
s.Start.Add(-n.Offset),
|
|
|
|
|
StalenessDelta,
|
|
|
|
|
n.LabelMatchers...,
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
n.iterators, queryErr = ng.querier.QueryRange(
|
|
|
|
|
n.iterators, queryErr = querier.QueryRange(
|
|
|
|
|
ctx,
|
|
|
|
|
s.Start.Add(-n.Offset-StalenessDelta),
|
|
|
|
|
s.End.Add(-n.Offset),
|
|
|
|
@ -487,7 +497,7 @@ func (ng *Engine) populateIterators(ctx context.Context, s *EvalStmt) error {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
case *MatrixSelector:
|
|
|
|
|
n.iterators, queryErr = ng.querier.QueryRange(
|
|
|
|
|
n.iterators, queryErr = querier.QueryRange(
|
|
|
|
|
ctx,
|
|
|
|
|
s.Start.Add(-n.Offset-n.Range),
|
|
|
|
|
s.End.Add(-n.Offset),
|
|
|
|
|