Сельдерей выполняет задачи в порядке их вызова (во время выполнения) - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть задача, состоящая из подзадач в цепочке. Как я могу убедиться, что второй вызов этой задачи не запускается до завершения первого?

@shared_task
def task(user):
    res = chain(subtask_1.s(), # each subtask takes ~1 hour
            subtask_2.s(),
            subtask_3.s())

    return res.apply_async()

django представление теперь может вызывать вызов этой задачи:

# user A visits page that triggers task
task.delay(userA)
# 10 seconds later, while task() is still executing, user B visits page
task.delay(userB) 

Это приводит к тому, что задачи гоняются друг за другом, а не выполняются в последовательном порядке. Например, когда работник закончил с subtask_1() первого задания, он начинает работать над subtask_1() второго задания вместо subtask_2() и subtask_3() первого.

Есть ли способ избежать этого? Я предполагаю, что проблема заключается в порядке добавления подзадач в очередь.

  1. Я уже установил работника --concurreny=1, но это все равно не меняет порядок, который он потребляет из очереди.
  2. Официальные документы (книга заданий) предлагает решение, которое я не понимаю и, к сожалению, не работает для меня.
  3. Возможно, включите механизм блокировки в задача, после цепочки, с взломом while not res.ready(): sleep(1)?

1 Ответ

0 голосов
/ 19 февраля 2020

Вы можете подождать, пока первое задание завершится sh, а затем выполнить второе, как показано ниже.

res = task.delay(userA)
res.get() # will block until finished
task.delay(userB)

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

@shared_task
def task(_, user): signature takes one extra argument
    # skipped

и

from celery.canvas import chain


chain(task.s(None, userA), task.s(userB))()
...