Ruby Ruby http 库没有 non-blocking 的 API 版本?

ibachue · 2013年09月27日 · 最后由 iBachue 回复于 2013年09月28日 · 4400 次阅读

Hi all, 在做搜索引擎那个项目的时候,我突然意识到查询时 Controller 里对 Solr 有多次请求,而那几次请求都是阻塞式的,也就是说在上一次请求没结束期间下一次请求没法发起,整个程序都会进入阻塞状态。 受到上次讲的 em-synchrony 的影响,我并不打算立即改用传统的 Thread,而是找找有没有 non-blocking 的办法 然后我就试图查询 rsolr(我用的 solr 的 gem)有没有 non-blocking 的 api,没找到,然后试图自己写,看了下 rsolr 用的 http 的库是 net/http,查了下这个库的 non-blocking api,竟然也没找到。网上甚至说可以用 delay job。 求助大家,Ruby http 库没有 non-blocking 的 api 版本?没有的话,除了 delay job,还有什么快一点的办法么?谢谢!

使用 event machine 啊。em-http-request 或者 em-synchrony

在新 thread 里做也不会 block 的

faraday 支持多个 adapter,包括 EventMachine。可以试试。比如这个例子 https://github.com/lostisland/faraday/wiki/Parallel-requests

#1 楼 @zhangyuan 这个其实我知道啦,当年第一次看到的时候还想不通,发请求干嘛还要 EventMachine,直接用 non blocking 不就行了,直到我发现 Ruby 根本没这个功能。。但有个问题是调它的 API 是不是一定要在 EventMachine.run 里?我这可是 Rails 的 Controller 啊。不能让 EM 一次次循环的啊。 #2 楼 @luikore 先找找 non blocking 嘛,因为感觉效率总是比 Thread 高。 #3 楼 @zhangyuan 这个我倒还真的不知道,谢谢了。

#4 楼 @iBachue 如果在 Rails 的一次请求里,调用了外部的 N 个请求。这 N 个请求,就可以放在一个 EventMachine.run ,然后确定所有 N 个请求都结束再 EM.stop。faraday 的 in_parallel 也是这样的。

以前一直觉得 Fiber 可以做这个,但是不知道怎么实现。

#7 楼 @zgm fiber 和 event machine 结合起来。请求 IO 后,立即放弃 CPU 控制权;等到 IO 就绪后,再获得 CPU 控制权。也就是 em-synchrony

#4 楼 @iBachue 不用线程和 EM, 就只能放到队列里了,更麻烦... 或者试试 celluloid

#8 楼 @zhangyuan 这个我知道,但是如果不用 EM, 也就是不使用其他 IO 模型的情况下,纯 Fiber 行吗?

#5 楼 @kevinxu 这个太底层了。。

#6 楼 @zhangyuan 好吧 我关键是怕效率低。。

#12 楼 @iBachue 嗯。好吧。我没仔细看你的贴。。

@iBachue 不是 Ruby 没有异步 IO, 实际上在底层,Ruby 实现的 read, write 都是异步 IO, 否则会影响到 Ruby 解释器本身。

我找到一个库,可能适合你:https://github.com/typhoeus/typhoeus

#14 楼 @lyfi2003 有什么例子或者资料可以看看吗?

@zgm readme 可以了吧

#14 楼 @lyfi2003 嗯 这个前面在玩 Faraday 的时候顺便玩过了。但是话说 Ruby 提供给我们的库确实还是同步的啊,为何不提供异步的呢?

ibachue 有没有这样一种 HTTP 请求方案? 提及了此话题。 04月03日 10:57
需要 登录 后方可回复, 如果你还没有账号请 注册新账号