Задания Celery не выполняются на heroku (приложение python/django)

У меня есть приложение Django с некоторыми запланированными задачами. Приложение развернуто на Heroku с Redis. Задание выполняется, если его вызвать синхронно в консоли или локально, когда у меня также запущены redis и celery. Однако запланированные задания не выполняются на Heroku.

Моя задача:

@shared_task(name="send_emails")
def send_emails():
.....

celery.py:

from __future__ import absolute_import, unicode_literals

import os
from celery import Celery
from celery.schedules import crontab

# set the default Django settings module for the 'celery' program.
# this is also used in manage.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_app.settings')

# Get the base REDIS URL, default to redis' default
BASE_REDIS_URL = os.environ.get('REDIS_URL', 'redis://localhost:6379')

app = Celery('my_app')

# Using a string here means the worker don't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()

app.conf.broker_url = BASE_REDIS_URL

# this allows you to schedule items in the Django admin.
app.conf.beat_scheduler = 'django_celery_beat.schedulers.DatabaseScheduler'

# These are the scheduled jobs
app.conf.beat_schedule = {
    'send_emails_crontab': {
        'task': 'send_emails',
        'schedule': crontab(hour=9, minute=0),
        'args': (),
    }
}

В Procfile: worker: celery -A my_app worker --beat -S django -l info

Я запустил рабочего с помощью heroku ps:scale worker=1 -a my-app. Я могу видеть зарегистрированные задачи под [tasks] в журналах рабочего. Однако запланированные задачи не выполняются в назначенное время. Вызов send_emails.delay() в производственной консоли работает. Как заставить рабочего остаться в живых и/или запустить задание в запланированное время?

У меня есть обходной путь с использованием команды и планировщика heroku. Просто не уверен, что это лучший способ сделать это.

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

Делюсь с вами любыми идеями.

  1. Запустите консоль и получите время даты Dyno. Dyno использует локальное время США.

  2. DynoFree спит каждые 30 минут и только 450 часов в месяц.

  3. Попробуйте заменить сельдерей на BackgroundScheduler, вам нужно добавить скрипт clock.py как:

     from myapp import myfunction
     from datetime import datetime
     from apscheduler.schedulers.background import BackgroundScheduler
     from apscheduler.schedulers.blocking import BlockingScheduler
     from time import monotonic, sleep, ctime
     import os
    
     sched = BlockingScheduler()
     hour = int(os.environ.get("SEARCH_HOUR"))
     minutes = int(os.environ.get("SEARCH_MINUTES"))
    
     @sched.scheduled_job('cron', day_of_week='mon-sun', hour=hour, minute = minutes)
     def scheduled_job():
         print('This job: Execute myfunction every at ', hour, ':', minutes)        
         #My function
         myfunction()
    
     sched.start(
    

)

В Procfile:

clock: python clock.py

и запустить:

heroku ps:scale clock=1 --app thenameapp

Приветствуется.

Вернуться на верх