Projet

Général

Profil

Development #52221

uwsgi, spooler, connexion db

Ajouté par Frédéric Péters il y a environ 3 ans. Mis à jour il y a environ 3 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Version cible:
-
Début:
19 mars 2021
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Il y aurait à assurer dans les jobs exécutés depuis le spooler qu'il y a une connexion db fonctionnelle.

De loin ce que j'imaginerais c'est un décorateur qui permettrait

@spool
@ensure_db
def refresh_statistics_list(args):
    ...

Et cet @ensure_db assurerait ouverture/fermeture de la connexion et tant qu'à faire pourrait aussi avoir la partie set_tenant().

(mais peu importe la solution)


Fichiers


Demandes liées

Lié à Publik Installation Développeur - Development #50525: Permettre l'utilisation de uwsgi (en plus du serveur django) Fermé25 janvier 2021

Actions

Révisions associées

Révision b9f1cbe2 (diff)
Ajouté par Benjamin Dauvergne il y a environ 3 ans

spooler: add decorator to simplify use of spooler (#52221)

The new tenantspool decorator keep the function signature using pickle
serialization (through the pass_arguments=True parameter of @spool),
setup and teardown Django db connections and restore the current tenant.

Historique

#1

Mis à jour par Frédéric Péters il y a environ 3 ans

  • Description mis à jour (diff)
#2

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

  • Assigné à mis à Benjamin Dauvergne
#3

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

C'est beaucoup de code un peu gratuit pour deux fonctions, j'avoue, mais ça pourrait aller dans hobo ensuite. Je n'ai rien trouvé de mieux que de simuler l'interface de uwsgi pour tester un poil.

#4

Mis à jour par Thomas Noël il y a environ 3 ans

Pour tenter en vrai, je lance Combo ainsi :

COMBO_SETTINGS_FILE=/home/$USER/.config/publik/settings/combo/settings.py uwsgi --chdir . --module=combo.wsgi:application --env DJANGO_SETTINGS_MODULE=combo.settings --master --process 3 --pidfile=/tmp/project-master.pid --http=127.0.0.1:8004 --spooler-python-import=combo.utils.spooler --spooler /var/lib/combo/spooler/

et ça crashe aussitôt :

...
spawned uWSGI master process (pid: 122209)
spawned the uWSGI spooler on dir /var/lib/combo/spooler with pid 122210
[spooler /var/lib/combo/spooler pid: 122210] managing request uwsgi_spoolfile_on_clevo_121595_4_1206669464_1616195736_720877 ...
Traceback (most recent call last):
  File "/home/thomas/envs/publik-env-py3/lib/python3.9/site-packages/uwsgidecorators.py", line 61, in manage_spool_request
    f = spooler_functions[vars['ud_spool_func']]
KeyError: 'refresh_statistics_list'
[spooler /var/lib/combo/spooler pid: 122210] managing request uwsgi_spoolfile_on_clevo_121595_5_951226711_1616195745_89058 ...
Traceback (most recent call last):
  File "/home/thomas/envs/publik-env-py3/lib/python3.9/site-packages/uwsgidecorators.py", line 61, in manage_spool_request
    f = spooler_functions[vars['ud_spool_func']]
KeyError: 'refresh_statistics_list'
spawned uWSGI worker 1 (pid: 122211, cores: 1)
spawned uWSGI worker 2 (pid: 122212, cores: 1)
spawned uWSGI worker 3 (pid: 122213, cores: 1)
spawned uWSGI http 1 (pid: 122214)

Ceci étant, juste avant j'avais testé l'idée du close_old_connections avec un mini-patch-à-la-noix :

 @spool
 def refresh_statistics_list(args):
+    close_old_connections()
     if args.get('domain'):
         # multitenant installation
         set_connection(args['domain'])

     update_available_statistics()
+    close_old_connections()
Pour voir que ça marche :
  • je lance Combo comme indiqué ci-dessus
  • je vais sur le manage d'une page avec une cellule Graphe : un spooler joue un job refresh_statistics_list
  • je coupe postgresql.. je le relance
  • je retourne sur le manage de la page : pas de soucis, un spooler rejoue refresh_statistics_list sans planter

... alors que sans les close_old_connections la dernière action provoque toujours le "django.db.utils.InterfaceError: connection already closed"

#5

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

Thomas Noël a écrit :

et ça crashe aussitôt :

[...]

Merci d'avoir testé, je n'ai juste aucun environnement pour tester localement.

#6

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

Thomas: et avec ce patch ? (j'ai ajouté un wraps(func) pour maintenir func.__name__ avec les divers décorateurs, car c'est la référence utilisé par uwsgidecorators dans son registre et dans ses messages).

#7

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

Benjamin Dauvergne a écrit :

Thomas: et avec ce patch ? (j'ai ajouté un wraps(func) pour maintenir func.__name__ avec les divers décorateurs, car c'est la référence utilisé par uwsgidecorators dans son registre et dans ses messages).

En réfléchissant ça doit venir du fait que tu avais déjà des actions "spoolés" dans le répertoire.

#8

Mis à jour par Thomas Noël il y a environ 3 ans

Benjamin Dauvergne a écrit :

En réfléchissant ça doit venir du fait que tu avais déjà des actions "spoolés" dans le répertoire.

Effectivement.

Mais en nettoyant le spooler, autre pépin :

[spooler] written 110 bytes to file /var/lib/combo/spooler/uwsgi_spoolfile_on_clevo_29326_1_329803100_1616257053_70863
[spooler /var/lib/combo/spooler pid: 29323] managing request uwsgi_spoolfile_on_clevo_29326_1_329803100_1616257053_70863 ...
Traceback (most recent call last):
  File "/home/thomas/envs/publik-env-py3/lib/python3.9/site-packages/uwsgidecorators.py", line 64, in manage_spool_request
    ret = f(*vars['args'], **vars['kwargs'])
  File "./combo/utils/spooler.py", line 33, in f
  File "./combo/utils/spooler.py", line 62, in spooler_func
TypeError: refresh_statistics_data() missing 1 required positional argument: 'cell_pk'

... et en ajoutant le patch de la note 6 :

[spooler] written 132 bytes to file /var/lib/combo/spooler/uwsgi_spoolfile_on_clevo_29553_1_1748013046_1616257157_123839
[spooler /var/lib/combo/spooler pid: 29550] managing request uwsgi_spoolfile_on_clevo_29553_1_1748013046_1616257157_123839 ...
Traceback (most recent call last):
  File "/home/thomas/envs/publik-env-py3/lib/python3.9/site-packages/uwsgidecorators.py", line 64, in manage_spool_request
    ret = f(*vars['args'], **vars['kwargs'])
  File "./combo/utils/spooler.py", line 34, in f
  File "./combo/utils/spooler.py", line 64, in spooler_func
  File "./combo/utils/spooler.py", line 83, in refresh_statistics_list
ModuleNotFoundError: No module named 'combo.apps.dataviz.utils'
#9

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

Thomas Noël a écrit :

Benjamin Dauvergne a écrit :

En réfléchissant ça doit venir du fait que tu avais déjà des actions "spoolés" dans le répertoire.

Effectivement.

Mais en nettoyant le spooler, autre pépin :

[...]

Pareil la signature à changer, je vais ajouter un try/except pour dégager ça.

... et en ajoutant le patch de la note 6 :

[...]

Là c'est simplement que tu lances mal uwsgi, j'ai refait ta ligne de commande pour que ça marche :

COMBO_SETTINGS_FILE=/home/$USER/.config/publik/settings/combo/settings.py uwsgi --plugins python3 --chdir /tmp -H /home/bdauvergne/envs/publik-env-py3/ --module=combo.wsgi:application --env DJANGO_SETTINGS_MODULE=combo.settings --master --process 3 --pidfile=/tmp/project-master.pid --http-socket=127.0.0.1:8004 --spooler-python-import=combo.utils.spooler --spooler /var/lib/combo/spooler/

Sans le -H /home/bdauvergne/envs/publik-env-py3/ tu ne charges pas combo au bon endroit je pense; aussi chez moi sans --plugins python3 et --http-socket au lieu de --http ça ne marche pas mais j'ai le uwsgi de testing.

Et là ça tourne :

[spooler] written 132 bytes to file /var/lib/combo/spooler/uwsgi_spoolfile_on_revestel_414499_1_1795967721_1616264134_805499
[spooler /var/lib/combo/spooler pid: 414496] managing request uwsgi_spoolfile_on_revestel_414499_1_1795967721_1616264134_805499 ...

Branche à jour.

#10

Mis à jour par Thomas Noël il y a environ 3 ans

Benjamin Dauvergne a écrit :

Là c'est simplement que tu lances mal uwsgi

Tu as tout à fait raison, my bad, désolé. Avec le -H posant bien le virtualenv, ça me semble bien fonctionner : même après un stop/start de postgresql le spooler ne joue plus dans une connexion psql cassée.

Ensuite ma relecture : le code dans la branche me semble bon mais je cache pas que je n'ai pas encore tout compris ;) Si qqun d'autre peu relire aussi (idéalement ça serait bien d'envoyer ça en recette le plus tôt possible).

#12

Mis à jour par Thomas Noël il y a environ 3 ans

  • Statut changé de Solution proposée à Solution validée
#13

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

  • Statut changé de Solution validée à Résolu (à déployer)
commit b9f1cbe2f5613732b44b85143c558e80e01cf3fe
Author: Benjamin Dauvergne <bdauvergne@entrouvert.com>
Date:   Fri Mar 19 23:30:29 2021 +0100

    spooler: add decorator to simplify use of spooler (#52221)

    The new tenantspool decorator keep the function signature using pickle
    serialization (through the pass_arguments=True parameter of @spool),
    setup and teardown Django db connections and restore the current tenant.
#14

Mis à jour par Frédéric Péters il y a environ 3 ans

  • Statut changé de Résolu (à déployer) à Solution déployée
#15

Mis à jour par Emmanuel Cazenave il y a environ 3 ans

  • Lié à Development #50525: Permettre l'utilisation de uwsgi (en plus du serveur django) ajouté

Formats disponibles : Atom PDF