et-go 20240919重建
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.8 KiB

package node_manager
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 GRPCPoolObject struct {
Conn *grpc.ClientConn // 保存 gRPC 连接
Client pb.NodeServiceClient // gRPC 客户端
}
type GRPCClientFactory struct {
address string
}
// NewGRPCClientFactory 创建新的 gRPC 连接工厂
func NewGRPCClientFactory(address string) *GRPCClientFactory {
return &GRPCClientFactory{
address: address,
}
}
func (f *GRPCClientFactory) MakeObject(ctx context.Context) (*pool.PooledObject, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 定义重试策略
serviceConfig := `{
"methodConfig": [{
"name": [{"service": "NodeService", "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.NewNodeServiceClient(conn)
return pool.NewPooledObject(
&GRPCPoolObject{
Conn: conn,
Client: client,
},
), nil
}
// 销毁 gRPC 连接
func (f *GRPCClientFactory) DestroyObject(ctx context.Context, object *pool.PooledObject) error {
grpcPoolObj := object.Object.(*GRPCPoolObject)
if grpcPoolObj.Client != nil {
// 关闭连接
grpcPoolObj.Conn.Close() // gRPC 客户端连接关闭
}
return nil
}
// 验证 gRPC 连接的有效性
func (f *GRPCClientFactory) ValidateObject(ctx context.Context, object *pool.PooledObject) bool {
grpcPoolObj := object.Object.(*GRPCPoolObject)
select {
case <-ctx.Done():
return false // 如果上下文已经取消,返回无效
default:
// 继续进行有效性检查
}
healthClient := grpc_health_v1.NewHealthClient(grpcPoolObj.Conn)
resp, err := healthClient.Check(ctx, &grpc_health_v1.HealthCheckRequest{
Service: "NodeService",
})
if err != nil || resp.Status != grpc_health_v1.HealthCheckResponse_SERVING {
log.Println("ValidateObject failed:", err)
return false
}
return true
}
// 激活 gRPC 连接
func (f *GRPCClientFactory) ActivateObject(ctx context.Context, object *pool.PooledObject) error {
// 可以在这里发送心跳请求以确保连接有效
return nil
}
// 非激活 gRPC 连接
func (f *GRPCClientFactory) PassivateObject(ctx context.Context, object *pool.PooledObject) error {
// 可以在这里进行连接的重置,例如清除状态或缓存
return nil
}