mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 02:40:26 -06:00
47 lines
1.4 KiB
Go
47 lines
1.4 KiB
Go
|
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)
|
||
|
}
|