2016-03-15 4 views
1

Я применил ограничение скорости API в своем приложении для вызова сторонней службы API, которая ограничивает количество запросов, сделанных для обслуживания за указанный промежуток времени.Может ли один замедленный рабочий рабочий начать следующую работу до окончания текущей работы?

Я прошел регистрацию на работу с задержкой и не смог найти информацию, которую я искал.

Мое дело;

Если есть действительно короткий промежуток времени, скажем, 5 секунд, между двумя отложенными заданиями, что сделает рабочий?

Ожидается, что первое задание закончится, даже если наступило второе время выполнения задания или начнется задание в указанное время?

Если последний, он нарушит мою скорость, ограничивая реализацию, поскольку API разрешает мне только 60 запросов в минуту, и оба задания ограничивают себя 60 запросами в минуту, и в целом оба задания будут пытаться отправить около 120 запросов в минуту.

Заранее благодарим за ура!

ответ

3

Это зависит от количества работников DelayedJob, которые доступны. Потому что свободный работник заберет работу и обработает ее, как только наступит ее время run_at.

Если вам необходимо убедиться, что только на работу проходит в то время, я вижу два простых варианта:

  1. ограничить ваше количество рабочих 1. Или
  2. введите следующую работу в качестве последнего шага обработки.

Это может выглядеть следующим образом:

class Job 
    def process 
    # code for the job ... 

    # enqueue the next job to run in 5 seconds 
    Job.delay(run_at: 5.seconds.from_now).process 
    end 
end 

Третий вариант, который является немного более сложным, играет с named queues. Когда вы помещаете этот вид заданий в специальную именованную очередь, вы можете использовать эту специальную очередь для вычисления времени для следующего задания. Вместо того, чтобы просто епдиеие работу, как это:

Job.delay.process 

Проверьте работу уже существует, например:

queue_name = 'one_at_a_time' 
latest_job = Delayed::Job.where(queue: queue_name).order(:run_at).last 
run_at  = latest_job ? latest_job.run_at + 5.seconds : Time.current 
Job.delay(queue: queue_name, run_at: run_at).process 
+0

Спасибо за быстрый ответ! Я уже уменьшил рабочих до 1, и если я его правильно пойму, этого будет достаточно? Рабочий будет занят работой над первой работой и только начнет работать над вторым, когда закончится первый? «Заменить следующую работу как последний шаг обработки». можете ли вы подробно рассказать об этом?В моих приложениях пользователи - это те, которые планируют задания, поэтому нет способа узнать, когда они планируют свои задания. – whizzkid

+1

Да, сокращение числа работников до 1 будет гарантировать, что за один раз будет работать только одна работа. Я не знал, что пользователи планируют задания в вашем приложении. В этих условиях вторая версия не работает. Но тогда может быть другой вариант. Обновит мой ответ за несколько минут ... – spickermann

+0

Большое спасибо за подробное объяснение, я вижу, что вы там делали в качестве третьего варианта, и это может работать, но для этого потребуется немного другая реализация. Потому что последняя работа не всегда та, которая может противоречить той, которую мы собираемся создать, не так ли? Пользователи могут планировать работу в течение следующего месяца, а также планировать ее на следующий день. Например, мне нужно проверить его на предыдущие и следующие 10 секунд, чтобы увидеть, есть ли какие-либо потенциальные конфликты. Но пока я поеду с единственным рабочим, которого я думаю. – whizzkid

0

И еще один вариант, чтобы запустить один экземпляр рабочего в очереди:

RAILS_ENV=production bin/delayed_job --queue=tracking start

или

RAILS_ENV=production bin/delayed_job --queues=mailers,tasks start

Documentation