The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/screenshot/ratelimit.go

46 lines
1.4 KiB

package screenshot
import (
"context"
)
// A rate limiter restricts the number of screenshots that can be taken in parallel.
//
//go:generate mockgen -destination=ratelimit_mock.go -package=screenshot github.com/grafana/grafana/pkg/services/screenshot RateLimiter
type RateLimiter interface {
// Do restricts the rate at which screenshots can be taken in parallel via screenshotFunc.
// It returns the result of screenshotFunc, or an error if either the context deadline
// has been exceeded or the context has been canceled while waiting its turn to call
// screenshotFunc.
Do(ctx context.Context, opts ScreenshotOptions, fn screenshotFunc) (*Screenshot, error)
}
// TokenRateLimiter is a rate limiter that uses a token bucket of fixed size N.
type TokenRateLimiter struct {
tokens chan struct{}
}
func NewTokenRateLimiter(n int64) RateLimiter {
return &TokenRateLimiter{
tokens: make(chan struct{}, n),
}
}
func (s *TokenRateLimiter) Do(ctx context.Context, opts ScreenshotOptions, fn screenshotFunc) (*Screenshot, error) {
select {
// the context is canceled
case <-ctx.Done():
return nil, ctx.Err()
// there is a token available
case s.tokens <- struct{}{}:
defer func() { <-s.tokens }()
return fn(ctx, opts)
}
}
// NoOpRateLimiter is a no-op rate limiter that has no limits.
type NoOpRateLimiter struct{}
func (b *NoOpRateLimiter) Do(ctx context.Context, opts ScreenshotOptions, fn screenshotFunc) (*Screenshot, error) {
return fn(ctx, opts)
}