在我做的一些web开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖于另一个的结果。我希望事情能够在后台运行。我发现concurrent-ruby library似乎工作得很好。通过将它混合到你创建的类中,这个类的方法有异步版本,在后台线程上运行,这导致我编写了如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法,该方法发送HTTP请求:
def index
op1_result = FirstAsyncWorker.new.async.work
op2_result = SecondAsyncWorker.new.async.work
render text: results(op1_result, op2_result)
end
然而,控制器会在action方法执行结束时隐式地呈现一个响应,因此响应会在op1_result和op2_result得到值之前发送,发送到浏览器的唯一内容是“#"。
到目前为止,我的解决方案是使用Ruby线程。我编写的代码如下:
def index
op1_result = nil
op2_result = nil
op1 = Thread.new do
op1_result = get_request_without_concurrent
end
op2 = Thread.new do
op2_result = get_request_without_concurrent
end
# Wait for the two operations to finish
op1.join
op2.join
render text: results(op1_result, op2_result)
end
我不使用互斥锁是因为两个线程不访问相同的内存。但是我想知道这是否是最好的方法。有没有更好的方法来使用concurrent-ruby库,或者其他更适合这种情况的库?
1条答案
按热度按时间jc3wubiy1#
在对concurrent-ruby库做了更多的研究之后,我最终回答了自己的问题。
Future
s最终就是我所追求的!简单地说,它们在后台线程中执行一个代码块,并试图访问Future的计算值,这会阻塞主线程,直到后台线程完成其工作。包含
render
的行阻塞,直到两个异步任务都完成,此时result
可以开始运行。