代码之家  ›  专栏  ›  技术社区  ›  cbmeeks

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

  •  1
  • cbmeeks  · 技术社区  · 15 年前

    我有一个Sinatra应用程序,它基本上获取一些输入值,然后从Flickr、Twitter等外部服务中找到与这些值匹配的数据。

    例如:

    输入:“chattanooga choo choo” 会在Flickr上的chattanooga-choo-choo和twitter等网站上找到图片。

    现在我有一些东西:

    @images = Flickr::...find...images..
    
    @tweets = Twitter::...find...tweets...
    
    @results << @images
    
    @results << @tweets
    

    所以我的问题是,Ruby中是否有一种有效的方法可以同时运行这些请求?而不是等待图像在tweets完成之前完成。

    5 回复  |  直到 10 年前
        1
  •  2
  •   Theo    15 年前

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

    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 子项目)可以帮助你,如果你做很多这样的事情。它可能使更高级别的代码编写更容易。线程很难纠正。

        2
  •  2
  •   Brian Deterling    15 年前

    您可以考虑进行客户端更改,以使用异步Ajax请求独立获取每种类型(image、twitter)。服务器线程(无论如何都是其中一个)的问题是,如果一个服务挂起,则整个请求挂起,等待该线程完成。使用Ajax,您可以加载图像部分、Twitter部分等,如果其中一个挂起,其他部分仍将显示其结果;最终,您可以超时请求并只显示失败的鲸鱼或该部分中的某些内容。

        3
  •  1
  •   VP.    15 年前

    是的,为什么不线程?

    据我所知。一旦用户提交表单,您希望并行处理所有请求,对吗?您可以拥有一个多线程控制器(Ruby线程支持非常好)。在这里,您接收到一个请求,然后并行执行外部查询服务,然后在一个响应中回复,或者在客户端,您为每个服务发送一个Ajax日志并处理它(可能每个外部服务都有自己的控制器/actio)。)?

        4
  •  1
  •   Tyler Gillies    14 年前

    http://github.com/pauldix/typhoeus

    并行/并发HTTP请求

        5
  •  1
  •   agf    13 年前

    考虑为此使用YQL。它支持子查询,这样您就可以通过一个(客户端,甚至是)调用来提取所需的一切,而这个调用只输出需要呈现的JSON。已经有很多教程了。