2013-08-07 3 views
2

J'ai une application Web Flask et certaines tâches sont de longue durée (> 1 minute). Je voudrais les décharger de flask (bloquant le serveur Web, etc.) et les déplacer dans des tâches externes. J'ai installé Celery et suis capable d'exécuter ces tâches depuis Flask. Bien.Celery + RabbitMQ Résultats Backend + WebSockets?

Pour avertir les utilisateurs lorsque la tâche est terminée et retourner les résultats, j'ai voulu utiliser des sockets Web. C'est là que ça devient difficile.

J'ai un serveur websocket gevent sur lequel mon client se connecte. Quand je lance la tâche de céleri, je passe l'identifiant de session du client de sorte que lorsque je reçois mes résultats, je sais à qui ils appartiennent.

Maintenant, j'ai besoin du serveur websocket pour savoir quand ces tâches sont effectuées, regarder les résultats et les envoyer à la connexion appropriée.

Comment? C'est là que je suis complètement perdu. Je peux écouter des événements céleri avec celery.events.EventListener.capture, mais cela bloque mon serveur websocket donc je ne peux pas avoir plusieurs connexions!

Comment puis-je écouter des événements de céleri sans blocage?

Une idée consiste à faire la demande sur le socket Web, puis lancer la tâche de céleri à partir de mon serveur websocket. Cela résoudrait le problème de notification (juste utilisé des événements de céleri), mais je suis toujours curieux de savoir ma question initiale où la demande a été faite à mon serveur flacon standard.

Répondre

1

Vous avez besoin que votre application Flask ne bloque pas lors de l'appel de capture. Une solution consiste à exécuter flask avec gevent ou eventlet afin que votre processus gère la requête de manière asynchrone et que le blocage des appels ne bloque pas le processus.

Il y a des tonnes d'exemples à ce sujet, pour en nommer un: https://gist.github.com/lrvick/1185629