Celery: cómo asegurarse de ejecutar de a una sola tarea a la vez. Ensuring a task is only executed one at a time
Celery
En el ecosistema python, se suele utilizar Celery para correr tareas de manera asíncrona. Celery no solo permite tomar tareas de una cola (queue) y ejecutarlas asincronamente sino que también soporta que las tareas puedan ser ejectudas con periodicidad. Celery soporta nativamente varios framework: Django, Flask, Pyramid, Tornado y algunos más.
Para usarlo es muy facil, solo hace falta instalarlo
pip install -U Celery
y elegir un broker que usualmente pueden ser RabbitMQ o Redis. La documentación para instalar y configurar con alguno de estas opciones es sencilla y la pueden seguir aquí.
Mutex: como bloquear el acceso a un recurso para evitar simultaneas modficaciones con celery
Muchas veces cuando ejecutamos tareas periódicas (periodic tasks) no queremos que algunas se ejecuten en paralelo porque 1) quizás una o más tareas quieren modificar algo (puede ser la base de datos) al mismo tiempo o 2) varias tareas quieren realizar algo de manera repetida o duplicada por ejemplo, pero hay muchos mas ejemplos. Por esto es muy común usar algun especie de bloqueo para que solo una tarea puede ejecutarse a la vez.
Asi lo recomienda hacer la documentacion oficial de celery: Ensuring a task is only executed one at a time pero el codigo que Celery proporciona usa un context manager y la memcache.
Primer decorador: https://gist.github.com/eduzen/6db2abbb9b9fcc16683f3d7f3bfebfba
Fuentes:
http://loose-bits.com/2010/10/distributed-task-locking-in-celery.html