...
1
16
17 package grpc
18
19 import (
20 "context"
21
22 gotimerate "golang.org/x/time/rate"
23 "k8s.io/klog/v2"
24
25 "google.golang.org/grpc"
26 "google.golang.org/grpc/codes"
27 "google.golang.org/grpc/status"
28 )
29
30 var (
31 ErrorLimitExceeded = status.Error(codes.ResourceExhausted, "rejected by rate limit")
32 )
33
34
35
36 type Limiter interface {
37
38 Allow() bool
39 }
40
41
42 func LimiterUnaryServerInterceptor(limiter Limiter) grpc.UnaryServerInterceptor {
43 return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
44 if !limiter.Allow() {
45 return nil, ErrorLimitExceeded
46 }
47 return handler(ctx, req)
48 }
49 }
50
51
52 func WithRateLimiter(serviceName string, qps, burstTokens int32) grpc.ServerOption {
53 qpsVal := gotimerate.Limit(qps)
54 burstVal := int(burstTokens)
55 klog.InfoS("Setting rate limiting for endpoint", "service", serviceName, "qps", qpsVal, "burstTokens", burstVal)
56 return grpc.UnaryInterceptor(LimiterUnaryServerInterceptor(gotimerate.NewLimiter(qpsVal, burstVal)))
57 }
58
View as plain text