mirror of
				https://github.com/grafana/grafana.git
				synced 2025-02-25 18:55:37 -06:00 
			
		
		
		
	Alerting: Fix evaluation timeout (#61303)
This commit is contained in:
		@@ -41,9 +41,13 @@ type ConditionEvaluator interface {
 | 
			
		||||
	Evaluate(ctx context.Context, now time.Time) (Results, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type expressionService interface {
 | 
			
		||||
	ExecutePipeline(ctx context.Context, now time.Time, pipeline expr.DataPipeline) (*backend.QueryDataResponse, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type conditionEvaluator struct {
 | 
			
		||||
	pipeline          expr.DataPipeline
 | 
			
		||||
	expressionService *expr.Service
 | 
			
		||||
	expressionService expressionService
 | 
			
		||||
	condition         models.Condition
 | 
			
		||||
	evalTimeout       time.Duration
 | 
			
		||||
}
 | 
			
		||||
@@ -62,7 +66,7 @@ func (r *conditionEvaluator) EvaluateRaw(ctx context.Context, now time.Time) (re
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	execCtx := ctx
 | 
			
		||||
	if r.evalTimeout <= 0 {
 | 
			
		||||
	if r.evalTimeout >= 0 {
 | 
			
		||||
		timeoutCtx, cancel := context.WithTimeout(ctx, r.evalTimeout)
 | 
			
		||||
		defer cancel()
 | 
			
		||||
		execCtx = timeoutCtx
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/grafana/grafana-plugin-sdk-go/backend"
 | 
			
		||||
	"github.com/grafana/grafana-plugin-sdk-go/data"
 | 
			
		||||
	"github.com/stretchr/testify/require"
 | 
			
		||||
	ptr "github.com/xorcare/pointer"
 | 
			
		||||
@@ -544,3 +545,38 @@ func TestValidate(t *testing.T) {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestEvaluateRaw(t *testing.T) {
 | 
			
		||||
	t.Run("should timeout if request takes too long", func(t *testing.T) {
 | 
			
		||||
		unexpectedResponse := &backend.QueryDataResponse{}
 | 
			
		||||
 | 
			
		||||
		e := conditionEvaluator{
 | 
			
		||||
			pipeline: nil,
 | 
			
		||||
			expressionService: &fakeExpressionService{
 | 
			
		||||
				hook: func(ctx context.Context, now time.Time, pipeline expr.DataPipeline) (*backend.QueryDataResponse, error) {
 | 
			
		||||
					ts := time.Now()
 | 
			
		||||
					for time.Since(ts) <= 10*time.Second {
 | 
			
		||||
						if ctx.Err() != nil {
 | 
			
		||||
							return nil, ctx.Err()
 | 
			
		||||
						}
 | 
			
		||||
						time.Sleep(10 * time.Millisecond)
 | 
			
		||||
					}
 | 
			
		||||
					return unexpectedResponse, nil
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			condition:   models.Condition{},
 | 
			
		||||
			evalTimeout: 10 * time.Millisecond,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_, err := e.EvaluateRaw(context.Background(), time.Now())
 | 
			
		||||
		require.ErrorIs(t, err, context.DeadlineExceeded)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type fakeExpressionService struct {
 | 
			
		||||
	hook func(ctx context.Context, now time.Time, pipeline expr.DataPipeline) (*backend.QueryDataResponse, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f fakeExpressionService) ExecutePipeline(ctx context.Context, now time.Time, pipeline expr.DataPipeline) (*backend.QueryDataResponse, error) {
 | 
			
		||||
	return f.hook(ctx, now, pipeline)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user