Tareas Asíncronas con Celery

  
15 de Junio de 2014   0  

Las tareas ( tasking) en proyectos complejos, es de suma importancia ya que reduces el esfuerzo de la aplicación en realizar actividades en un solo hilo, pudiendo generar varios que realicen tareas de manera asíncrona. Para estos casos presentamos “CELERY”.

 

Celery es una cola de colas de tareas asincrónicas basado en paso de mensajes distribuidos. Se centra en una operación en tiempo real, pero también admite la programación de las mismas. Las unidades de ejecución, llamadas tareas, se ejecutan simultáneamente en un único o varios servidores de trabajo utilizando el multiprocesamiento, Eventlet o gevent. Las tareas se pueden ejecutar de forma asincrónica (en segundo plano) o síncrona (espere hasta que esté listo).

Instalación.

La instalación de Celery es muy sencillo, y por ser un paquete python, podemos tenerlo en nuestro equipo corriendo la siguiente línea en nuestras terminales:

$ pip install -U Celery
Utilizando Celery con Django.

Asumiendo que tenemos la siguiente estructura de nuestro proyecto en Django:

- proj/
  - proj/__init__.py
  - proj/settings.py
  - proj/urls.py
- manage.py

Necesitamos crear un archivo celery.py que será nuestra instancia en la que se configurarán algunos aspectos básicos, y quedará de la siguiente manera:

- proj/
  - proj/__init__.py
  - proj/settings.py
  - proj/urls.py
  - proj/celery.py
- manage.py

Ahora escribiremos dentro del archivo lo siguiente:

from __future__ import absolute_import

import os

from celery import Celery

from django.conf import settings

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')

app = Celery('proj')

# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

Luego necesitaremos agregar algunas líneas de código en el archivo __init__.py para que se asegure que la aplicación cargará al iniciar o ejecutar el proyecto Django.

proj/proj/__ini__.py

from __future__ import absolute_import

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from celery import app as celery_app

Con las líneas que hemos escrito en el archivo “celery.py”,  Celery será capaz de encontrar todas las tareas asíncronas que se encuentren en cada app creada en Django, identificándolas dentro de los archivos “tasks.py” como podemos ver en este ejemplo:

- app1/
    - app1/tasks.py
    - app1/models.py
- app2/
    - app2/tasks.py
    - app2/models.py

Aquí tenemos 2 apps, app1 y app2 que tienen un archivo llamado “tasks.py” y dentro estarán nuestras tareas asíncronas.

Usando el decorador @shared_task.

El decorador @shared_task realizará la tarea de convertir ciertas funciones en nuestras app reusables en actividades asíncronas, ahora veremos este ejemplo:

from __future__ import absolute_import
from celery import shared_task

@shared_task
def add(x, y):
    return x + y

@shared_task
def mul(x, y):
    return x * y

@shared_task
def xsum(numbers):
    return sum(numbers)

Definimos 3 funciones para ejecutar operaciones matemáticas básicas.

Ejecutando el servicio Celery.

Ahora para poder probar el servicio que hemos levantado en nuestro proyecto Django, bastará con ejecutar lo siguiente en consola:

$ celery -A proj worker -l info

Esto iniciará un servicio test para probar nuestro proyecto que hemos creado. Para el caso de servidores en producción, deberemos leer cómo levantar el servidor celery pero como un daemon o service en el sistema operativo.

Llamando los tasking.

Para el caso de las funciones que hemos definido anteriormente, utilizaremos el def “add” el cual se le pasan 2 variables y devuelve un resultado de la suma de ambas.

result = add.apply_async((2, 2), countdown=3)
result.get()

Lo anterior se interpreta:

1. utilizando “apply_async” especificamos que queremos ejecutar la función de manera asíncronas y que tomará 3 segundos para retornarnos un resultado.

2. El result.get() realiza la operación y podremos ver que el task tardará 3 segundos y retornará el resultado.

Más información sobre las llamadas la podemos encontrar en : http://celery.readthedocs.org/en/latest/userguide/calling.html

Proyectos relacionados.

Flower.

Monitor en tiempo real y un administrador web para Celery.

Jobtastic.

Librería Celery que le permiten correr jobs largos de manera sorprendente, integrando características mejoradas a nuestras actividades en Celery.

¿Quién utiliza Celery?

Celery es utilizado actualmente por miles de proyectos en todo el mundo y es considerado una de las mejores librerías que dan muy buen soporta a las actividades en tiempo real en nuestras plataformas python.

Captura de pantalla 2014-06-15 a la(s) 11.47.07

Si deseas conocer más sobre esta herramienta, te invito a visitar su sitio oficial: http://www.celeryproject.org/



Alex Dzul

FullStack Python / Django Developer. #jslove

Etiquetas

Temas relacionados