我正在创建一个最多显示 9 个费率的搜索页面。在前端,我正在向我的 rails 应用程序发送一个请求,其中包含获取 9 个费率所需的数据。
在我的一个 Rails 控制器中,我爬取了一个网页以获取速率。这可能需要 2 到 15 秒之间的任何时间。
我想在后台运行所有 9 个请求,这样我就可以处理其他进来的请求。例如,用户可以进行搜索并显示建议的结果。
我正在尝试将 concurrent-ruby gem 与 Promises 一起使用。clean_params 变量是发出请求所需的数据数组。最多有 9 个请求数据。
这是我到目前为止所拥有的:
tasks = cleaned_params.map { |request_data|
Concurrent::Promises.future(request_data) { |request_data| api_get_rate(request_data) }
}
# My tasks could still be in the pending state, all_promises is a new promise that will be fulfilled once all fo the inner promises have been fulfilled
all_promises = Concurrent::Promises.zip(*tasks)
# Use all_promises.value! to block - I don't want to render a response until we have the rates.
render json: {:success => true, :status => 200, :rates => all_promises.value! }
现在我看到所有对 api_get_rate 的请求都在启动,但是在我的api_get_rate
函数中,我调用了另一个类中的方法,BetterRateOverride.check_rate
. 当我同步运行相同的代码时,我成功地调用了上述方法,但是当我运行它时,我现在如何设置它,我的代码一旦到达这个调用就会挂起。为什么会这样?
在后台线程中是否不能从另一个类调用方法?承诺是否在后台线程中运行?我读到 Promises 在 ruby 全局线程池中运行。
如果这不是最好的方法,你能引导我走向正确的方向吗?
谢谢你的帮助。
编辑:我认为这可能是我的代码死锁的问题: https ://github.com/rails/rails/issues/26847