【发布时间】:2019-11-11 21:34:12
【问题描述】:
因此,我正在构建一个调用第三方 API 的网站,该 API 可能需要 20 秒到 30 分钟才能返回结果。但是我不能提前知道这个持续时间,所以需要经常轮询它以检查工作是否完成(返回“COMPLETE”和结果)或没有(返回“IN_PROGRESS”)。此外,该 API 可能会同时被多个用户多次调用。
所以我创建了一个 Sidekiq 工作程序,它每 5 秒检查一次 API,直到它收到“COMPLETE”,然后才结束。但我读到 Sidekiq 应该只做短暂的工作,我正在努力弄清楚我应该如何去做。此外,我一直在尝试寻找答案,但我怀疑我不知道要查找的内容。
我确信有一种方法可以告诉我的工作人员调用 API 一次,如果结果是“IN_PROGRESS”结束,但确保另一个工作人员将执行另一个 API 调用来检查,依此类推直到结果为“COMPLETE”。
另外,我想这对于更好地分配负载也很方便,以防许多用户要求使用所述 API,因为更少的工人可以做更多的这种短期工作。
这是我的工人,我希望能澄清我现在在做什么:
class ThingProgressWorker
include Sidekiq::Worker
def perform(id)
@thing = Thing.find(id)
@thing_api_call = ThingAPICall.new // This uses the ruby library of the API
completed = false
while completed == false
result = @thing_api_call.get_result( { thing_job_name: @thing.job_name })
if !result.include? "COMPLETED"
completed = false
sleep 5
else
completed = true
@thing.status = "completed"
@thing.save
break
end
end
end
end
因此,如果 API 从“IN_PROGRESS”到“COMPLETED”需要 10 分钟,则该工作人员将忙那么长时间,我认为根本不建议这样做。
我已经考虑了几个小时了,我想不出我应该如何让每个 API 调用它自己的工作,而不让工作人员忙于 API 完成。
到目前为止,我想到的唯一解决方案是让一个主工作器为每个 API 调用调用另一个工作器,但是只要 API 需要发送结果,我仍然会有一个工作器忙碌。
如果有任何帮助或指示,我将不胜感激!
提前致谢
【问题讨论】:
标签: ruby-on-rails sidekiq