|
@@ -95,3 +95,56 @@ réalisation, tandis que dans un modèle par disponibilité l'appel à
|
|
|
\section{Gestion du multiplexage des messages}
|
|
|
|
|
|
% TODO: évolutivité, messages totalement asynchrones, cookies
|
|
|
+Une fois cette abstraction en place, chaque worker va pouvoir recevoir des
|
|
|
+messages venant de plusieurs sources. On peut commencer à tracer les premières
|
|
|
+communications entre modules, mais il n'est pas encore possible d'effectuer des
|
|
|
+RPC. En effet, les messages que l'on envoient et le découpage que l'on a fait
|
|
|
+en eventloop ne permettent pas de recevoir une réponse. Or cette réponse est
|
|
|
+cruciale autant pour garder un modèle synchrone là où il est synchrone dans VLC
|
|
|
+de base que pour pouvoir récupérer le résultat de l'appel de la fonction dans
|
|
|
+l'autre processus. De plus, on peut vouloir faire évoluer l'architecture vers
|
|
|
+moins de synchronisation plus tard, et avoir un système s'approchant de
|
|
|
+l'asynchrone avec des promesses, des résultats futurs et de la synchronisation
|
|
|
+à la demande seulement.
|
|
|
+
|
|
|
+Une première idée serait de bloquer la boucle événementielle tant qu'aucun
|
|
|
+message de réponse n'est reçu, en écoutant directement sur l'IPC à qui on a
|
|
|
+envoyé le message. Conceptuellement, cela demande de séparer le canal de
|
|
|
+requête du canal de réponse pour éviter de confondre une requête du module
|
|
|
+jouant le rÔle de correspondant avec la réponse à la RPC du premier module.
|
|
|
+Cela rajoute donc déjà de la complexité dans l'application. Mais plus encore,
|
|
|
+cela ouvre la voie à des verrous très facile où un module ferait une RPC vers
|
|
|
+un autre module qui ferait une RPC vers le premier module, qui ne pourra pas
|
|
|
+répondre sans la boucle événementielle.
|
|
|
+
|
|
|
+Une autre idée est donc de copier une technique déjà utilisée dans d'autres
|
|
|
+projets, en particulier XCB, et dans des protocoles bien connus comme TCP. Nous
|
|
|
+allons introduire un compteur de RPC envoyés dans chaque processus, et prendre
|
|
|
+en compte valeur de ce compteur dans les messages. Lorsqu'un module voudra
|
|
|
+lancer une nouvelle RPC vers un autre module, il utilisera la valeur de ce
|
|
|
+compteur en début de message puis l'incrémentera. Lorsqu'un autre module voudra
|
|
|
+répondre à une requête, il réutilisera la valeur de ce compteur en début de
|
|
|
+réponse. Du point de vue du proxy, on peut récupérer un
|
|
|
+\inltype{vlc_msg_cookie_t} en utilisant \inltype{vlc_msg_SendMsgReply}, qui
|
|
|
+contiendra les détails de la requête, et il sera alors possible d'envoyer autant
|
|
|
+de requêtes que nécessaire puis attendre que les cookies soient utilisés par la
|
|
|
+boucle événementielle pour récupérer les réponses.
|
|
|
+
|
|
|
+% https://xcb.freedesktop.org/manual/structxcb__void__cookie__t.html
|
|
|
+Le mécanisme est analogue à celui de \inltype{xcb_void_cookie_t}, allant jusqu'à
|
|
|
+en reprendre le nom, mais n'est pas basé sur de la génération de code et ne done
|
|
|
+pas de cookie différent par type de requête. En réalité, les cookies devraient
|
|
|
+être pouvoir alloués sur la pile, par exemple, sans que cela soit gênant du
|
|
|
+point de vue de l'API. L'unique liberté qui doit être interdite est de
|
|
|
+transférer le cookie à d'autres fonctions ou stocker le cookie en dehors de la
|
|
|
+fonction dans laquelle le RPC a été effectué. En effet, ce système donne
|
|
|
+l'impression de pouvoir faire de la programmation complètement asynchrone, mais
|
|
|
+le contexte dans lequel s'exécute le RPC n'est pas asynchrone. L'appel a lieu
|
|
|
+dans une architecture prévue pour être synchrone et la fonction devra retourner
|
|
|
+une valeur à la fin, il faut donc avoir terminé l'ensemble des requêtes
|
|
|
+associées à une fonction. La situation est similaire à l'implémentation de XCB
|
|
|
+dans Xlib: bien qu'XCB supporte l'écriture de requête asynchrone, Xlib ne peut
|
|
|
+pas fournir d'outils à travers son API pour gérer cette caractéristique. XCB a
|
|
|
+le droit d'être complètement asynchrone au sein d'un appel à une fonction de
|
|
|
+Xlib mais doit impérativement avoir terminé ses requêtes à la fin de l'appel de
|
|
|
+la fonction.
|