Ruby(Sinatra?)的并发Web请求?

时间:2010-04-26 13:24:32

标签: ruby concurrency httpwebrequest sinatra

我有一个Sinatra应用程序,基本上需要一些输入值,然后找到与来自外部服务(如Flickr,Twitter等)的那些值匹配的数据。

例如:

输入:“Chattanooga Choo Choo” 会在Chattanooga Choo Choo的Flickr上找到图像,也可以在Twitter上找到推文等。

现在我有类似的东西:

@images = Flickr::...find...images..

@tweets = Twitter::...find...tweets...

@results << @images

@results << @tweets

所以我的问题是,Ruby是否有一种有效的方式同时运行这些请求?而不是在推文结束前等待图片完成。

5 个答案:

答案 0 :(得分:2)

线程可以工作,但它是一个粗糙的工具。你可以尝试这样的事情:

flickr_thread = Thread.start do
  @flickr_result = ... # make the Flickr request
end

twitter_thread = Thread.start do
  @twitter_result = ... # make the Twitter request
end

# this makes the main thread wait for the other two threads
# before continuing with its execution
flickr_thread.join
twitter_thread.join

# now both @flickr_result and @twitter_result have
# their values (unless an error occurred)

您必须对代码进行修改,并添加正确的错误检测。我现在不记得在线程块内部声明实例变量时,除非在外部显式声明,否则局部变量不会。

我不认为这是一个优雅的解决方案,但我认为它有效,并且它不是太复杂。在这种情况下,幸运的是除了连接之外不需要锁定或同步,因此代码读取得非常好。

如果您做了很多这样的事情,也许像EventMachine这样的工具(尤其是em-http-request子项目)可能对您有所帮助。它可能使在更高级别编码更容易。线程很难正确。

答案 1 :(得分:2)

您可以考虑进行客户端更改以使用异步Ajax请求来独立获取每种类型(图像,推特)。服务器线程(无论如何其中之一)的问题在于,如果一个服务挂起,整个请求将等待该线程完成。使用Ajax,您可以加载图像部分,推特部分等,如果一个挂起,其他人仍然会显示他们的结果;最终你可以超时请求并在该部分显示失败的鲸鱼或其他东西。

答案 2 :(得分:1)

是的,为什么不是线程?

据我了解。一旦用户提交表单,您想要并行处理所有请求吗?你可以有一个多线程控制器(Ruby线程支持非常好。)你收到一个请求,然后你并行执行外部查询服务然后你回答一个响应或在客户端你发送一个ajax帖子服务和处理它(也许每个外部服务都有你自己的控制器/动作?)

答案 3 :(得分:1)

考虑使用YQL。它支持子查询,因此您可以使用单个(客户端,偶数)调用来提取所需的所有内容,该调用只会向您呈现需要呈现的内容。那里已经有很多教程了。

答案 4 :(得分:1)

http://github.com/pauldix/typhoeus

并行/并发http请求