django-celery-results icon indicating copy to clipboard operation
django-celery-results copied to clipboard

Unable to Catch Signals for TaskResult Updates with RESULT_BACKEND=django-db

Open urzbs opened this issue 8 months ago • 2 comments

Problem Description:

When using RESULT_BACKEND = django-db on remote Celery workers, Django fails to catch signals on the TaskResult object when workers update their results. This prevents the expected behavior of triggering actions upon task result updates.

Details:

The issue arises because Celery workers are bypassing Django ORM and directly updating the database using PostgreSQL queries. Consequently, signals like post_save on TaskResult instances are not triggered as expected.

Code Example:

Using a signal to create the PENDING Task: Related Issue

@receiver(post_save, sender=TaskResult)
def task_result_saved(sender, instance, created, **kwargs):
    if created:
        logger.info(f'TaskResult created: {instance.task_id} with status {instance.status}')
    else:
        # This branch will not be triggered due to direct database updates
        logger.info(f'TaskResult updated: {instance.task_id} with status {instance.status}')

Current Workaround:

A Cronjob executes a manage.py command periodically to check for state changes, which is inefficient and not ideal.

Other Attempts:

Utilizing Celery Signals: Attempted to use celery task_success signal in signals.py, but it did not function as expected (did not function at all).

from celery.signals import task_success

@task_success.connect
def task_success_handler(sender=None, result=None, **kwargs):
   logger.info(f'Task {sender.name} succeeded with result {result}')

Another idea I had is to create a REST endpoint based on TaskResult, that enables workers to update the model without using PSQL direct queries, but that would make RESULT_BACKEND=django-db pretty much obsolete.


I was hoping someone has a solution for this which is already something built-in.


urzbs avatar Jun 13 '24 12:06 urzbs