novembre
2010
Le modèle du passage de messages est très simple et il s’apparente au fonctionnement de l’Internet. Le client demande des informations par l’envoi d’un message (requête), et le serveur retourne un message (réponse) avec les informations requises, par exemple une page web. En attendant la réponse, le client peut s’occuper à d’autres tâches. Si les informations demandent du temps à être reçues, le client peut utiliser les données partielles pour commencer son travail, par exemple pour réserver de la place à une image dans une page.
Je ne vais pas poursuivre l’analogie du navigateur Internet plus loin. Mais vous pouvez la garder en tête quand je vais discuter le passage de message dans dodo, car les deux se rejoignent parfois.
Dodo utilise un modèle client-serveur pour la programmation parallèle. Le partage de données se fait par envoi de messages, ce qui évite les problèmes de synchronisation liés à la mémoire partagée.
Le client
L’envoi d’un message se fait de la façon suivante:
service!capability.Message(arguments)
service est le nom du service requis, par exemple net désigne un service lié au réseau.
capability est un objet qui donne accès à un certain aspect du service, par exemple la communication avec une adresse choisie.
Message est le nom du message envoyé, par exemple Get pour demander le contenu à une adresse.
arguments est une liste de données qui font partie du message, par exemple un nom de page web.
Pour recevoir le contenu de la page d’accueil de dodo, on peut faire:
def dodohome = net.Connection("http://dodo.sourceforge.net") def contenu = net!dodohome.Get("index.html")
À partir de cet instant, on peut utiliser la variable contenu dans le programme. Cependant, sa valeur est future, ce qui signifie qu’elle n’est connue qu’à partir du moment où le service a répondu au message. Si l’on tente de lire sa valeur avant cela le programme va s’interrompre jusqu’à ce qu’elle soit disponible.
On peut définir un gestionnaire pour la variable à l’aide de handler, qui permet de limiter le délai de réponse, ou demander à dodo de répéter la requête si la réponse n’est pas retournée à temps.
Dans l’exemple précédent, la capability est obtenue juste avant son utilisation. Souvent une capability est reçue en paramètre de la fonction. En effet les fonctions dodo, que l’on distingue des méthodes, n’autorisent pas les effets de bord. L’utilisation d’une capability permet de contourner cette limitation.
Le serveur
Un serveur est un programme dodo qui est enregistré pour délivrer un certain service. Il offre aussi le moyen d’obtenir des capabilities qui permettent de s’assurer que le message provient d’un client autorisé.
Le serveur est démarré quand un client lui fait une requête, et peut être arrêté ou continuer en fonction des ressources disponibles et de son utilisation.
L’exemple ci-dessous illustre la définition d’un service. Dans cet exemple les possibilités de programmation parallèle apportées par les modèle client-serveur ne sont pas exploitées.
__Service__ exemple export capability DireHello: String nom message Parle(Link(<with: DireHello>) ressource) { console!Stdout().Puts("Hello, " + ressource.nom) } . __Module__ program __Main__ def Main() { def helloworld = new DireHello.instance(nom: "world") exemple!helloworld.Parle() }
Partie 1 – Présentation
Partie 3 – Les tâches et les variables partagées
Partie 4 – Les transactions