web-dev-qa-db-fra.com

Celery CRITICAL / MainProcess] Erreur irrécupérable: AttributeError ("l'objet 'float' n'a pas d'attribut 'items'",)

J'ai exécuté une application flask avec un travailleur de céleri et redis dans trois conteneurs docker séparés sans aucun problème.

Voici comment je le démarre:

celery worker -A app.controller.engine.celery -l info --concurrency=2 --pool eventlet

Le céleri commence bien:

 -------------- celery@a828bd5b0089 v4.2.1 (windowlicker)
---- **** -----
--- * ***  * -- Linux-4.9.93-linuxkit-aufs-x86_64-with 2018-11-15 16:06:59
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app:         app.controller.engine:0x7f8ba4eb70b8
- ** ---------- .> transport:   redis://redis:6379/0
- ** ---------- .> results:     redis://redis:6379/1
- *** --- * --- .> concurrency: 2 (eventlet)
-- ******* ---- .> task events: ON
--- ***** -----
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery


[tasks]
  . app.controller.engine.do

INFO:engineio:Server initialized for eventlet.
INFO:engineio:Server initialized for threading.
[2018-11-15 15:44:34,301: INFO/MainProcess] Connected to redis://redis:6379/0
[2018-11-15 15:44:34,321: INFO/MainProcess] mingle: searching for neighbors
[2018-11-15 15:44:35,358: INFO/MainProcess] mingle: all alone
[2018-11-15 15:44:35,396: INFO/MainProcess] pidbox: Connected to redis://redis:6379/0.
[2018-11-15 15:44:35,415: INFO/MainProcess] celery@12af03844cd0 ready.

Mais au démarrage d'une tâche, elle se bloque soudainement:

[2018-11-15 15:02:03,224: CRITICAL/MainProcess] Unrecoverable error: AttributeError("'float' object has no attribute 'items'",)
Traceback (most recent call last):
  File "/app/env/lib/python3.6/site-packages/celery/worker/worker.py", line 205, in start
    self.blueprint.start(self)
  File "/app/env/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start
    step.start(parent)
  File "/app/env/lib/python3.6/site-packages/celery/bootsteps.py", line 369, in start
    return self.obj.start()
  File "/app/env/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 317, in start
    blueprint.start(self)
  File "/app/env/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start
    step.start(parent)
  File "/app/env/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 593, in start
    c.loop(*c.loop_args())
  File "/app/env/lib/python3.6/site-packages/celery/worker/loops.py", line 121, in synloop
    connection.drain_events(timeout=2.0)
  File "/app/env/lib/python3.6/site-packages/kombu/connection.py", line 301, in drain_events
    return self.transport.drain_events(self.connection, **kwargs)
  File "/app/env/lib/python3.6/site-packages/kombu/transport/virtual/base.py", line 963, in drain_events
    get(self._deliver, timeout=timeout)
  File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 359, in get
    ret = self.handle_event(fileno, event)
  File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 341, in handle_event
    return self.on_readable(fileno), self
  File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 337, in on_readable
    chan.handlers[type]()
  File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 724, in _brpop_read
    self.connection._deliver(loads(bytes_to_str(item)), dest)
  File "/app/env/lib/python3.6/site-packages/kombu/transport/virtual/base.py", line 983, in _deliver
    callback(message)
  File "/app/env/lib/python3.6/site-packages/kombu/transport/virtual/base.py", line 632, in _callback
    self.qos.append(message, message.delivery_tag)
  File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 149, in append
    pipe.zadd(self.unacked_index_key, time(), delivery_tag) \
  File "/app/env/lib/python3.6/site-packages/redis/client.py", line 2263, in zadd
    for pair in iteritems(mapping):
  File "/app/env/lib/python3.6/site-packages/redis/_compat.py", line 123, in iteritems
    return iter(x.items())
AttributeError: 'float' object has no attribute 'items'

Je ne vois aucune référence à mon code dans la stacktrace.

Voici la méthode de tâche:

@celery.task()
def do(module_name, json_input):
    logger.info('____ Running _________________________')
    logger.info('testing ***********************')
    #modules.run(module_name, json_input)

J'ai commenté l'appel à mon code actuel juste pour vérifier que je ne l'ai pas gâché avec le code de mes modules .. mais il plante quand même.

Quelqu'un a une idée de ce qui pourrait mal se passer ou comment le déboguer correctement?

Merci beaucoup

11
magnoz

Le problème était que le conteneur my celery a téléchargé une nouvelle version du package redis avec pip au moment de la construction, éventuellement avec un bogue ou un changement grave qui se bloque lorsque céleri essaie de l'utiliser lors de la connexion à redis. Cette nouvelle bibliothèque redis est la 3.0.0 et elle est sortie aujourd'hui.

Pour résoudre le problème, vous devez spécifier la version précédente dans le fichier requirements.txt (qui est 2.10.6).

Et en fait, la spécification des versions de package dans le fichier requirements.txt est une bonne pratique qui évite ce type de problèmes.

19
magnoz

J'ai rencontré ce même problème aujourd'hui. j'espère que cela sera résolu sous peu dans une mise à jour de Celery. Je suis également revenu à une version précédente.

2
Rocky Holms

Pas encore assez de représentants pour un commentaire:

Ce problème est suivi par les gens du céleri dans: https://github.com/celery/celery/issues/5175

Menant à ce PR: https://github.com/celery/celery/pull/5176

Qui a été fusionné et rétabli. Parce qu'un autre correctif a atterri. Je ne sais pas si cela a résolu le problème. Ce n'est plus pertinent pour moi.

2
Sander Beekhuis

Pour tous ceux qui utilisent le docker-airflow, j'ai utilisé le folk de puckel/docker-airflow Il suffit de modifier le dockerfile en ajoutant

   && pip install 'redis>=2.10.5,<3'\

remplacer celery[redis] avec seulement celery, en ajoutant du céleri dans le module intégré Apache-airflow, c'est-à-dire

  && pip install Apache-airflow[crypto,celery,postgres,Hive,jdbc,mysql]==$AIRFLOW_VERSION 

Mise à jour: Ils ont également changé récemment le fichier docker-airflow dockerfile pour corriger ce bogue, voir ici

1
Kevin Li