APScheduler (with Redis)

Tip

Before you use APScheduler, Check Celery has been removed from your project

Install Dramatiq (using Redis).

Add the following to requirements/base.txt:

APScheduler==

Tip

See Requirements for the current version.

Create a management command to start the scheduler:

project/management/commands/start_scheduler.py

Tip

22/05/2020, I don’t think The scheduler has access to the Dramatiq queue, so I am creating proxy functions to send the message send the message to Dramatiq (see schedule_process_mail below as an example).

Note

22/05/2020, I have started using max_instances=1 and replace_existing=True to try and stop multiple processes from running at the same time.

This command should create the scheduler and then add jobs e.g:

import logging

from django.core.management.base import BaseCommand
from pytz import utc

from base.scheduler_utils import create_scheduler

logger = logging.getLogger(__name__)

class Command(BaseCommand):
    """Start APScheduler scheduler."""

    help = "Start APScheduler..."

    def handle(self, *args, **options):
        self.stdout.write("{}...".format(self.help))
        scheduler = create_scheduler()
        self.stdout.write("Scheduler, adding jobs...")
        # payment_intent_fulfillment
        scheduler.add_job(
            "checkout.tasks:schedule_payment_intent_fulfillment",
            "interval",
            minutes=15,
            id="schedule_payment_intent_fulfillment",
            max_instances=1,
            replace_existing=True,
        )
        # email_task_reminders
        scheduler.add_job(
            "flow.tasks:schedule_email_task_reminders",
            "cron",
            day_of_week="mon-fri",
            hour=5,
            minute=30,
            id="schedule_email_task_reminders",
            max_instances=1,
            replace_existing=True,
        )
        # process_mail
        scheduler.add_job(
            "mail.tasks:schedule_process_mail",
            "interval",
            minutes=60,
            id="schedule_process_mail",
            max_instances=1,
            replace_existing=True,
        )
        self.stdout.write("Scheduler, starting...")
        scheduler.start()
        self.stdout.write("{} - Complete".format(self.help))

# from #mail/tasks.py'
def schedule_process_mail():
    """APScheduler would like to process the email.

    .. note:: The scheduler doesn't have access to the Dramatiq queue, so send
              the message from here.

    https://www.kbsoftware.co.uk/crm/ticket/5001/

    """
    process_mail.send()

Check Celery has been removed from your project

To remove Celery from your project:

# 1. remove the following line from 'project/__init__.py'
from .celery import app as celery_app
# 2. delete 'project/celery.py'
# 3. Remove Celery from settings files...
# 4. Remove ``celery`` from requirements.