Итак, я создаю веб-сайт, который вызывает сторонний API, который может занять от 20 секунд до 30 минут, чтобы вернуть результат. Но я не могу знать эту продолжительность заранее, поэтому нужно часто опрашивать ее, чтобы проверить, выполнена ли работа (возвращает «COMPLETE» и результат) или нет (возвращает «IN_PROGRESS»). Кроме того, этот API может вызываться много раз от многих пользователей одновременно.
Поэтому я создал воркер Sidekiq, который проверяет API каждые 5 секунд, пока не получит «COMPLETE», и только тогда он завершается. Но я читал, что Sidekiq должен выполнять только кратковременную работу, и я изо всех сил пытаюсь понять, как мне это сделать. Также я пытался найти ответ, но подозреваю, что не знаю слов, чтобы найти то, что ищу.
Я уверен, что есть способ сказать своим работникам вызвать API один раз, и если результат будет "IN_PROGRESS", конец, но убедитесь, что другой работник выполнит еще один вызов API для проверки, и так далее и так далее, пока не будет получен результат. завершено".
Кроме того, я думаю, это также удобно для лучшего распределения нагрузки в случае, если многие пользователи потребуют использования указанного 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», этот рабочий процесс будет занят в течение этого времени, что, по моему мнению, вообще не рекомендуется.
Я думал об этом уже несколько часов и не могу придумать, как мне сделать, чтобы каждый API вызывал свою собственную работу, не заставляя работника быть занятым, пока API не будет выполнен.
Единственное решение, о котором я думал до сих пор, — это наличие основного рабочего процесса, который вызывает другого рабочего процесса для каждого вызова API, но тогда у меня все еще будет рабочий процесс, пока API отправляет результат.
Буду признателен за любую помощь или указания!
заранее спасибо
else
14.11.2019