2015-10-14 93 views
0

我有一個處理Cap'n Proto RPC請求的Linux服務器。其中一些請求需要將請求中的數據轉發到另一臺運行的服務器,在這種情況下爲卡夫卡經紀人。 librdkafka和Cap'n Proto KJ庫都可以使用poll(),所以我認爲操作系統將確保它們都可以異步運行,但我不確定是否需要進一步的集成或者是否有益。有人對此有經驗嗎?什麼是將第三方異步API與Cap'n Proto RPC集成的好方法?

這個問題比我列出的細節稍寬一點..還有其他的API可能會在Cap'n Proto RPC的將來調用,因此任何廣泛的指導方針將不勝感激。

回答

2

不幸的是,這並不那麼簡單。是的,他們都使用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的低級別事件界面非常糟糕,否則您應該能夠以這種方式與它整合。 –