Skip to content

Commit 375dd19

Browse files
Properly handle grpc dial errors in the throttler metric aggregation (vitessio#18073)
Signed-off-by: Arthur Schreiber <[email protected]> Signed-off-by: Mohamed Hamza <[email protected]> Co-authored-by: Mohamed Hamza <[email protected]>
1 parent 20c989e commit 375dd19

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

go/vt/vttablet/tabletserver/throttle/base/throttle_metric.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ package base
4444
import (
4545
"errors"
4646
"strings"
47+
48+
"google.golang.org/grpc/codes"
49+
"google.golang.org/grpc/status"
4750
)
4851

4952
// MetricResult is what we expect our probes to return. This can be a numeric result, or
@@ -70,6 +73,11 @@ func IsDialTCPError(e error) bool {
7073
if e == nil {
7174
return false
7275
}
76+
77+
if s, ok := status.FromError(e); ok {
78+
return s.Code() == codes.Unavailable || s.Code() == codes.DeadlineExceeded
79+
}
80+
7381
return strings.HasPrefix(e.Error(), "dial tcp")
7482
}
7583

go/vt/vttablet/tabletserver/throttle/throttler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ func (throttler *Throttler) generateTabletProbeFunction(ctx context.Context, clu
859859
req := &tabletmanagerdatapb.CheckThrottlerRequest{} // We leave AppName empty; it will default to VitessName anyway, and we can save some proto space
860860
resp, gRPCErr := tmClient.CheckThrottler(ctx, probe.Tablet, req)
861861
if gRPCErr != nil {
862-
mySQLThrottleMetric.Err = fmt.Errorf("gRPC error accessing tablet %v. Err=%v", probe.Alias, gRPCErr)
862+
mySQLThrottleMetric.Err = fmt.Errorf("gRPC error accessing tablet %v. Err=%w", probe.Alias, gRPCErr)
863863
return mySQLThrottleMetric
864864
}
865865
mySQLThrottleMetric.Value = resp.Value

go/vt/vttablet/tabletserver/throttle/throttler_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,15 @@ import (
2929
"github.com/stretchr/testify/assert"
3030
"github.com/stretchr/testify/require"
3131

32+
"google.golang.org/grpc"
33+
"google.golang.org/grpc/credentials/insecure"
34+
35+
"vitess.io/vitess/go/vt/grpcclient"
3236
"vitess.io/vitess/go/vt/topo"
3337
"vitess.io/vitess/go/vt/vtenv"
3438
"vitess.io/vitess/go/vt/vttablet/tabletserver/connpool"
3539
"vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv"
40+
"vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base"
3641
"vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/config"
3742
"vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/mysql"
3843
"vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp"
@@ -191,6 +196,21 @@ func TestInitThrottler(t *testing.T) {
191196
assert.EqualValues(t, 3, throttler.recentCheckDiff)
192197
}
193198

199+
func TestIsDialTCPError(t *testing.T) {
200+
// Verify that IsDialTCPError actually recognizes grpc dial errors
201+
cc, err := grpcclient.DialContext(context.Background(), ":0", true, grpc.WithTransportCredentials(insecure.NewCredentials()))
202+
require.NoError(t, err)
203+
defer cc.Close()
204+
205+
err = cc.Invoke(context.Background(), "/Fail", nil, nil)
206+
207+
require.True(t, base.IsDialTCPError(err))
208+
require.True(t, base.IsDialTCPError(fmt.Errorf("wrapped: %w", err)))
209+
210+
nonDialErr := fmt.Errorf("rpc error: code = NotFound desc = method not found")
211+
require.False(t, base.IsDialTCPError(nonDialErr))
212+
}
213+
194214
func TestIsAppThrottled(t *testing.T) {
195215
throttler := Throttler{
196216
throttledApps: cache.New(cache.NoExpiration, 0),

0 commit comments

Comments
 (0)