简而言之,用户向我的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秒内回复并返回有效答案(所以此时我应该杀死所有其他线程并回复该答案),但相反,我加入所有线程并且不会太有道理了。
有没有办法在ruby中睡觉或等到一个线程回答,检查答案是否有效,然后再次阻塞/休眠直到所有线程都完成,或者直到其中一个线程给我一个有效的响应?
编辑:
应该并行完成。当我收到客户的请求时,我可以将请求转发给5家不同的公司。
每家公司的最长可达60秒(疯狂但真实的医疗保健业务)。
一旦这些公司中的一个回答,我必须检查响应(如果它是真实的响应或错误),如果它是真实的响应,我应该杀死所有其他线程并立即回答客户(没有理由让他等待60秒,如果其中一个请求让我恢复超时)。此外,没有理由在循环中进行它(就像我在循环中这样做,在最坏的情况下它会像5 x 60秒)。
答案 0 :(得分: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