Bonjour à tous,

[merci à tous ceux qui auront la patience de lire tout mon mail. Ma
gratitude vous enveloppe châleureusement en ces humides journées
d'hiver]

j'ai du code Django 1.6.8 où si j'active `transaction.commit()` autour
d'un simple bloc, une erreur se produit *systématiquement* quelque part
près de la BDD. 

Mais je ne sais pas *quelle erreur*, car elle n'est pas remontée. Et
bien évidement, quand elle se produit et occasionne la fermeture de la
connexion à la base, tout le process plante à cause d'un
"InterfaceError: connection already closed". 

Dans mon cas, c'est dans un worker celery avec gevent. Donc tout le
worker s'arrête, alors qu'il est censé gérer 100 tâches à la seconde, et
envoyer d'autres tâches en suivant à d'autres workers qui se retrouvent
au chomage, et forcément le gouvernement nous crée des platasses de lois
pour créer des jobs de merde, et… Ah non, c'est pas ici que je dois dire
ça. Au moins, la machine ne chauffe plus, mais autant dire que c'est pas
vraiment ce que je souhaite.

J'ai cherché un bon moment sur Gogogle, qui m'a donné finalement ça : 

https://code.djangoproject.com/ticket/21202 

C'était le bug parfait, presque exactement mon problème, mais Aymeric a
corrigé ce truc depuis plus d'un an, et tous mes petits pypis sont à
jour. J'ai le sentiment qu'il reste [peut-être au moins] un cas dans
lequel le problème se produit encore [à peu près pareil], puisque si je
retire le `transaction.atomic()`, je n'ai plus le "InterfaceError". De
temps j'ai un crash de type IntegrityError, justement celui que la doc
dit d'encadrer comme ça:

    try:
        with transaction.atomic():
            do_some_stuff()
    except IntegrityError:
        handle_exception() 

Le truc c'est que quand je l'encadre pour le cas sur 10k où il se
produit, ben plus rien ne s'exécute et la connexion à la base est fermée
pour une raison inconnue (celle qui est la cause du pourquoi je vous
écris un mail de 5Ko, vous suivez ?).

J'ai réussi à isoler un endroit où ça pète : 

https://github.com/1flow/1flow/blob/develop/oneflow/core/models/reldb/feed/rssatom.py#L581

Si je rajoute un "with transaction.atomic():" entre le try: et le
"new_article.add_original_data(…)", ben tout le worker s'arrête avec une
stacktrace comme http://dev.1flow.net/1flow/1flow/group/48838/ . 

Mais je suis obligé d'attendre que celery essaie de tracer le résultat
de la tâche pour qu'il se rende comte que la connexion a été fermée
avant, et du coup plus personne ne sait pourquoi ça a eu lieu. atomic()
a bouffé l'exception.

Bref, je suis un peu dég'. Tout le bienfait de `transaction.atomic()`
part en fumée, et de temps en temps (une fois toutes les 1000 ou 10k
transactions), j'ai une tâche qui plante pour une vraie raison, et qui
forcément me plante mon worker puisque je n'ai pas d'atomic() pour me
protéger le call « comme il faut le faire que c'est écrit dans la doc,
mais RTFM, bordel™ ».

Alors avant d'ouvrir un bug en anglais qui sera wontfix parce que je
n'arriverai pas à reproduire mon problème en 10 lignes, je serai preneur
d'une idée, une piste, un truc à essayer, un retour d'expérience, qui
pourrait me lancer sur la voie de quelque chose que j'aurais oublié. 

Si vous aimez les projets libres et que vous avez un peu de temps, ça
peut se faire autour d'une bière (ou d'un rouge, ou d'un jus de fruit,
ou d'un café) si vous êtes dans la région de bordeaux…

PS: une fois sur 1k ou 10K ça peut paraître peu, mais sur
http://1flow.io/ c'est environ toutes les 9h… Et comme on ne peut pas
encore redémarrer les workers de l'intérieur (cf.
http://stackoverflow.com/q/14447322/654755) j'en suis réduit à
redémarrer mes workers toutes les 6h automatiquement pendant les phases
où je ne pas veiller au grain, ce qui occasionne quelques tâches qui
partent à la trappe, et ainsi de suite. Bref, pendant ce temps, sentry,
lui, est bien nourri.

Allez a+ et merci à tous. Même si c'est pour envoyer une vanne, ça me
fera plaisir.

--
Olivier

_______________________________________________
django mailing list
[email protected]
http://lists.afpy.org/mailman/listinfo/django

Répondre à