func (ng *Engine) exec(ctx context.Context, q *query) (Value, storage.Warnings, error) {
	ng.metrics.currentQueries.Inc()
	defer ng.metrics.currentQueries.Dec()

	ctx, cancel := context.WithTimeout(ctx, ng.timeout)
	q.cancel = cancel

	execSpanTimer, ctx := q.stats.GetSpanTimer(ctx, stats.ExecTotalTime)
	defer execSpanTimer.Finish()

	queueSpanTimer, _ := q.stats.GetSpanTimer(ctx, stats.ExecQueueTime, ng.metrics.queryQueueTime)

	if err := ng.gate.Start(ctx); err != nil {
		return nil, nil, contextErr(err, "query queue")
	}
	defer ng.gate.Done()

	queueSpanTimer.Finish()

	// Cancel when execution is done or an error was raised.
	defer q.cancel()

	const env = "query execution"

	evalSpanTimer, ctx := q.stats.GetSpanTimer(ctx, stats.EvalTotalTime)
	defer evalSpanTimer.Finish()

	// The base context might already be canceled on the first iteration (e.g. during shutdown).
	if err := contextDone(ctx, env); err != nil {
		return nil, nil, err
	}

	switch s := q.Statement().(type) {
	case *EvalStmt:
		return ng.execEvalStmt(ctx, q, s)
	case testStmt:
		return nil, nil, s(ctx)
	}

	panic(errors.Errorf("promql.Engine.exec: unhandled statement of type %T", q.Statement()))
}
func (ng *Engine) exec(ctx context.Context, q *query) (Value, storage.Warnings, error) {
	ng.metrics.currentQueries.Inc()
	defer ng.metrics.currentQueries.Dec()

	ctx, cancel := context.WithTimeout(ctx, ng.timeout)
	q.cancel = cancel

	execSpanTimer, ctx := q.stats.GetSpanTimer(ctx, stats.ExecTotalTime)
	defer execSpanTimer.Finish()

	queueSpanTimer, _ := q.stats.GetSpanTimer(ctx, stats.ExecQueueTime, ng.metrics.queryQueueTime)

	if err := ng.gate.Start(ctx); err != nil {
		return nil, nil, contextErr(err, "query queue")
	}
	defer ng.gate.Done()

	queueSpanTimer.Finish()

	
	defer q.cancel()

	const env = "query execution"

	evalSpanTimer, ctx := q.stats.GetSpanTimer(ctx, stats.EvalTotalTime)
	defer evalSpanTimer.Finish()

	
	if err := contextDone(ctx, env); err != nil {
		return nil, nil, err
	}

	switch s := q.Statement().(type) {
	case *EvalStmt:
		return ng.execEvalStmt(ctx, q, s)
	case testStmt:
		return nil, nil, s(ctx)
	}

	panic(errors.Errorf("promql.Engine.exec: unhandled statement of type %T", q.Statement()))
}
func ( ng * Engine ) exec ( ctx context . Context , q * query ) ( Value , storage . Warnings , error ) { ng . metrics . currentQueries . Inc ( ) defer ng . metrics . currentQueries . Dec ( ) ctx , cancel := context . WithTimeout ( ctx , ng . timeout ) q . cancel = cancel execSpanTimer , ctx := q . stats . GetSpanTimer ( ctx , stats . ExecTotalTime ) defer execSpanTimer . Finish ( ) queueSpanTimer , _ := q . stats . GetSpanTimer ( ctx , stats . ExecQueueTime , ng . metrics . queryQueueTime ) if err := ng . gate . Start ( ctx ) ; err != nil { return nil , nil , contextErr ( err , " " ) } defer ng . gate . Done ( ) queueSpanTimer . Finish ( ) // Cancel when execution is done or an error was raised. defer q . cancel ( ) const env = " " evalSpanTimer , ctx := q . stats . GetSpanTimer ( ctx , stats . EvalTotalTime ) defer evalSpanTimer . Finish ( ) // The base context might already be canceled on the first iteration (e.g. during shutdown). if err := contextDone ( ctx , env ) ; err != nil { return nil , nil , err } switch s := q . Statement ( ) . ( type ) { case * EvalStmt : return ng . execEvalStmt ( ctx , q , s ) case testStmt : return nil , nil , s ( ctx ) } panic ( errors . Errorf ( " " , q . Statement ( ) ) ) }
// exec executes the query.
//
// At this point per query only one EvalStmt is evaluated. Alert and record
// statements are not handled by the Engine.
exec executes the query . At this point per query only one EvalStmt is evaluated . Alert and record statements are not handled by the Engine .