跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Go 没有泛型,业务逻辑相似的 grpc 调用代码如何能更优雅一些?
未分類
21 10 月 2020

Go 没有泛型,业务逻辑相似的 grpc 调用代码如何能更优雅一些?

Go 没有泛型,业务逻辑相似的 grpc 调用代码如何能更优雅一些?

資深大佬 : xmcy0011 2

有个 gate 网关,包装一层 grpc 调用 logic 上的接口,协议使用的 protobuf 。大致业务流程都差不多: 1.反序列化成对象 2.调用 grpc 接口 3.根据结果,发送到客户端。

具体代码如下:

// 创建群 func (tcp *TcpConn) onHandleCreateGroup(header *cim.ImHeader, buff []byte) {  req := &cim.CIMGroupCreateReq{}  err := proto.Unmarshal(buff, req)  if err != nil {   logger.Sugar.Warnf("onHandleCreateGroup error")   return  }   logger.Sugar.Info("onHandleCreateGroup")   conn := GetMessageConn()  ctx, cancelFun := context.WithTimeout(context.Background(), time.Second*3)  defer cancelFun()   rsp, err := conn.CreateGroup(ctx, req)  if err != nil {   logger.Sugar.Warnf("CreateGroup(gRPC) err:", err.Error())  } else {   _, err = tcp.Send(header.SeqNum, uint16(GROUP_CREATE_DEFAULT_REQ), rsp)   logger.Sugar.Infof("onHandleCreateGroup CreateGroup(gRPC) res")  } }  // 解散群 func (tcp *TcpConn) onHandleDisbandingGroup(header *cim.ImHeader, buff []byte) {  req := &cim.CIMGroupDisbandingReq{}  err := proto.Unmarshal(buff, req)  if err != nil {   logger.Sugar.Warnf("onHandleDisbandingGroup error")   return  }   logger.Sugar.Info("onHandleDisbandingGroup")   conn := GetMessageConn()  ctx, cancelFun := context.WithTimeout(context.Background(), time.Second*3)  defer cancelFun()   rsp, err := conn.DisbandingGroup(ctx, req)  if err != nil {   logger.Sugar.Warnf("DisbandingGroup(gRPC) err:")  } else {   _, err = tcp.Send(header.SeqNum, uint16(GROUP_DISBINGDING_RSP), rsp)   logger.Sugar.Infof("onHandleDisbandingGroup res")  } } 

大佬有話說 (13)

  • 資深大佬 : BoarBoar

    一般都是 interface{}代替泛型,不过会写很多用反射或者断言去判断 interface 持有类型的代码,用得少的话没必要搞

  • 資深大佬 : lance6716

    我当时用的运行时和反射。当时也考虑过 go generate template…

  • 資深大佬 : fuis

    @xmcy0011 随手写了一段,大概看个意思。基本思路就是把重复的地方抠出来做成 func,然后用另一个 helper func 去调用它们。参数尽量看准原来就使用 interface{} 的地方,这样不用写很多 type assert

    “`go
    func (tcp *TcpConn) onHandleCreateGroup(header *cim.ImHeader, buff []byte) {
    req := &cim.CIMGroupCreateReq{}
    call(header, buff, req, func() {
    return conn.CreateGroup(ctx, req)
    }, func(rsp Response) {
    _, err = tcp.Send(…)
    })
    }

    func (tcp *TcpConn) onHandleDisbandingGroup(header *cim.ImHeader, buff []byte) {
    req := &cim.CIMGroupDisbandingReq{}
    call(header, buff, req, func () {
    return conn.DisbandingGroup(ctx, req)
    }, func(rsp Response) {
    _, err = tcp.Send(…)
    })
    }

    func (t *TcpConn) call(
    header *cim.ImHeader,
    buff []byte,
    req interface{},
    method string,
    rpcFn func(context.Context, interface{}) (Response, error),
    callback func(Response) error) func() {
    return func() {
    err := proto.Unmarshal(buff, req)
    if err != nil {
    logger.Sugar.Warnf(“%s error”, method)
    return
    }

    logger.Sugar.Info(method)

    conn := GetMessageConn()
    ctx, cancelFun := context.WithTimeout(context.Background(), time.Second*3)
    defer cancelFun()

    rsp, err := rpcFn(ctx, req)
    if err != nil {
    logger.Sugar.Warnf(“DisbandingGroup(gRPC) err:”)
    } else {
    _, err := callback(rsp)
    logger.Sugar.Infof(“onHandleDisbandingGroup res”)
    }
    }
    }

    “`

  • 資深大佬 : hakono

    反射会影响程序性能

  • 資深大佬 : beidounanxizi

    别整反射 去看看 go proverb
    泛型 去用回 JAVA 吧
    没泛型 更优雅

  • 資深大佬 : deepreader

    等 go 1.15 支持泛型吧 https://blog.golang.org/why-generics

  • 資深大佬 : raaaaaar

    在写了在写了,别催

  • 資深大佬 : xuanbg

    用不着泛型,log 的内容可以参数拼接,发送的内容可以先序列化再作为参数传入进行发送。你需要的只是分拆几个静态方法而已。

  • 資深大佬 : eudore

    不是有 pb 插件自动生成的调用代码? 你还自己手写个啥

  • 資深大佬 : zunceng

    我在自己的 infra 里面写了个代码生成的脚本

  • 資深大佬 : mikulch

    @beidounanxizi 已经在做了,这个语法。

  • 資深大佬 : joesonw

    自己写个 protoc-plugin 进去, 生成 go 代码?

  • 資深大佬 : troywinter

    传个闭包进来,用户使用时,在 func 里自己 cast 到想要的类型,稍微啰嗦一两行。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具