0

我正在制作一个我正在尝试优化的数据密集型 Web 应用程序。我听说过分叉和线程,但我不知道它们是否适用于我正在尝试做的事情,如果适用,如何实现它们。我的代码如下所示:

  def search
      @amazon_data=Hash.from_xml(item.retrieve_amazon(params[:sku]))
        unless @amazon_data['results'] == nil
          @amazon_data['results']['item'].size.times do |i|
            @all_books << { :vendor => 'Amazon.com',
                            :price => @amazon_data['results']['item'][i]['price'].to_f,
                            :shipping => @amazon_data['results']['item'][i]['ship'].to_f,
                            :condition => @amazon_data['results']['item'][i]['condition'],
                            :total => @amazon_data['results']['item'][i]['price'].to_f + @amazon_data['results']['item'][i]['ship'].to_f,
                            :availability => 'In Stock',
                            :link_text => 'Go to Amazon.com',
                            :link_url => "http://www.amazon.com/gp/offer-listing/#{params[:isbn]}"
            }
        end
      end
       @ebay_data=Hash.from_xml(Book.retrieve_ebay(params[:sku]))
        unless @ebay_data['results'] == nil
          @ebay_data['results']['item'].size.times do |i|
            @all_books << { :vendor => 'eBay',
                            :price => @ebay_data['results']['item'][i]['price'].to_f,
                            :shipping => @ebay_data['results']['item'][i]['ship'].to_f,
                            :condition => 'Used',
                            :total => @ebay_data['results']['item'][i]['price'].to_f + @ebay_data['results']['item'][i]['ship'].to_f,
                            :availability => 'In Stock',
                            :link_text => 'Go to eBay',
                            :link_url => "http://www.amazon.com/gp/offer-listing/#{params[:sku]}"
            }
        end
    end
  end

所以,基本上我有两个从 eBay 和 Amazon 检索数据并在此处解析的操作。我怎样才能让这两个动作同时运行?fork 或 thread 与我想要完成的事情有什么关系吗?


这将 API 时间减少了一半,但我不知道如何返回结果。在返回 API 结果之前加载后续视图......但是,它正在返回数据。当我编码时

puts @all_books  

线程内的结果显示在控制台中。但是,在线程之外,不会返回结果。

def search
    Thread.new do
      @amazon_data=Hash.from_xml(item.retrieve_amazon(params[:sku]))
        unless @amazon_data['results'] == nil
          @amazon_data['results']['item'].size.times do |i|
            @all_books << { :vendor => 'Amazon.com',
                            :price => @amazon_data['results']['item'][i]['price'].to_f,
                            :shipping => @amazon_data['results']['item'][i]['ship'].to_f,
                            :condition => @amazon_data['results']['item'][i]['condition'],
                            :total => @amazon_data['results']['item'][i]['price'].to_f + @amazon_data['results']['item'][i]['ship'].to_f,
                            :availability => 'In Stock',
                            :link_text => 'Go to Amazon.com',
                            :link_url => "http://www.amazon.com/gp/offer-listing/#{params[:isbn]}"
            }
        end
      end
     end
    Thread.new do
       @ebay_data=Hash.from_xml(Book.retrieve_ebay(params[:sku]))
        unless @ebay_data['results'] == nil
          @ebay_data['results']['item'].size.times do |i|
            @all_books << { :vendor => 'eBay',
                            :price => @ebay_data['results']['item'][i]['price'].to_f,
                            :shipping => @ebay_data['results']['item'][i]['ship'].to_f,
                            :condition => 'Used',
                            :total => @ebay_data['results']['item'][i]['price'].to_f + @ebay_data['results']['item'][i]['ship'].to_f,
                            :availability => 'In Stock',
                            :link_text => 'Go to eBay',
                            :link_url => "http://www.amazon.com/gp/offer-listing/#{params[:sku]}"
            }
        end
      end
    end
  end

我在正确的轨道上吗?如何从线程内返回结果?是该变量只能在线程内访问,还是问题在于程序在返回结果之前进行了处理?


不幸的是,该应用程序需要实时用户输入来查询 API。返回的数据必须是新鲜的,因为它与市场中的产品定价有关……例如,用户将输入一个 SKU,并且程序将使用该信息向适用的网站(在这种情况下为亚马逊和 eBay)发出请求.) 目前它向亚马逊发出请求,解析数据,格式化,然后转到 eBay,解析数据,并格式化。然后将格式化的数据显示在视图中。

我的想法是,如果我可以同时进行这些 API 调用(在不同的线程上?),它将节省 Web 服务端的时间,因为所需要做的就是解析返回的数据并正确格式化它。(我也可以加快速度......)

4

3 回答 3

1

是的,我仍然认为在这种情况下使用作业调度程序会更好。像这样的操作可以执行的绝对最快速度是两个 API 请求中较慢的 --- 并且您无法保证网络延迟、远程 API 上的负载等。另一方面,您将必须实现一些 Javascript代码定期轮询以检测作业完成并通知用户结果。

此外,ruby 1.8 中的线程行为有时会有点奇怪,尤其是在规模上,所以要小心。

于 2009-08-20T20:54:16.280 回答
0

没有更多信息很难说,但我怀疑等待 API 响应是花费大部分时间的地方。

尝试不同的方法,其中 API 响应的请求和处理在与 Web 服务进程不同的进程中处理。前端代码可能需要定期轮询结果,并将操作结果注入页面。但胜利是整个请求没有得到支持,等待亚马逊和 Ebay 做他们的事情。

有几个插件可以提供帮助,delayed_job是一个很好的起点。

于 2009-08-20T05:56:48.140 回答
0

您还可以查看 EventMachine,它允许您以非阻塞方式执行出站网络调用。如果你能将第一个结果返回给用户,通过ajax得到最终结果,用户交互会感觉更快。

这类似于 Kayak.com 的实时航班搜索。

您还可以考虑缓存结果,快速将结果返回给用户,然后通过 ajax 填充更新的结果(您异步加载的)。(您必须为此找出正确的用户界面,也许只是将“流行”结果放在首屏,然后将最新更新放在首屏或其他东西)

*EventMachine 很复杂

于 2011-12-14T22:13:56.953 回答