Skip to content

Commit 76b73e7

Browse files
committed
add grpc healthcheck option for clientv3
Signed-off-by: shenmu.wy <shenmu.wy@antfin.com>
1 parent 22d55b5 commit 76b73e7

4 files changed

Lines changed: 85 additions & 17 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../tests/integration/clientv3/examples/example_healthcheck_test.go
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2026 The etcd Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package healthcheck
16+
17+
import (
18+
"google.golang.org/grpc"
19+
// Register the gRPC client's health check implementation via its init().
20+
// It sets internal.HealthCheckFunc = clientHealthCheck, which is required
21+
// for the client-side healthCheckConfig (see GRPCClientHealthCheckOptions)
22+
// to perform health checks against the server.
23+
_ "google.golang.org/grpc/health"
24+
)
25+
26+
func GRPCClientHealthCheckOptions() []grpc.DialOption {
27+
return []grpc.DialOption{
28+
grpc.WithDisableServiceConfig(),
29+
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`),
30+
}
31+
}

tests/e2e/failover_test.go

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ import (
2424
"github.com/stretchr/testify/require"
2525
"golang.org/x/sync/errgroup"
2626
"google.golang.org/grpc"
27-
_ "google.golang.org/grpc/health"
2827

2928
clientv3 "go.etcd.io/etcd/client/v3"
29+
"go.etcd.io/etcd/client/v3/healthcheck"
3030
"go.etcd.io/etcd/tests/v3/framework/config"
3131
"go.etcd.io/etcd/tests/v3/framework/e2e"
3232
)
@@ -62,10 +62,7 @@ func TestFailoverOnDefrag(t *testing.T) {
6262
e2e.WithServerFeatureGate("StopGRPCServiceOnDefrag", true),
6363
e2e.WithGoFailEnabled(true),
6464
},
65-
gRPCDialOptions: []grpc.DialOption{
66-
grpc.WithDisableServiceConfig(),
67-
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`),
68-
},
65+
gRPCDialOptions: healthcheck.GRPCClientHealthCheckOptions(),
6966
expectedMinQPS: 20,
7067
expectedMaxFailureRate: 0.01,
7168
},
@@ -76,10 +73,7 @@ func TestFailoverOnDefrag(t *testing.T) {
7673
e2e.WithServerFeatureGate("StopGRPCServiceOnDefrag", false),
7774
e2e.WithGoFailEnabled(true),
7875
},
79-
gRPCDialOptions: []grpc.DialOption{
80-
grpc.WithDisableServiceConfig(),
81-
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`),
82-
},
76+
gRPCDialOptions: healthcheck.GRPCClientHealthCheckOptions(),
8377
expectedMinQPS: 20,
8478
expectedMinFailureRate: 0.25,
8579
},
@@ -100,10 +94,7 @@ func TestFailoverOnDefrag(t *testing.T) {
10094
e2e.WithServerFeatureGate("StopGRPCServiceOnDefrag", true),
10195
e2e.WithGoFailEnabled(true),
10296
},
103-
gRPCDialOptions: []grpc.DialOption{
104-
grpc.WithDisableServiceConfig(),
105-
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`),
106-
},
97+
gRPCDialOptions: healthcheck.GRPCClientHealthCheckOptions(),
10798
expectedMinQPS: 20,
10899
expectedMaxFailureRate: 0.01,
109100
},
@@ -114,10 +105,7 @@ func TestFailoverOnDefrag(t *testing.T) {
114105
e2e.WithServerFeatureGate("StopGRPCServiceOnDefrag", false),
115106
e2e.WithGoFailEnabled(true),
116107
},
117-
gRPCDialOptions: []grpc.DialOption{
118-
grpc.WithDisableServiceConfig(),
119-
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`),
120-
},
108+
gRPCDialOptions: healthcheck.GRPCClientHealthCheckOptions(),
121109
expectedMinQPS: 20,
122110
expectedMinFailureRate: 0.25,
123111
},
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2026 The etcd Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package clientv3_test
16+
17+
import (
18+
"context"
19+
"fmt"
20+
"log"
21+
22+
clientv3 "go.etcd.io/etcd/client/v3"
23+
"go.etcd.io/etcd/client/v3/healthcheck"
24+
)
25+
26+
func mockHealthCheck() {
27+
fmt.Println("")
28+
}
29+
30+
func Example_grpcClientHealthCheck() {
31+
forUnitTestsRunInMockedContext(mockHealthCheck, func() {
32+
cli, err := clientv3.New(clientv3.Config{
33+
Endpoints: exampleEndpoints(),
34+
DialTimeout: dialTimeout,
35+
DialOptions: healthcheck.GRPCClientHealthCheckOptions(),
36+
})
37+
if err != nil {
38+
log.Fatal(err)
39+
}
40+
defer cli.Close()
41+
42+
_, err = cli.Put(context.TODO(), "foo", "bar")
43+
if err != nil {
44+
log.Fatal(err)
45+
}
46+
})
47+
// Output:
48+
}

0 commit comments

Comments
 (0)