美文网首页
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 泛型

    go 泛型 1. 类型参数(Type parameters) Go语言的泛型(Generic)叫做类型参数。泛型可...

  • Java-API-集合框架(三)-泛型

    泛型的由来和基本使用 泛型的擦除 泛型类的使用 泛型方法的使用 泛型接口 泛型通配符(?) 通配符? 在api中的...

  • Go语言 泛型

    本篇文章转载自 在go中使用"泛型" 在进入泛型的话题之前, 首先实现对int 数组切片的冒泡排序: 如你所见, ...

  • golang Interface 泛型编程

    严格来说,在 Golang 中并不支持泛型编程。在 C++ 等高级语言中使用泛型编程非常的简单,所以泛型编程一直是...

  • Kotlin 泛型

    Kotlin 泛型 1. 泛型类 定义一个泛型类 使用 在继承中 使用 2. 泛型函数 使用 3. 泛型的擦除 无...

  • Golang学习笔记---“泛型”的实现

    Golang学习笔记---“泛型”的实现 大家都知道,go语言中是没有泛型的,但是我们可以通过空接口的方式来实现泛...

  • Go 泛型初体验

    在 Go1.17 中,千呼万唤的泛型终于出来了,但又没有完全出来。在 Go1.17 的发布文档中,并没有提到泛型,...

  • JavaSE学习笔记——泛型

    泛型在集合中的使用集合中不使用泛型时: public void test1(){ //1.在集合中没有使用...

  • typescript 难点梳理

    1.new关键字在类型中的使用 泛型 在泛型里使用类类型 在TypeScript使用泛型创建工厂函数时,需要引用构...

  • java基础-day13-泛型

    泛型 1. 泛型 1.1 为什么要使用泛型 1.2 泛型的基本格式 1.3 泛型在方法中使用 1.3 泛型在类内的...

网友评论

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

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