Les réseaux à grande échelle, tel l'Internet, et les grilles de calcul ou de stockage donnent accès à des quantités de données, de services, de ressources logicielles et matérielles répartis. Dans un tel contexte, qui touche également l'informatique ominiprésente (ubiquitous computing) et l'informatique nomade, le développement et le déploiement d'applications demande des méthodes et des outils adaptés permettant de traiter les problèmes qui résultent de l'hétérogénéité (des données, du logiciel, du matériel), de la répartition des ressources et des utilisateurs, des volumes de données déplacés sur le réseau, de la concurrence, de la sécurité, etc. En particulier, les applications doivent faire face à de fortes variations des conditions d'exécution (capacités physiques des réseaux et des machines, disponibilité des composants) et il n'est pas possible de faire d'hypothèse sur la qualité des services requis ou rendus. Ainsi, les applications doivent être adaptables, si possible de manière dynamique. Dans ce cadre, les concepts d'agents, de mobilité, et d'implémentation ouverte semblent du plus grand intérêt.
Les intergiciels « classiques » permettent aux développeurs de s'abstraire de certains aspects techniques, parfois complexes, liés à la répartition et aux opérations distantes. Cependant, dans le contexte du calcul réparti à grande échelle et de l'informatique mobile, il est nécessaire, lors du développement, de prendre en compte la qualité des services et de s'y adapter. Afin de limiter la complexité du développement et de la maintenance et de faciliter la construction d'applications robustes capables de s'adapter dynamiquement aux conditions d'exécution, nous proposons JAVACT, un intergiciel de haut niveau à base d'agents mobiles adaptables.
La programmation par agents mobiles est un paradigme de programmation des applications réparties, susceptible de compléter ou de se substituer à d'autres paradigmes plus classiques tel le passage de messages, l'appel de procédure à distance, l'invocation d'objet à distance, l'évaluation à distance [FPV98,BI02]. Elle est d'un grand intérêt pour la mise en
uvre d'applications dont les performances varient en fonction de la disponibilité et de la qualité des services et des ressources, ainsi que du volume des données déplacées. Le concept d'agent mobile facilite en effet la mise en
uvre d'applications dynamiquement adaptables, et il offre un cadre générique [CHK94] pour le développement des applications réparties sur des réseaux de grande taille qui recouvrent des domaines administratifs multiples.
Un agent logiciel est une entité autonome capable de communiquer, disposant d'une connaissance partielle de ce qui l'entoure et d'un comportement privés, ainsi que d'une capacité d'exécution propre. Un agent agit pour le compte d'un tiers (un autre agent, un utilisateur) qu'il représente sans être obligatoirement connecté à celui-ci, réagit et interagit avec d'autres agents.
Un agent mobile peut se déplacer d'un site à un autre en cours d'exécution pour accéder à des données ou à des ressources. Il se déplace avec son code et ses données propres, mais aussi avec son état d'exécution. L'agent décide lui-même de manière autonome de ses mouvements. Ainsi, la mobilité est contrôlée par l'application elle-même, et non par le système d'exécution comme dans le cas de la migration de processus dans les systèmes opératoires.
En pratique, la mobilité d'agent permet de rapprocher client et serveur et en conséquence de réduire le nombre et le volume des interactions distantes (en les remplaçant par des interactions locales), de spécialiser des serveurs distants ou de déporter la charge de calcul d'un site à un autre. Une application construite à base d'agents mobiles peut se redéployer dynamiquement suivant un plan pré-établi ou en réaction à une situation particulière, afin par exemple d'améliorer la performance ou de satisfaire la tolérance aux pannes, de réduire le trafic sur le réseau, ou de suivre un composant matériel mobile. La mobilité du code offre un premier niveau de flexibilité aux applications. La décentralisation de la connaissance et du contrôle à travers les agents, et la proximité physique entre les agents et les ressources du système renforce la réactivité et les capacités d'adaptation.
La mobilité ne se substitue pas aux capacités de communication des agents (la communication distante reste possible) mais les complète ; afin de satisfaire aux contraintes des réseaux de grande taille ou sans fil (latence, non permanence des liens de communication), les agents communiquent par messages asynchrones.
Le déplacement d'une unité en cours d'exécution d'une machine à une autre se heurte aux problèmes d'hétérogénéité des matériels et des logiciels. Les intergiciels destinés au développement d'applications réparties à grande échelle doivent permettre de s'en abstraire. Par ailleurs, ils doivent fournir les mécanismes permettant le déplacement des agents et la communication entre agents. En particulier, la communication doit (a priori) être insensible aux déplacements des agents : les messages à destination ou provenant d'un agent doivent être acheminés indépendamment des mouvements de cet agent.
La capacité de capture et de restauration de l'état d'exécution d'un agent, appelée mobilité forte, est un point critique. La mobilité faible représente la capacité pour un système de déplacer le code des agents accompagné seulement de données d'initialisation (et non de l'état complet). En fait, c'est essentiellement un problème d'abstraction et d'expressivité, lié à la manipulation des processus qui exécutent les agents, qui est posé : dans les systèmes à mobilité faible, c'est au programmeur de gérer lui-même le mécanisme de reprise. Cette propriété est liée (et parfois confondue) avec la capacité pour un agent de se déplacer à n'importe quel point de son exécution (mobilité anytime).
Un frein à l'utilisation réelle de cette technologie réside cependant dans les problèmes de sécurité qu'elle introduit. La mise en place d'une politique de sécurité peut demander, d'une part la protection des ressources et des données des machines hôtes (en limitant les droits d'accès et la consommation des ressources), et d'autre part, la préservation de l'intégrité et de la confidentialité des agents eux-mêmes et de leurs communications.
La large diffusion de l'environnement Java (et l'utilisation courante des applets) a contribué à l'intérêt porté aux agents mobiles, de par les nombreux avantages offerts (machine virtuelle, sérialisation, invocation de méthode à distance, gestionnaires de sécurité, ...). Java ne permet cependant pas la capture de l'état d'exécution des threads, et par conséquent, l'état dans lequel le calcul sera repris à distance doit être explicitement programmé, ce qui réduit l'expressivité : cette propriété est appelée mobilité faible (il existe des solutions Java non-standard basées sur la modification de la machine virtuelle, ou un pré-traitement code source, ou une modification du bytecode).
Les acteurs [Agh86] sont des entités anthropomorphes qui communiquent par messages. Au sein d'une communauté, un acteur est uniquement connu par sa référence. La communication est point à point, asynchrone, unilatérale et supposée sûre. Les messages reçus sont stockés dans une boîte aux lettres et traités en série (en exclusion mutuelle). Le comportement décrit la réaction de l'acteur à un message. Le comportement est privé : il contient les données et les fonctions de l'acteur, et constitue son état. L'acteur encapsule données et fonctions mais également une activité (fil d'exécution) unique qui les manipule. Un comportement d'acteur n'est donc, à un instant donné, traversé que par un fil d'exécution au plus (la synchronisation est implicite).
Lors du traitement d'un message, un acteur peut créer (dynamiquement) de nouveaux acteurs, envoyer des messages aux acteurs qu'il connaît, et changer de comportement c'est-à-dire définir son comportement pour le traitement du prochain message. Le changement de comportement est un mécanisme puissant d'évolution et d'adaptation individuelles. Il permet à un acteur de modifier dynamiquement son interface ; mais, en conséquence, il n'est pas possible de garantir dans tous les cas qu'un message envoyé pourra effectivement être traité par son destinataire. Cependant, pour le programmeur, le changement de comportement offre une alternative à la gestion de variables d'état et à l'utilisation de gardes, qui accroît l'expressivité. Programmer un acteur revient donc à programmer ses comportements, l'enchaînement des comportements étant décrit dans les comportements eux-mêmes.
La capacité de changement de comportement introduit une difficulté particulière dans le contrôle des envois de messages. En effet, il est délicat de déterminer statiquement si un message envoyé à un acteur pourra effectivement être traité. C'est le problème des messages orphelins [DP+00] :
Si on lui envoie deux fois le message
, l'un des deux messages sera orphelin de sûreté. Si on lui envoie seulement le message
, alors celui-ci sera orphelin de vivacité ; il ne pourra être traité tant qu'aucun message
n'aura été envoyé à l'acteur.
L'idée de l'utilisation des acteurs pour la programmation d'applications concurrentes et réparties n'est pas neuve. Néanmoins, elle semble particulièrement pertinente dans le cadre du calcul réparti à grande échelle de par les propriétés qui distinguent les acteurs du modèle d'objet classique (encapsulation de l'activité, changement d'interface, communications asynchrones). D'une part, la communication par messages asynchrones est bien adaptée aux réseaux de grande taille, voire sans fil, où les communications synchrones sont trop difficiles et coûteuses à établir. D'autre part, l'autonomie d'exécution et l'autonomie comportementale favorisent l'intégration de mécanismes de mobilité et garantissent un certain niveau d'intégrité.
La mobilité d'acteur peut être naturellement définie en se basant sur le traitement des messages en série et le changement de comportement, ainsi que sur la création dynamique et l'envoi de messages. Lors du changement de comportement (donc, entre deux messages), l'acteur se réduit d'une part au contenu de sa boîte aux lettres, et d'autre part au comportement défini pour le traitement du prochain message. Par nature, le comportement est une entité de première classe qui matérialise l'état et qui est manipulable par programme. Il est alors possible de créer à distance un autre acteur défini à partir du comportement. On obtient ainsi simplement une évolution de l'acteur d'origine à qui on peut faire suivre tous les messages qui étaient en attente. L'état est donc entièrement transporté (via le comportement) et restauré sans que le programmeur n'ait à développer de code spécifique pour cela. Ainsi, après migration, l'acteur peut poursuivre son activité à distance en bénéficiant des acquis résultant des traitements de messages précédents. La mobilité est ainsi différée au moment où l'acteur change de comportement.
La communication entre acteurs étant supposée sûre, la mobilité pose le problème de l'acheminement des messages. Pour cela, on définit le protocole suivant (d'autres sont possibles) : l'acteur d'origine se transforme lors du déplacement en un proxy du nouvel acteur (distant) ; il ne traite plus les messages qu'il reçoit mais les transmet. Ainsi, l'acteur reste connu à son adresse d'origine qui demeure valide, et l'envoi de message reste possible à tout instant y compris pendant que l'acteur se déplace (les messages sont stockés au niveau de l'acteur d'origine, puis transmis quand le clone distant est opérationnel). D'autre part, les communications sortantes (émissions de messages) restent valides (pour cela, les références d'acteur doivent être visibles à travers le réseau). Le mécanisme de mobilité est donc transparent pour le système de communication (il reste cependant les problèmes de liaison avec les ressources et les fichiers ouverts). La multiplication des déplacements d'un acteur a alors pour effet de construire une chaîne de liens de poursuite à travers laquelle l'acteur mobile peut être localisé et les messages acheminés (en pratique, on peut optimiser ce mécanisme).
Tout acteur est donc potentiellement mobile, et, ainsi définie, la mobilité n'altère pas la sémantique des programmes. On peut noter que les problèmes de cohérence de copies et de synchronisation que l'on rencontre quand on introduit la mobilité dans le modèle objet ne se posent pas ici du fait de l'unicité du fil d'exécution et de l'exclusion mutuelle sur le traitement des messages.