美文网首页
go语言泛型在grpc-client中的使用

go语言泛型在grpc-client中的使用

作者: 鸿雁长飞光不度 | 来源:发表于2023-08-17 00:06 被阅读0次

    通过使用泛型可以减少grpc-client公共代码的重复编写。

    // ------------------------------公共的------------------------------------------------------
    type clientSvc[T any] struct {
        *grpcpool.Pool
        InitClientCall func(grpc.ClientConnInterface) T
    }
    
    func (c *clientSvc[T]) getCli(ctx context.Context) (T, func() error, error) {
        defer timecost.LogFuncTimeCost(ctx)()
        var defaultValue T
        if c.Pool == nil {
            return defaultValue, nil, fmt.Errorf("clientSvcConnPool not initialized yet")
        }
    
        conn, err := c.Pool.Get(ctx)
    
        if err != nil {
            return defaultValue, nil, fmt.Errorf("get client svc client err, available=%d capacity=%d err=%w", c.Pool.Available(), c.Pool.Capacity(), err)
        }
    
        return c.InitClientCall(conn), conn.Close, nil
    }
    
    func (c *clientSvc[T]) baseCall(ctx context.Context, reqCall func(T) error) error {
        cli, closeFunc, err := c.getCli(ctx)
        if err != nil {
            return err
        }
        defer func() {
            _ = closeFunc()
        }()
    
        if reqCall != nil {
            err = reqCall(cli)
            if err != nil {
                return err
            }
        }
        return nil
    }
    
    func newBaseClient[T any](addr string, poolCfg *grpcutils.PoolConfig, opts []grpcutils.Option, InitClientCall func(grpc.ClientConnInterface) T) (*clientSvc[T], error) {
        connPool, err := grpcutils.NewGRPCPool(addr, poolCfg, opts...)
        if err != nil {
            return nil, fmt.Errorf("get client svc client err, available=%d capacity=%d err=%w", connPool.Available(), connPool.Capacity(), err)
        }
    
        return &clientSvc[T]{
            Pool:           connPool,
            InitClientCall: InitClientCall,
        }, nil
    }
    
    func (c *clientSvc[T]) Close() {
        if c.Pool != nil && !c.Pool.IsClosed() {
            c.Pool.Close()
        }
    }
    
    //------------------------------Client服务的Client------------------------------------------------------
    
    type IClient interface {
        Close()
        GetClientID(ctx context.Context, id uint64) (int64, error)
    }
    
    type clientSvcClient struct {
        clientSvc[clientservicepb.InternalServiceClient]
    }
    
    func NewClientSvc(addr string, poolCfg *grpcutils.PoolConfig, opts []grpcutils.Option) (IClient, error) {
        c, err := newBaseClient[clientservicepb.InternalServiceClient](addr, poolCfg, opts, func(conn grpc.ClientConnInterface) clientservicepb.InternalServiceClient {
            return clientservicepb.NewInternalServiceClient(conn)
        })
        if err != nil {
            return nil, err
        }
        return &clientSvcClient{
            clientSvc: *c,
        }, nil
    }
    
    func (c *clientSvcClient) GetClientID(ctx context.Context, id uint64) (int64, error){
        var resultId int64
        err := c.baseCall(ctx, func(cli clientservicepb.InternalServiceClient) error {
            req := &clientcommonpb.IDRequest{
                Id: clientMemberId,
            }
    
            resp, err := cli.GetClientIDByClientMemberID(ctx, req)
            if err != nil {
                return err
            }
            resultId = resp.GetData().GetId()
            return nil
        })
    
        if err != nil {
            return 0,  err
        }
        return resultId, nil
    }
    
    

    相关文章

      网友评论

          本文标题:go语言泛型在grpc-client中的使用

          本文链接:https://www.haomeiwen.com/subject/hzylmdtx.html