En nuestra aplicación, tenemos una aplicación Rails que realiza una llamada API a una API Flask. Luego, la API programa una tarea y estamos usando Redis como la cola.
@app.route("/api/article", methods=["POST"]) def api_article(): app.logger.info("[route] /api/article") . . res_id = celery.send_task("tasks.text_stats", args=[article], kwargs={}).id @celery.task(name="tasks.text_stats") def text_stats(article): logger.info("text_stats")Lo que estoy pensando es que si la base de datos de Redis es accesible tanto para Rails como para Flask, podríamos simplemente crear la tarea directamente en Redis, que luego sería recogida por el trabajador de Celery.
Preguntas:
Para resolver este problema, simplemente podemos inspeccionar en Redis cómo Celery empuja las tareas a la LIST .
Esta es una tarea de apio de ejemplo que Celery envió a Redis:
{'body': 'W1siYjVmNDhmNDQtOWZiZS00MjdiLWE3NDMtZjc3MDgwMDQzN2ZiIl0sIHt9LCB7ImNhbGxiYWNrcyI6IG51bGwsICJlcnJiYWNrcyI6IG51bGwsICJjaGFpbiI6IG51bGwsICJjaG9yZCI6IG51bGx9XQ==', 'content-encoding': 'utf-8', 'content-type': 'application/json', 'headers': {'lang': 'py', 'task': 'my_python_function', 'id': '64148470-0dde-4e31-ab63-09c98955d24f', 'shadow': None, 'eta': None, 'expires': None, 'group': None, 'retries': 0, 'timelimit': [None, None], 'root_id': '64148470-0dde-4e31-ab63-09c98955d24f', 'parent_id': None, 'argsrepr': "('my_string_argument_one', 'my_string_argument_2',)", 'kwargsrepr': '{}', 'origin': 'gen73965@mac.local'}, 'properties': {'correlation_id': '64148470-0dde-4e31-ab63-09c98955d24f', 'reply_to': '1a223e51-77c3-37d3-a870-baae15b3b741', 'delivery_mode': 2, 'delivery_info': {'exchange': '', 'routing_key': 'celery'}, 'priority': 0, 'body_encoding': 'base64', 'delivery_tag': 'f840868a-18c9-4b1f-bc95-5ff95666ca21'}} Las claves más importantes de lo anterior son headers.task , que es el nombre de la función de Python que debe llamar, así como headers.argsrepr y headers.kwargsrepr , que es una tupla/dict en cadena que representa los args/kwargs que debe pasar a la función.
Hay otras claves en el dictado anterior como dict (la cola de apio), un par de ID (puede generarlas automáticamente), eta , que podría usar para personalizar el comportamiento.
Una vez que comprendamos cómo interactúa el apio con Redis, de forma similar a este ejemplo , simplemente puede ejecutar LPUSH con el cliente Redis de Ruby con el dictado de Python en dict .
La parte más preocupante, en realidad, es que celery espera que el elemento LIST en cadena esté en formato dict , que tiene algunas diferencias con to_json de Ruby. Deberá hacer esa parte manualmente (como convertir booleans a python bool )