Celery n'acknowledge pas les tâches s'il est éteint trop vite

a marqué ce sujet comme résolu.

Bonjour,

Dans le cadre d’un projet utilisant Celery, j’aurais aimé tester l’exécution d’une tâche. Je sais que la documentation conseille d’utiliser du mocking, mais n’utilisant pas le client officiel je voudrais vérifier pour un test particulier que tout se déroule bien. Pour cela j’ai mis en place une tâche très simple qui reçoit en paramètres le nom d’une socket Unix et un message à écrire dessus : la tâche ouvre une connexion sur la socket, écrit le message et clôt la connexion.

Au sein des tests, le worker Celery est lancé à l’aide d’un subprocess : je l’instancie avant d’envoyer la tâche, lui transmets un SIGTERM une fois le message reçu sur ma socket puis j’attends qu’il se termine proprement. Tout se passe correctement au niveau des test : le message est bien reçu, correspond à ce qui était attendu et le worker s’arrête.

Cependant, j’ai constaté qu’une fois les tests terminés, un message restait présent dans la queue RabbitMQ, comme s’il n’y avait jamais d’acknowledge pour la tâche. C’est ce que j’ai confirmé en regardant l’interface graphique RabbitMQ : un « Deliver » apparaît bien suite à l’exécution de la tâche mais pas d’« Acknowledge ». Cela me semble étrange puisqu’utilisant la configuration par défaut, l'acknowledge devrait avoir lieu avant même l’exécution.

Continuant de chercher le problème, j’ai remarqué que si j’ajoutais un sleep d’une fraction de seconde juste avant d’envoyer le SIGTERM au worker, lacknowledge avait bien lieu. J’ai tenté d’inspecter les exécutions avec et sans sleep à l’aide de strace dont voici les deux résultats.

La seule différence notable que je remarque est que dans le cas du sleep, le worker a le temps d’entamer une nouvelle communication avec le broker. Il reçoit un EAGAIN lors d’un recvfrom et transmets une trame "\1\0\1\0\0\0\r\0<\0P\0\0\0\0\0\0\0\1\0\316". Serait-ce l'acknowledge ? Pourquoi surviendrait-il aussi tard ?

Je vous donne aussi les paramètres avec lesquels j’instancie le worker Celery : celery worker --app tests.functional.tasks.app --concurrency 1 --pool solo --without-heartbeat. Le without-heartbeat est simplement là pour amoindrir la différence entre les exécutions avec/sans sleep, car sans le paramètre il y avait aussi une trame heartbeat qui apparaissant en plus avec le sleep.

Merci.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte