什么是将第三方异步API与Cap'n Proto RPC集成的好方法?

问题描述:

我有一个处理Cap'n Proto RPC请求的Linux服务器。其中一些请求需要将请求中的数据转发到另一台运行的服务器,在这种情况下为卡夫卡经纪人。 librdkafka和Cap'n Proto KJ库都可以使用poll(),所以我认为操作系统将确保它们都可以异步运行,但我不确定是否需要进一步的集成或者是否有益。有人对此有经验吗?什么是将第三方异步API与Cap'n Proto RPC集成的好方法?

这个问题比我列出的细节稍宽一点..还有其他的API可能会在Cap'n Proto RPC的将来调用,因此任何广泛的指导方针将不胜感激。

不幸的是,这并不那么简单。是的,他们都使用poll(),但问题是,一次只有一个库将调用poll(),并且只有该库实际上会接收任何事件 - 另一个会卡住。这是事件循环库的经典挑战 - 默认情况下,它们不能一起使用。

一种选择是尝试在单独的线程中使用这些库。但是,经常事件驱动的库设计的假设是你在单线程中做所有事情,否则为什么你需要一个事件循环?

但“正确的事情”是整合事件循环。 KJ的事件循环能够与其他事件库集成。例如,我将它与libuv集成为node-capnp;看到此文件的第一部分:(。在某些时候,我打算在这里分离出libuv相关代码到附带头儿原一个单独的库)

https://github.com/kentonv/node-capnp/blob/master/src/node-capnp/capnp.cc

对于另一例如,这是Nathan Hourt提出的添加与Qt事件循环集成的请求 - 但请注意,这不包括I/O集成,我认为是因为Nathan正在使用一个实现AsyncIoStream,当他可用:

https://github.com/sandstorm-io/capnproto/pull/253

无论如何,你需要做一些类似于Kafka使用的东西。希望你会将你的代码回复给Cap'n Proto! :)

+0

谢谢Kenton。我查看了节点的实现,但有点谨慎,因为它将libuv添加到混合中,并且它被认为是缓慢且有点笨拙。 我很想将Kafka位移入一个与KJ的接口链接的新库。如果RPC管道可以使用零拷贝访问新功能,那将会很不错,但我不确定这是多么的困难。这听起来对你有用吗? 我处于初创阶段的创业公司,所以我们可能无法开放源代码,直到我们得到一些投资者:)。 –

+0

librdkafka提供了一个非阻塞的异步接口,所有的IO操作都是在后台线程中执行的,所以你应该简单地依靠Cap'n的事件分派器作为你的主循环。 – Edenhill

+0

@JamesFremen我将libuv实现作为如何将KJ与外部事件循环集成的示例。我不知道KJ-UV胶水代码有任何性能问题或其他主要问题。它完全是零拷贝。除非Kafka的低级别事件界面非常糟糕,否则您应该能够以这种方式与它整合。 –