我正在做一个数据密集型的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检索数据,并在这里解析它。如何使这两种操作同时运行?叉子或线与我想要完成的事情有什么关系吗?
这将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。返回的数据必须是新鲜的,因为它与marketplaces...For实例中的产品定价有关,用户将输入SKU,程序将根据这些信息向适用的站点(这里是亚马逊和eBay )提出请求。目前,它向Amazon发出请求,解析数据,格式化数据,然后转到eBay,解析数据,并对其进行格式化。然后在视图中显示格式化的数据。
我的想法是,如果我能够同时(在不同的线程上)进行这些API调用?它将节省web服务端的时间,因为所需的只是解析返回的数据并正确格式化它。(我也许也能加快……)
发布于 2009-08-20 20:54:16
是啊,我还是觉得在这种情况下用作业调度器会更好。这样的操作所能执行的绝对最快的是两个API请求中速度较慢的--您无法保证网络延迟、远程API上的加载等等。另一方面,您必须实现一些Javascript代码来定期轮询,以检测作业完成并通知用户结果。
另外,ruby1.8中的线程行为有时会有些古怪,特别是在规模上,所以要小心。
发布于 2009-08-20 05:56:48
如果没有更多的信息,很难说,但我怀疑,等待API响应是大多数时间花费的地方。
尝试一种不同的方法,其中API响应的请求和处理在与web服务流程不同的过程中处理。前端代码可能必须定期轮询结果,并将操作结果注入页面。但胜利在于,等待亚马逊( Amazon )和易趣( Ebay )完成他们的任务后,整个请求都不会被备份。
有几个插件可以帮助,工作是一个很好的起点。
发布于 2011-12-14 22:13:56
您还可以查看EventMachine,它允许您以非阻塞的方式执行出站网络调用。如果您可以将第一个结果返回给用户,即通过ajax获得最终结果,那么用户交互将感觉更快。
这与Kayak.com在实时飞行搜索中所做的类似。
您还可以考虑缓存结果,快速将结果返回给用户,然后通过ajax填充更新的结果(加载异步)。(你必须找出正确的UI,也许只是把“流行”的结果放在折叠上,然后再把最新的更新放在折叠下面什么的)
*事件机是复杂的
https://stackoverflow.com/questions/1304113
复制相似问题