Le module main
permet de lancer la boucle principale du programme en automatisant son arrêt, ainsi que de gérer de manière automatique la convergence de plusieurs instances entre elles (dans l'esprit de ce que fait la libunique, mais sans devoir passer par DBus).
La fonction daemon est à utiliser comme décorateur, avec un paramètre indiquant si le programme peut fonctionner de manière autonome ou non. La fonction passée à ce décorateur sera alors appelée pour chaque programme et jeu d'arguments détecté. Plus précisément :
--standalone
(les - initiaux étant optionnels) est fourni, la fonction sera appelée une seule fois (avec un paramètre supplémentaire à vrai), et la fonction daemon
renverra None
. Le programme ne tentera pas de communiquer avec d'autres instances.--daemon
(idem, les - sont optionnels) est fourni, le programme créera une socket à son nom dans $TARGETSHM/daemons pour recevoir les connexions d'autres instances, et enverra si besoin un SIGCHLD
à son parent pour lui signifier être prêt. La fonction passée au décorateur sera appelée une première fois avec les arguments du daemon, puis une fois par tentative de connexion à la socket. Le décorateur renverra dans ce cas vrai.SIGCHLD
. Dans ce cas, la fonction passée au décorateur n'est jamais appelée, et celui-ci renvoie faux.Un autre attribut spécial, --quit
(encore une fois, les - sont optionnels) force le daemon à s'arrêter proprement lorsqu'il est lu sur la socket (ledit daemon s'arrête d'ailleurs également si un autre daemon lui signifie qu'il prend le relai).
Chaque fois qu'elle est appelée, le premier paramètre passé à la fonction est un objet particulier, appelé Caller, fournissant les attributs suivants :
pid
, numéro du processus,name
, nom de l'exécutable,args
, tuple contenant les arguments (identifiés par le module dédié),path
, chemin d'accès au « truc » correspondant au processus,thing
, ce « truc » lui-même (présent uniquement si la bibliothèque dédiée est accessible),env
variables d'environnement du programme (nécessite la bibliothèque des trucs),cwd
répertoire d'exécution du programme (lu depuis l'environnement s'il n'est pas possible de faire autrement).Cet objet présente également une méthode done
, qui termine proprement le programme concerné une fois son traitement terminé (elle est sans effet s'il s'agit du daemon ou d'un programme autonome), et peut être utilisé pour ouvrir un bloc with
. Toutes les sorties (standard ou d'erreur, notamment les traces d'exceptions) du code exécuté dans un tel bloc seront alors redirigées vers les sorties du programme appelant, plutôt que celles du daemon.
L'objet tasks fournit deux méthodes, workingon
permettant d'indiquer que le programme travaille sur une tâche donnée, et done
permettant d'indiquer que le travail sur cette tâche est terminée. Les objets utilisés pour identifier les tâches sont des « trucs » (si la bibliothèque dédiée est disponible, sinon des chaînes de caractères), et certains sont référencés automatiquement en cours de vie du programme (par exemple les processus par la fonction daemon
, ou bien les trucs partagés). L'objet tasks
est écoutable et les fonctions d'écoutes sont notifiées à chaque ajout ou retrait de tâche.
Enfin, la méthode loop permet de déclencher une boucle principal pour le programme, en fonction d'un paramètre donné (chaîne de caractère identifiant le type de boucle. Actuellement, deux boucles principales sont gérées : gtk
, dont le nom est évident, et pause
, qui se contente de lancer signal.pause
en boucle jusqu'à l'arrêt du programme, et est donc sans doute la plus économique (il est possible par exemple de récupérer la valeur de retour du décorateur daemon
pour ne démarrer GTK que si le programme va être actif, « pause » étant a priori amplement suffisant s'il s'agit uniquement de relayer les sorties du daemon).
Ces deux boucles principales lancent une écoute sur l'objet tasks
afin de se terminer proprement dès qu'il n'y a plus aucune tâche en cours. Elles génèrent également (et ajoutent dans l'espace de nom du module main
) une fonction quit
qui permet de déclencher proprement la fermeture du programme en cours de fonctionnement (celle-ci est par exemple utilisée lors de la réception de l'argument --quit
: il faut donc en définir une en cas de boucle principale personnalisée.)