Skip to content

Commit

Permalink
fix(retry): fix retries when using protobuf encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
ashwanthgoli committed Jun 25, 2024
1 parent 0cb3ff1 commit 76a764b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
6 changes: 3 additions & 3 deletions pkg/querier/queryrange/queryrangebase/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (

"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/gogo/status"
"github.com/grafana/dskit/backoff"
"github.com/grafana/dskit/httpgrpc"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

Expand Down Expand Up @@ -89,8 +89,8 @@ func (r retry) Do(ctx context.Context, req Request) (Response, error) {
}

// Retry if we get a HTTP 500 or a non-HTTP error.
httpResp, ok := httpgrpc.HTTPResponseFromError(err)
if !ok || httpResp.Code/100 == 5 {
status, ok := status.FromError(err)
if !ok || status.Code()/100 == 5 {
lastErr = err
level.Error(util_log.WithContext(ctx, r.log)).Log(
"msg", "error processing request",
Expand Down
46 changes: 38 additions & 8 deletions pkg/querier/queryrange/queryrangebase/retry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import (
"testing"

"github.com/go-kit/log"
"github.com/gogo/status"
"github.com/grafana/dskit/httpgrpc"
"github.com/stretchr/testify/require"
"go.uber.org/atomic"
"google.golang.org/grpc/codes"

"github.com/grafana/loki/v3/pkg/util/constants"
)
Expand All @@ -19,10 +21,11 @@ func TestRetry(t *testing.T) {
var try atomic.Int32

for _, tc := range []struct {
name string
handler Handler
resp Response
err error
name string
handler Handler
resp Response
err error
expectedCalls int
}{
{
name: "retry failures",
Expand All @@ -32,21 +35,26 @@ func TestRetry(t *testing.T) {
}
return nil, fmt.Errorf("fail")
}),
resp: &PrometheusResponse{Status: "Hello World"},
resp: &PrometheusResponse{Status: "Hello World"},
expectedCalls: 5,
},
{
name: "don't retry 400s",
handler: HandlerFunc(func(_ context.Context, req Request) (Response, error) {
try.Inc()
return nil, httpgrpc.Errorf(http.StatusBadRequest, "Bad Request")
}),
err: httpgrpc.Errorf(http.StatusBadRequest, "Bad Request"),
err: httpgrpc.Errorf(http.StatusBadRequest, "Bad Request"),
expectedCalls: 1,
},
{
name: "retry 500s",
handler: HandlerFunc(func(_ context.Context, req Request) (Response, error) {
try.Inc()
return nil, httpgrpc.Errorf(http.StatusInternalServerError, "Internal Server Error")
}),
err: httpgrpc.Errorf(http.StatusInternalServerError, "Internal Server Error"),
err: httpgrpc.Errorf(http.StatusInternalServerError, "Internal Server Error"),
expectedCalls: 5,
},
{
name: "last error",
Expand All @@ -56,7 +64,28 @@ func TestRetry(t *testing.T) {
}
return nil, httpgrpc.Errorf(http.StatusInternalServerError, "Internal Server Error")
}),
err: httpgrpc.Errorf(http.StatusBadRequest, "Bad Request"),
err: httpgrpc.Errorf(http.StatusBadRequest, "Bad Request"),
expectedCalls: 5,
},
// previous entires in this table use httpgrpc.Errorf for generating the error which also populates the Details field with the marshalled http response.
// Next set of tests validate the retry behavior when using protobuf encoding where the status does not include the details.
{
name: "protobuf enc don't retry 400s",
handler: HandlerFunc(func(_ context.Context, req Request) (Response, error) {
try.Inc()
return nil, status.New(codes.Code(http.StatusBadRequest), "Bad Request").Err()
}),
err: status.New(codes.Code(http.StatusBadRequest), "Bad Request").Err(),
expectedCalls: 1,
},
{
name: "protobuf enc retry 500s",
handler: HandlerFunc(func(_ context.Context, req Request) (Response, error) {
try.Inc()
return nil, status.New(codes.Code(http.StatusInternalServerError), "Internal Server Error").Err()
}),
err: status.New(codes.Code(http.StatusInternalServerError), "Internal Server Error").Err(),
expectedCalls: 5,
},
} {
t.Run(tc.name, func(t *testing.T) {
Expand All @@ -68,6 +97,7 @@ func TestRetry(t *testing.T) {
resp, err := h.Do(context.Background(), req)
require.Equal(t, tc.err, err)
require.Equal(t, tc.resp, resp)
require.EqualValues(t, tc.expectedCalls, try.Load())
})
}
}
Expand Down

0 comments on commit 76a764b

Please sign in to comment.