2013-04-17 155 views
7

我拉着多個請求(其拉一次一個),我想知道如果有一種方法引入請求都在同一時間,如果我有這樣的事情:Ruby on Rails同時多個HTTP請求?

client = Instagram.client(:access_token => session[:access_token]) 
@user = client.user 
@recent_media_items = client.user_recent_media 

@lv = client.tag_recent_media('lv', options = {:count => 60}) 
@lv1 = client.tag_recent_media('lv1', options = {:count => 60}) 
@lv2 = client.tag_recent_media('lv2', options = {:count => 60}) 
@lv3 = client.tag_recent_media('lv3', options = {:count => 60}) 

每個lv發出請求到client。我想知道是否有辦法這樣做,因此它可以一次完成請求(一起),而不是一個完成請求,然後繼續下一個請求,依此類推...

謝謝!

回答

10

是的!對於概念驗證,請嘗試

require 'thread' 

client = Instagram.client(:access_token => session[:access_token]) 
@user = client.user 
@recent_media_items = client.user_recent_media 

threads = [] 
threads << Thread.new { @lv = client.tag_recent_media('lv', options = {:count => 60}) } 
threads << Thread.new { @lv1 = client.tag_recent_media('lv1', options = {:count => 60}) } 
threads << Thread.new { @lv2 = client.tag_recent_media('lv2', options = {:count => 60}) } 
threads << Thread.new { @lv3 = client.tag_recent_media('lv3', options = {:count => 60}) } 
threads.each(&:join) # this waits for all the threads to finish before proceeding 
puts [@lv, @lv1, @lv2, @lv3] 

實際上,您需要在線程中設置一些錯誤處理和重試設置。此外,你可能會遇到Instagram的寶石線程安全問題。如果您正在大規模地處理數百或數千個請求,則可能需要嘗試使用併發HTTP客戶機(如Typhoeus)或一個已公開的HTTP客戶機(如EM-HTTP-Request)。對於這些,你將不得不手動實現在Instagram寶石中的tag_recent_media方法。

+0

聖莫利,我認爲這一個工作!嗯,我猜這應該是好的,如果我只是在生產權這樣做? – hellomello

+2

是的,但你可能會想要一些錯誤處理。如果在其中一個線程中發生異常,'threads.each(&:join)'會引發異常。從那裏,你可以使用[Thread#status](http://ruby-doc.org/core-2.0/Thread.html#method-i-status)來檢查哪些線程有異常。你也可以在線程塊中使用[retryable](https://github.com/nfedyashev/retryable)來處理網絡錯誤。 –

+0

是不是你的例子在每個'Thread.new {...}'前面缺少'threads <<'? –