Задание не выполняется APScheduler BackgroundScheduler

У меня есть приложение Django, которое я запускаю на Docker. Я пытаюсь запустить планировщик APScheduler при запуске контейнера Docker.

Я создал планировщик и просто добавил к нему задание, которое я назвал test1, и оно отправляет электронное письмо на мой адрес.

Это скрипт Python, который запускается, когда я запускаю контейнер.

from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.schedulers.background import BackgroundScheduler

#scheduler = BlockingScheduler()
scheduler = BackgroundScheduler()

def test1():
    ... (code to send email)

scheduler.add_job(test1, 'interval', seconds = 20)
scheduler.start()

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

  • BlockingScheduler: планировщик работает, я получаю электронное письмо каждые 20 секунд. Однако я не могу получить доступ к приложению. Я предполагаю, что это нормально из-за самой природы BlockingScheduler.

Screenshot1

screenshot2

  • BackgroundScheduler: нет проблем с доступом к приложению. Тем не менее, я не получаю по электронной почте.

Поскольку электронные письма были отправлены в одном из двух случаев, я полагаю, что проблема не связана ни с Django, ни с Docker, а связана только с APScheduler. Я провел исследование, но не смог понять, почему BackgroundScheduler не работает, как в прочитанных мною учебниках, разработчик настроил планировщик так же, как и я.

Любая помощь будет высоко ценится, спасибо!

ОБНОВЛЕНИЕ 1

Я попробовал две следующие вещи, обе заставили BackgroundScheduler вести себя как BlockingScheduler (это не то, что я хочу)

1) Установка опции демона в False при инициализации экземпляра планировщика:

scheduler = BackgroundScheduler(daemon = False)

2) "Попытка поддержать основной поток", как объяснено в этих:

как-д-я-график-ан-интервальная работа-с apscheduler

apscheduler-внутри-а-класс-объект

Я добавил это сразу после scheduler.starts():

while True:
    time.sleep(1)
scheduler.shutdown()

ОБНОВЛЕНИЕ 2

Когда я пытаюсь настроить BackgroundScheduler в одном файле Python (вне контекста приложения), он работает очень хорошо:

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.schedulers.blocking import BlockingScheduler


def test1():
    print('issou')

scheduler = BackgroundScheduler()
scheduler.start()
scheduler.add_job(test1, 'interval', seconds=5)

print('yatangaki')

Сначала печатается "ятангаки", а затем "каждые пять секунд", так что все выглядит хорошо.

ОБНОВЛЕНИЕ 3

Теперь я попытался запустить планировщик в приложении Django, с которым я работал локально python manage.py runserver, без использования Docker.

Он работает отлично: письма отправляются, и я могу получить доступ к основному виду приложения.

Примечание: BackgroundScheduler запускается функцией под названием start_test1, В этом приложении я бегу start_test1 в файле верхнего уровня urls.py. В другом приложении, которое я запускаю с помощью Docker, которое я хочу использовать в конце концов, - start_test1 запускается в скрипте Python, который сам запускается в файле.sh, который я запускаю с помощью команды CMD Docker.

2 ответа

Решение

Похоже, это было все о том, где запустить планировщик и добавить работу.

В том, что я сделал изначально (поместив код в файл.sh), BackgroundScheduler запустился, но скрипт Python сразу же завершился после запуска, так как у него не было блокирующего поведения и sh. Файл на самом деле не был частью приложения (он используется Dockerfile, а не приложением).

В итоге я нашел решение здесь: execute-code-when-django-запуска-единожды. В моем приложении не было файла apps.py, поэтому я создал его и следовал инструкциям в этой теме.

Теперь работает нормально.

У меня похожая проблема, но она решилась только тем, что не блокировал воркер:

      # working:
def worker():

    phone_elm = ....
    thread = threading.Thread(target=work, args=(phone_elm,))
    thread.start()

# not working:
def worker():
    phone_elm = ....
    work(phone_elm)

scheduler2 = BackgroundScheduler(timezone="Asia/Kolkata")
# schedule scanning running of folder's running file
scheduler2.add_job(worker, 'interval', seconds=15,  max_instances=5000)

scheduler1.start()

Я имею в виду, что не работает, это то, что после 10 ~ раз, когда он сработал, он был остановлен без причины, снова запущен после того, как 1 из 10 остановился (работа завершилась)

Это тоже часть Django, но понятно, что старт не завершается...

Другие вопросы по тегам