2013-12-19 57 views
0

簡而言之,用戶向我的Web服務發出請求,並且我必須將請求轉發給X個不同的API。我應該並行執行,因此我爲此創建了線程,並且第一個線程使用有效的響應來回答,我應該殺死其餘線程並立即將答案提供給我的客戶。如何等待線程通知而不是加入所有線程?

在Ruby中一個常見的模式,是創建多個線程像

threads << Thread.new {} 
threads.each { |t| t.join } 

我已經有其中的邏輯是這樣的:

results = [] 
threads = [] 
valid_answer = nil 

1.upto(10) do |i| 
    threads = Thread.new do 
    sleep(rand(60)) 
    results << i 
    end 
end 

threads.each { |t| t.join } 

valid_answer = results.detect { |r| r > 7 } 

但在像以前的代碼,我阻止該進程,直到所有線程完成。這可能是因爲一個線程會在1秒內回答一個有效的答案(所以在這一點上,我應該殺死所有其他線程並回報該答案),但是相反,我加入所有線程並且不會使太有意義了。

有沒有一種方法讓紅寶石睡覺或等到一個線程回答,檢查該回答是否有效,然後再次阻塞/休眠,直到所有線程完成或者直到其中一個線程返回有效響應?


編輯:

應該並行進行。當我收到客戶的請求時,我可以將請求轉發給5家不同的公司。

每家公司可能會有超過60秒的時間(瘋狂但真實的醫療保健業務)。

只要其中一家公司回覆,我必須檢查回覆(如果它是一個真實的回覆或錯誤),如果它是一個真實的迴應,我應該殺死所有其他線程,並立即回答客戶(沒有理由讓他等待60秒,如果其中一個請求讓我回到超時)。此外,沒有理由讓它在一個循環中(就像我在一個循環中這樣做,最糟糕的情況是5 x 60秒)。

+0

你的問題聽起來更是一個循環的線程。等待正確的事情並開始另一個請求是一個循環,你會做什麼並行? – devanand

+0

我剛剛做了一個編輯,解釋了我遇到的問題以及我在不同線程上需要所有這一切的原因。 – rorra

回答

1

也許通過讓主線程睡覺?

def do_stuff 
    threads = [] 
    valid_answer = nil 

    1.upto(10) do |i| 
    threads << Thread.new do 
     sleep(rand(3)) 
     valid_answer ||= i if i > 7 
    end 
    end 

    sleep 0.1 while valid_answer.nil? 
    threads.each { |t| t.kill if t.alive? } 
    valid_answer 
end 

編輯:有一個與喚醒一個更好的辦法,也:

def do_stuff 
    threads = [] 
    answer = nil 

    1.upto(10) do |i| 
    threads << Thread.new do 
     sleep(rand(3)) 
     answer ||= i and Thread.main.wakeup if i > 7 
    end 
    end 

    sleep 
    threads.each { |t| t.kill if t.alive? } 
    answer 
end 
+0

很酷,這將工作,我正在尋找一個系統調用來阻止進程,直到一個線程通知我它準備好或類似的東西,但你的代碼是務實的,它會解決我的問題:)我也應該確保一個的線程是至少運行或返回一個錯誤,但它的一個小的更新,thx再次:) – rorra

+0

我懷疑有一種方法可以用throw/catch塊來做到這一點。 –

+1

更好的方法是使用'wakeup'(請參閱我的編輯)。 –