Une solution pour faire du parallélisme par processus ?

Bonjour, je suis à la recherche d’un module Python (ou une solution facilement pilotable par du code Python) pour implémenter une “grille” de calcul qui lance et gère des sous-processus pour exécuter des routines.

J’ai besoin de :

  • lancer des sous-processus qui exécutent un module Python ;
  • pouvoir leur envoyer des messages, même sur une machine distante (à la mode multiprocessing.Manager). Je recherche plus qu’un pool de processus, j’ai besoin de lancer des exécuteurs qui acceptent des tâches les unes après les autres sans être tués entre deux tâches (sauf si ladite tâche prend trop de temps ou rencontre un problème lors de son exécution) ;
  • gérer les cas d’erreurs : le code Python à exécuter est assez complexe, il va charger et exécuter des bibliothèques déjà compilées (qui sont susceptibles de planter) qui vont elle-mêmes ré-appeler du la C-API de Python (et même recharger la libpython dans certains cas). J’ai aussi besoin de récupérer les informations d’erreurs (pile d’appel Python ou vidage mémoire) en cas de problème et de décider de relancer ou non l’exécuteur.
  • pouvoir associer des ressources à chaque exécuteur (concrètement contrôler le nombre d’exécuteurs qui accèdent en même temps à un périphérique) ;
  • et bien entendu journaliser correctement le tout.

Idéalement j’aimerais aussi:

  • une solution pensée avec le paradigme de fils d’exécution plutôt que coroutines (c.-à-d. philosophie threading plutôt que concurrent.futures) ;
  • pouvoir partager de mémoire vive entre les exécuteurs (comme multiprocessing.shared_memory).

Toutes ces fonctionnalités sont couvertes par le module multiprocessing.
Il marche à merveille mais j’ai le sentiment de faire un peu trop de choses un peu trop bas-niveau à la main : lancer des processus, ouvrir des tubes de communication, envoyer-récupérer des signaux d’interruption, gérer les plantages du code fonctionnel etc.

Avez-vous une alternative à conseiller ?
J’ai regardé du côté de loky mais ça ne me semble pas assez puissant (notamment sur la gestion d’erreurs).

Merci.

Je ne sais pas si il conviendra à ton cas d’usage particulier, mais tu as déjà regardé mpire?

En fait tu veux erlang ?

Bon pour rester en Python dans mes petites notes, que je n’ai pas essayé, j’ai :

mais je préjuge qu’aucun des trois ne se concentre sur le cas bien spécifique que tu décris là.

En fait j’ai le sentiment que ce que tu cherches nécessite plusieurs composants indépendants, comme :

Systemd qui pourrait s’occuper de gérer un (ou plusieurs) « processus exécuteur » par machine :

  • Il s’occupe de récupérer les core-dump (man coredumpctl)
  • Il s’occupe du journal (man journalctl)
  • Il s’occupe de relancer ton exécuteur quand il tombe.

Ton processus exécuteur pourrait, sans se soucier de planter :

  • S’occuper de gérer les ressources partagées comme tu l’entends.
  • Aller chercher les jobs dans une file, les exécuter, renvoyer le résultat.

Et il te faut une file de travaux à traiter (pour communiquer entre tes machines), et là il y a le choix, de redis à kafka en passant par PostgreSQL…

C’est vite beaucoup plus compliqué que ce que tu fais actuellement avec multiprocessing, tu cherchais à simplifier, j’ai répondu de travers…

Ah Je n’avais jamais entendu parler de ce module. C’est effectivement plus haut-niveau que multiprocessing mais ça reste un peu limité en termes d’allers-retours avec l’exécuteur et le maître et en gestion d’erreur.