Skip to content

Commit

Permalink
Ratelimiter returns resource exhausted error
Browse files Browse the repository at this point in the history
This is necessary so that when it is used with the backoff retry it will
allow for the backoff to continue to work as expected.

Signed-off-by: Nathan Zender <github@nathanzender.com>
  • Loading branch information
zendern committed Feb 24, 2020
1 parent 2e09e2c commit fec6e23
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
4 changes: 3 additions & 1 deletion pkg/util/grpcclient/ratelimit.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (

"golang.org/x/time/rate"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

// NewRateLimiter creates a UnaryClientInterceptor for client side rate limiting.
Expand All @@ -17,7 +19,7 @@ func NewRateLimiter(cfg *Config) grpc.UnaryClientInterceptor {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
err := limiter.Wait(ctx)
if err != nil {
return err
return status.Error(codes.ResourceExhausted, err.Error())
}
return invoker(ctx, method, req, reply, cc, opts...)
}
Expand Down
36 changes: 36 additions & 0 deletions pkg/util/grpcclient/ratelimit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package grpcclient_test

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/cortexproject/cortex/pkg/util/grpcclient"
)

func TestRateLimiterFailureResultsInResourceExhaustedError(t *testing.T) {
config := grpcclient.Config{
RateLimitBurst: 0,
RateLimit: 0,
}
conn := grpc.ClientConn{}
invoker := func(currentCtx context.Context, currentMethod string, currentReq, currentRepl interface{}, currentConn *grpc.ClientConn, currentOpts ...grpc.CallOption) error {
return nil
}

limiter := grpcclient.NewRateLimiter(&config)
err := limiter(context.Background(), "methodName", "", "expectedReply", &conn, invoker)

if se, ok := err.(interface {
GRPCStatus() *status.Status
}); ok {
assert.Equal(t, se.GRPCStatus().Code(), codes.ResourceExhausted)
assert.Equal(t, se.GRPCStatus().Message(), "rate: Wait(n=1) exceeds limiter's burst 0")
} else {
assert.Fail(t, "Could not convert error into expected Status type")
}
}

0 comments on commit fec6e23

Please sign in to comment.