BOB Docs
APIFeatures

Background Tasks

BOB employs two types of tasks:

  1. Dynamic Tasks: Triggered during program execution, such as sending an email upon user registration.
  2. Periodic Tasks: Scheduled to run at regular intervals, like a cron job (e.g., every Monday at 10:00 AM).

Dynamic Tasks

Dynamic tasks can be invoked from anywhere in the code. These tasks are decorated with @shared_task. Due to limitations in Celery (as of this documentation's writing), asynchronous methods cannot be directly decorated.

Example:

@shared_task
def send_email(to, subject, html, text, attachments=None) -> bool:
    """
    Sends an email using the MailSender class.
    """
    # Use async_to_sync to run asynchronous code in Celery
    return async_to_sync(mail_sender.send_email)(to, subject, html, text, attachments)

To maintain organization, dynamic tasks should be stored in files located at / <app_name> /tasks/<task_name>.

Running Dynamic Tasks

Dynamic tasks only require the Celery worker process:

celery -A core.celery worker --loglevel=info

Periodic Tasks

Periodic tasks are scheduled based on a predefined timetable registered in the Celery configuration file (core/celery.py). You must also include the paths to all files containing periodic tasks.

Example Configuration

app.conf.update(
    include=['_template.tasks.example']
)
 
app.conf.beat_schedule = {
    'run-every-minute': {
        'task': '_template.tasks.example.hello',
        'args': ("",),
        'schedule': crontab(minute='*/1'),  # Run every minute
    },
}

The schedule uses cron syntax. For assistance in writing cron expressions, refer to Crontab Guru.

Defining a Periodic Task

Periodic tasks must also be defined as synchronous methods, using asyncio internally.

@app.task
def hello(argument="world"):
    """
    Example of a periodic task declaration. Use asyncio inside the method to handle async operations.
    """
    logger.info(f"Hello {argument} before.")
    asyncio.run(sleep(1))
    logger.info(f"Hello {argument} after.")

Running Periodic Tasks

To execute periodic tasks, start the Celery Beat process alongside the worker:

celery -A core.celery beat

Celery Beat monitors all registered schedules and dispatches tasks to the Celery worker at the appropriate time.

Key Notes

  • Use async_to_sync for asynchronous methods in dynamic tasks.
  • Periodic tasks require both Celery Beat and the Celery worker to be running.
  • Tasks should be well-organized in app-specific directories for better maintainability.

This setup ensures efficient handling of time-consuming operations and periodic processes, improving overall application performance and reliability.

On this page