Projet

Général

Profil

Development #50017

utiliser le spooler uwsgi pour l'exécution des jobs

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

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

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Comme ça a été fait dans #48407 pour w.c.s.; ça aurait notamment comme avantage d'éviter un délai de max 5 minutes avant l'exécution.


Fichiers


Demandes liées

Lié à Passerelle - Bug #50864: cron errorRejeté04 février 2021

Actions
Lié à Passerelle - Bug #50862: /etc/cron.hourly/passerelle: Exec format errorFermé04 février 2021

Actions

Révisions associées

Révision d53ce49a (diff)
Ajouté par Lauréline Guérin il y a environ 3 ans

jobs: use uwsgi spooler to run jobs (#50017)

Historique

#1

Mis à jour par Lauréline Guérin il y a plus de 3 ans

  • Assigné à mis à Lauréline Guérin
#2

Mis à jour par Lauréline Guérin il y a plus de 3 ans

à discuter

je pense qu'il manque quelque chose dans le spooler pour passer le domain:

    subprocess.run([
        settings.PASSERELLE_MANAGE_COMMAND,
        'runjob',
        '--job-id', args['job_id']
    ])

mais je ne vois pas d'exemple dans le code

à la différence de wcs qui lance des jobs pendant le rendering de la réponse via un middleware, je me suis dit qu'on pouvait se placer dans le add_job:

    def add_job(self, method_name, natural_id=None, after_timestamp=None, **kwargs):
        resource_type = ContentType.objects.get_for_model(self)
        job = Job(resource_type=resource_type,
                  resource_pk=self.pk,
                  method_name=method_name,
                  natural_id=natural_id,
                  parameters=kwargs)
        job.set_after_timestamp(after_timestamp)
        job.save()
+       job.run(spool=True)
        return job

mais je me demande si ça ne va pas poser des pb de transaction (genre le job n'est pas encore en DB, et pourtant on l'envoie au spooler)

#3

Mis à jour par Benjamin Dauvergne il y a plus de 3 ans

Utiliser transaction.on_commit(lambda: job.run(spool=True)) ? Si on est dans une transaction ça attendra qu'elle commit, sinon ça lancera le job tout de suite.

PS: on a le même souci avec les logs en base qui disparaissent si jamais on est dans une transaction qui avorte (le cas à ma connaissance n'est pas arrivé, vu qu'on utilise très peu les transactions dans les connecteurs, mais comment en être sûr...).

#4

Mis à jour par Lauréline Guérin il y a plus de 3 ans

on_commit ajouté (j'ai testé avec et sans, les deux fonctionnent, mais dans un env de prod avec plus de mouvements probablement que sans on_commit on aurait des pb de transaction pas commitées au moment où le spooler prend le job)

j'ai testé en local en mode uwsgi, ça a l'air de tourner.

j'ai laissé la possibilité à la commande cron de traiter les jobs (pour les envs sans uwsgi), tout en supprimant la ligne qui va bien de la crontab.

#5

Mis à jour par Benjamin Dauvergne il y a plus de 3 ans

Si un job fait raise SkipJob dans le runjob lancé par le spooler, quand sera-t-il ré-exécuté vu qu'il n'y a plus de cron ? comment est géré set_after_timestamp() dans ce cas ?

runjob ne lock pas la ligne de job, est-ce que le cron et le spooler ne vont pas se marcher sur les pieds ?

À mon avis on devrait conserver le cron (ou utiliser un cronjob dans uwsgi pour cela) pour gérer les rejeux/délais et utiliser select_for_update(skip_locked=True) dans la commande runjob pour éviter que les deux ne se marchent sur les pieds.

#7

Mis à jour par Lauréline Guérin il y a plus de 3 ans

cron avec uwsgi

pour info en local je lance ça comme ça:

PASSERELLE_SETTINGS_FILE=/home/lguerin/.config/publik/settings/passerelle/settings.py uwsgi --chdir . --module=passerelle.wsgi:application --env DJANGO_SETTINGS_MODULE=passerelle.settings --master --process 4 --pidfile=/tmp/project-master.pid --http=127.0.0.1:8024 --spooler-python-import=passerelle.utils.spooler --spooler /var/lib/passerelle/spooler/ --cron="-2 -1 -1 -1 -1 passerelle-manage tenant_command cron --all-tenants jobs" 

*** Starting uWSGI 2.0.19.1 (64bit) on [Mon Jan 18 10:50:15 2021] ***
...
[uwsgi-cron] command "passerelle-manage tenant_command cron --all-tenants jobs" registered as cron task
...
Mon Jan 18 10:50:20 2021 - [uwsgi-cron] running "passerelle-manage tenant_command cron --all-tenants jobs" (pid 474438)
...
[uwsgi-cron] command "passerelle-manage tenant_command cron --all-tenants jobs" running with pid 474438 exited after 3 second(s)
#9

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

Je ne suis pas sûr à 100% qu'on puisse juste supprimer debian/passerelle.cron.d, car pas sûr que ça supprimera bien les /etc/cron.d/passerelle sur les machines cibles... Sauf si un dev Debian me dit que je manque de confiance, je proposerais de mettre dans ce fichier :

MAILTO=root

# all cron are handled by uwsgi, see /etc/passerelle/uwsgi.ini

(et idem pour debian/passerelle.cron.hourly je dirais)

#10

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

En virant même le MAILTO, et oui faut faire ainsi (parce que supprimer c'est compliqué, https://wiki.debian.org/DpkgConffileHandling).

#12

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

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

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

  • Statut changé de Solution validée à En cours

Jenkins est rouge sur des tests qui jouent avec les jobs dans test_sms.py :

    def test_send_schema(app, connector, to, destination):
        base_path = '/%s/%s/send/' % (connector.get_connector_slug(), connector.slug)
        payload = {
            'message': 'not a spam',
            'from': '+33699999999',
            'to': [to],
        }
        with mock.patch.object(connector, 'send_msg') as send_function:
            app.post_json(base_path, params=payload)
            connector.jobs()
>           assert send_function.call_args[1]['destinations'] == [destination]
E           TypeError: 'NoneType' object is not subscriptable

... send_function.call_args est None, comme si le job n'avait pas été joué lors du connector.jobs()

#14

Mis à jour par Lauréline Guérin il y a environ 3 ans

Ce test a été ajouté dans main entre temps, et nécessite une adaptation du mock

#15

Mis à jour par Lauréline Guérin il y a environ 3 ans

#16

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

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

Parfait !

#17

Mis à jour par Lauréline Guérin il y a environ 3 ans

  • Statut changé de Solution validée à Résolu (à déployer)
commit d53ce49abbe98953fc1b52afc63abc311cb9ff5c
Author: Lauréline Guérin <zebuline@entrouvert.com>
Date:   Thu Jan 14 15:00:15 2021 +0100

    jobs: use uwsgi spooler to run jobs (#50017)
#18

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
#19

Mis à jour par Lauréline Guérin il y a environ 3 ans

#20

Mis à jour par Lauréline Guérin il y a environ 3 ans

  • Lié à Bug #50862: /etc/cron.hourly/passerelle: Exec format error ajouté

Formats disponibles : Atom PDF