Celery Singleton

0.3.1 · active · verified Thu Apr 16

Celery Singleton is a Python library that provides a base class for Celery tasks, ensuring that only one instance of a specific task can be queued or running at any given time. It achieves this by using Redis for distributed locking, leveraging the task's name and arguments to determine uniqueness. The current version is 0.3.1, released in January 2021, and its development appears to be in maintenance with recent activity on its GitHub issues.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a Celery task as a singleton using `celery-singleton`. It shows that subsequent calls to `delay()` with identical arguments will return the `AsyncResult` of the already queued or running task, rather than queuing a new one. Ensure your Celery app is configured with a Redis broker and result backend.

import time
from celery_singleton import Singleton
from celery import Celery
import os

# Assuming a local Redis for Celery broker and result backend
celery_app = Celery(
    'my_app',
    broker=os.environ.get('CELERY_BROKER_URL', 'redis://localhost:6379/0'),
    backend=os.environ.get('CELERY_RESULT_BACKEND', 'redis://localhost:6379/1')
)

@celery_app.task(base=Singleton)
def do_stuff(*args, **kwargs):
    time.sleep(4)
    return 'I just woke up'

if __name__ == '__main__':
    # Example of running tasks
    print('Calling do_stuff(1, 2, 3, a="b") the first time...')
    async_result = do_stuff.delay(1, 2, 3, a='b')
    print(f'First call result ID: {async_result.id}')

    print('Calling do_stuff(1, 2, 3, a="b") the second time (should return existing task)...')
    async_result2 = do_stuff.delay(1, 2, 3, a='b')
    print(f'Second call result ID: {async_result2.id}')

    assert async_result.id == async_result2.id
    print('Assertion successful: Duplicate task call returned the same AsyncResult ID.')

    print(f'Task 1 status: {async_result.status}')
    print(f'Waiting for task 1 to complete...')
    print(f'Task 1 result: {async_result.get()}')

view raw JSON →