You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
2.9 KiB
112 lines
2.9 KiB
package app
|
|
|
|
import (
|
|
"context"
|
|
"et_rpc/pb"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
"google.golang.org/grpc/health/grpc_health_v1"
|
|
"log"
|
|
"time"
|
|
|
|
pool "github.com/jolestar/go-commons-pool"
|
|
)
|
|
|
|
type MasterGRPCPoolObject struct {
|
|
Conn *grpc.ClientConn // 保存 gRPC 连接
|
|
Client pb.MasterServiceClient // gRPC 客户端
|
|
}
|
|
|
|
type MasterGRPCClientFactory struct {
|
|
address string
|
|
}
|
|
|
|
// NewGRPCClientFactory 创建新的 gRPC 连接工厂
|
|
func NewMasterGRPCClientFactory(address string) *MasterGRPCClientFactory {
|
|
return &MasterGRPCClientFactory{
|
|
address: address,
|
|
}
|
|
}
|
|
|
|
func (f *MasterGRPCClientFactory) MakeObject(ctx context.Context) (*pool.PooledObject, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
// 定义重试策略
|
|
serviceConfig := `{
|
|
"methodConfig": [{
|
|
"name": [{"service": "MasterService", "method": "*"}],
|
|
"retryPolicy": {
|
|
"maxAttempts": 2,
|
|
"initialBackoff": "1s",
|
|
"maxBackoff": "10s",
|
|
"backoffMultiplier": 2,
|
|
"retryableStatusCodes": ["UNAVAILABLE", "DEADLINE_EXCEEDED"]
|
|
}
|
|
}]
|
|
}`
|
|
|
|
conn, err := grpc.NewClient(
|
|
f.address,
|
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
|
grpc.WithDefaultServiceConfig(serviceConfig),
|
|
)
|
|
|
|
if err != nil {
|
|
return nil, err // 如果3次都失败,返回错误
|
|
}
|
|
|
|
client := pb.NewMasterServiceClient(conn)
|
|
return pool.NewPooledObject(
|
|
&MasterGRPCPoolObject{
|
|
Conn: conn,
|
|
Client: client,
|
|
},
|
|
), nil
|
|
}
|
|
|
|
// 销毁 gRPC 连接
|
|
func (f *MasterGRPCClientFactory) DestroyObject(ctx context.Context, object *pool.PooledObject) error {
|
|
grpcPoolObj := object.Object.(*MasterGRPCPoolObject)
|
|
if grpcPoolObj.Client != nil {
|
|
// 关闭连接
|
|
grpcPoolObj.Conn.Close() // gRPC 客户端连接关闭
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 验证 gRPC 连接的有效性
|
|
func (f *MasterGRPCClientFactory) ValidateObject(ctx context.Context, object *pool.PooledObject) bool {
|
|
grpcPoolObj := object.Object.(*MasterGRPCPoolObject)
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
return false // 如果上下文已经取消,返回无效
|
|
default:
|
|
// 继续进行有效性检查
|
|
}
|
|
|
|
healthClient := grpc_health_v1.NewHealthClient(grpcPoolObj.Conn)
|
|
resp, err := healthClient.Check(ctx, &grpc_health_v1.HealthCheckRequest{
|
|
Service: "MasterService",
|
|
})
|
|
|
|
if err != nil || resp.Status != grpc_health_v1.HealthCheckResponse_SERVING {
|
|
log.Println("ValidateObject failed:", err)
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// 激活 gRPC 连接
|
|
func (f *MasterGRPCClientFactory) ActivateObject(ctx context.Context, object *pool.PooledObject) error {
|
|
// 可以在这里发送心跳请求以确保连接有效
|
|
return nil
|
|
}
|
|
|
|
// 非激活 gRPC 连接
|
|
func (f *MasterGRPCClientFactory) PassivateObject(ctx context.Context, object *pool.PooledObject) error {
|
|
// 可以在这里进行连接的重置,例如清除状态或缓存
|
|
return nil
|
|
}
|
|
|