忍不住想吐槽下 grpc 的 C++ async API

2020-03-11 09:35:01 +08:00
 DinoStray

grpc 当前版本的 C++ async API, 是基于 completion queue 实现的.

  1. 首先在 api 设计上, 对于单次 rpc 调用, 这个 completion queue 只能有两个, 分别是 call 和 notification(grpc 起的名字), 读写事件只能在 call 这一个 completion queue 回调
  2. completion queue 事件返回时会带有一个标识. 在官方的 demo 中, 这个标识用来标记是哪个对象产生了事件. 你想通过这个标识同时区分到底是哪种事件产生, 是不可能了.
  3. 简单来说, completion queue 返回的值, 只有一个, 这个值在有些 demo(官方) 里被用来标记对象, 有些 demo(网上的一些例子) 里被用来标记事件, 可是我写基于 stream(也就是 N 个请求 N 个返回) 的长连接, 需要同时获得这两个信息啊
  4. 如果参照 libevent 之类的办法, 最起码应该分别有"读"/"写"以及"连接事件"的 completion queue
  5. 可能官方也不知道怎么处理最好, 唯一的 async api demo 是不包含 stream 的, 简单的单次 rpc 调用

为了解决这个问题, 我只好用一个"全局唯一的 uint64 id"标识对象, 并在分配 id 的时候做了区间划分, 比如 * id + 0 用来标识 "连接创建事件"

然后下一个新的对象 id , 在上一个 id 的基础上 + 4
这是我的 demo:
https://github.com/DinoStray/grpc_example_async_cpp_api

关于这个问题, 几年前就有人开始吐槽(描述的问题和我一模一样)
https://groups.google.com/forum/#!topic/grpc-io/7P8QvBBNq_E
grpc 官方也给了回应, 并表示将优化 api
https://github.com/grpc/grpc/issues/7352
可是 2016 年的回应, 都过去 4 年了, 还没完成....吐血

5631 次点击
所在节点    程序员
28 条回复
DinoStray
2020-03-11 12:06:20 +08:00
@jonah Sorry, 我看懂你的意思了, 你是做了第二层封装, 把 session 对象和状态封装到一起了
DinoStray
2020-03-11 12:07:50 +08:00
@jonah 你的这个封装, 和我把 session id + event 事件 的解决方式, 是类似的, 不过有一点, 我的代码习惯用 C++11 智能指针管理, 不太想直接传递裸指针
DinoStray
2020-03-11 12:11:28 +08:00
@DinoStray 你的意思, 是每次调用异步 api, 都 new 一个新的对象, 新的对象封装了 session 和事件, 异步 api 回调的时候, 就可以通过这个对象知道 session 和产生的 event, 然后直接销毁这个临时的对象, 我的理解没错吧
jonah
2020-03-11 12:17:43 +08:00
@DinoStray unique_ptr 更安全,传的时候 release 一下,Next 回来就用 unique_ptr 包起来。但是传递给 completion queue 避免不了裸指针的,它调的底层 c 的接口。
对, 是这个意思,我看你主题里说主要问题是需要获取同时多个信息,这种是个通用的做法,可以保存任何必要的信息。
DinoStray
2020-03-11 12:22:34 +08:00
@jonah 我一直觉得用了智能指针就不能暴露裸指针了, 这两个东西混太容易导致程序崩溃. 我看 grpc 源码, 到处都是 unique_ptr 和裸指针的混用, 看的蛋疼
jonah
2020-03-11 12:27:55 +08:00
@DinoStray 只能说尽量这样做。grpc 的代码一言难尽。。。
DinoStray
2020-03-11 12:30:31 +08:00
@jonah 我还一个问题暂时不知道怎么办, 不管服务端还是客户端, 我好像只能调用 TryCancel() 函数去主动关闭 一个处于 读写状态的 session, 更合适的主动关闭方式是调用哪个函数呢
jonah
2020-03-11 12:33:29 +08:00
@DinoStray 这个我也不清楚,已经弃用 grpc 有些年头了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/651747

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX