Objet et Répartition, Le Grand Mariage

Malheureusement pour les utilisateurs des objets répartis, et pour les sociétés qui en font des bénéfices, mais fort heureusement pour les chercheurs dans le domaine, l'union des concepts d'objet et de répartition, bien que consommée, est semée d'embûches. Des problèmes fondamentaux sont encore à résoudre, loin des batailles stratégiques que se livrent DCOM, CORBA, Java RMI et ONE. Ce document fait le point sur les technologies permettant de manipuler des objets répartis au sein des applications.

Article lu   fois.

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

L'union entre les concepts d'objet et de répartition semble être l'une des combinaisons gagnantes de la fin des années 1990, comme le fut à la fin des années 1980 la combinaison entre les interfaces graphiques et les bases de données relationnelles qui conduisit au fameux modèle client-serveur. Avec les objets répartis, un pas de plus est franchi: il ne s'agit plus de systèmes locaux et fermés dans lesquels les rôles de client et de serveur sont établis à l'avance, mais de systèmes ouverts dans lesquels les objets, à la fois clients et serveurs, coopèrent dans un monde démocratique à travers Internet. Les efforts déployés par l'industrie pour affiner les technologies orientées objet et les rendre économiquement et techniquement viables sont considérables, et le danger pour des équipes de recherche universitaires est de se retrouver paradoxalement à la traîne. Malheureusement pour les utilisateurs des objets répartis, et pour les sociétés qui en font des bénéfices, mais fort heureusement pour les chercheurs dans le domaine, l'union des concepts d'objet et de répartition, bien que consommée, est semée d'embûches. Des problèmes fondamentaux sont encore à résoudre, loin des batailles stratégiques que se livrent DCOM, CORBA, Java RMI et ONE.

II. Des mots magiques

Java RMI, ONE, CORBA, et DCOM sont des acronymes dont vous avez probablement entendu parler, qui vous ont peut-être fait peur, ou du moins vous ont un peu dépassé. Vous avez peut-être fait semblant d'en comprendre certains, ou même pire, vous les avez utilisés pour avoir l'air dans le coup.

Ces mots magiques ont deux points communs. Le premier est qu'ils sont tous considérés comme très branchés, et par conséquent sont particulièrement appréciés dans les réunions au sommet sur les nouvelles technologies informatiques. Je me souviens d'un professeur d'informatique qui, au sujet de la manière d'être un bon ingénieur commercial, nous conseillait d'utiliser beaucoup d'acronymes, et de souvent répéter ceux que nos interlocuteurs semblaient ne pas comprendre. Cela, disait-il, permet d'établir un rapport de force en notre faveur, et de faciliter les négociations par la suite.

Le deuxième point commun de ces acronymes est que tous sont les fruits du même mariage, d'un grand mariage, d'un mariage comme on en voit rarement. Il s'agit du mariage de deux technologies, presque aussi vieilles que l'informatique, mais chacune particulièrement en vogue ces derniers temps: la programmation par objets et les systèmes répartis. On peut se demander si un tel mariage n'est pas seulement un mariage de raison, permettant aux acteurs industriels développant chacune des deux technologies d'étendre un peu plus leur champ d'action. Un peu comme lorsque l'on apprend que Michael Jackson épouse Lisa Marie Presley, et que l'on se demande si le premier ne veut tout simplement pas se faire adopter par un public nostalgique du vrai rock et plus regardant sur certaines mœurs, et si la seconde n'aimerait pas simplement entrer par la grande porte dans le monde du show-business.

Il y a très probablement du vrai dans un scénario arrangé, mais au-delà du mariage de raison, il y a une complémentarité indéniable entre les deux partenaires, en tout cas en ce qui concerne les concepts d'objet et de répartition.

III. Il était une fois un langage de programmation

Le premier langage de programmation par objets, Simula, a été défini en 1965 par Ole-Johan Dahl et Kristen Nygaard en Norvège. Il avait pour objectif les applications de simulation, mais ses concepteurs réalisèrent que les concepts sous-jacents du langage pouvaient s'appliquer à d'autres types d'applications. Ils développèrent alors le successeur de Simula, Simula 67, comme une extension du langage Algol 60, en y rajoutant les concepts d'encapsulation et d'héritage, à travers les mécanismes de classes et de sous-classes. Le concept d'encapsulation permettant de réunir des données et des procédures dans une même entité antropomorphique, appelée objet, et de séparer les interfaces des mises en œuvre, s'avéra particulièrement utile pour concevoir les composants d'un programme de manière modulaire, et de s'abstraire des détails de leur mise en œuvre. Ce concept inspira C.A.R. Hoare en 1972 dans la construction de types abstraits de données, puis un peu plus tard en 1977, Barbara Liskov et Alain Snyder dans la conception du langage CLU. Par ailleurs, le concept d'héritage, permettant d'automatiser le procédé de réutilisation du code par spécialisation, s'avéra particulièrement utile pour faciliter le prototypage et rendre plus lisibles les programmes. La puissance de ce concept fut démontrée à travers le langage Smalltalk, développé par Alain Kay et Adèle Goldberg au début des années 80 chez Xerox, à travers la bibliothèque des composants de l'interface graphique de développement. Pour la petite histoire, on raconte que des ingénieurs de chez Apple, alors qu'ils développaient l'interface graphique du système Mac OS, rendirent souvent visite à leurs voisins de Xerox. On sait par la suite que le fameux Windows95 s'inspira quelque peu (beaucoup) de cette interface graphique.

La dénomination langage de programmation orienté objets, ou plus simplement langages à objets, fut attribuée aux langages, tels que Simula, Smalltalk et Eiffel, qui offraient des mécanismes de construction de classes et de sous-classes. Pendant longtemps, ces langages furent considérés comme des jouets pour les universitaires, ou au mieux comme des outils de composition de fenêtres en couleur. La raison invoquée était la lenteur d'exécution des programmes. Le succès industriel de C++, un peu plus pragmatique et plus proche des machines que ses prédécesseurs, mit fin à ce tabou. On connait la suite de l'histoire avec un fameux café (1).

IV. Le grand mariage

IV-A. Déjà à l'époque

Le premier langage à objets, Simula 67, permettait déjà de programmer des applications réparties (du moins logiquement). Grâce à la notion de coroutine de Simula, le programmeur pouvait écrire des activités indépendantes, et les faire exécuter de manière concurrente. Quoi de plus naturel en fait puisque, d'une part Simula était destiné à des applications de simulation, en particulier de processus industriels où certaines activités se déroulent en parallèle, et d'autre part, le concept d'objet était destiné à modéliser des entités du monde réel, souvent autonomes. Du fait probablement du poids culturel de la programmation séquentielle, et des limitations technologiques de la vitesse de communication en réseau, l'aspect répartition des langages à objets fut mis en veilleuse. Pas complètement néanmoins, car dans les années 80, au MIT par exemple, Carl Hewit et Gul Agha s'amusaient avec des objets actifs pour modéliser des pièces de théâtres (les fameux acteurs), et Barbara Liskov proposait une extension répartie du langage CLU, appelée ARGUS, pour permettre à des objets de communiquer à travers des machines distantes (les fameux objets gardiens). Un peu plus à l'Ouest, à l'Université de Washington, Andrew Black proposait un système, baptisé Emerald, qui permettait de rendre mobile des objets en les faisant voyager d'une machine à une autre.

IV-B. Tout s'est ensuite passé très vite

Depuis, la vitesse de communication entre machines est devenue de plus en plus rapide grâce aux progrès technologiques des réseaux. Par ailleurs, l'intérêt de la répartition est devenu fondamental. Des applications réparties, telles que le travail coopératif et le commerce électronique, sont devenues à la mode. De plus, on s'est rendu compte que la répartition permet de tolérer les défaillances, de répartir les charges et de partager les ressources l'un des programmes répartis les plus utilisés est celui qui permet le partage d'une imprimante par plusieurs utilisateurs. Bref, on s'est rendu compte que la répartition permet de laver encore plus blanc.

La première phase dans la création d'architectures réparties a consisté à permettre à des machines, appelées serveurs, d'accomplir des tâches spécifiques pour le compte d'autres machines, aux capacités plus restreintes, appelées clients. Ce type d'architecture était particulièrement adapté à des réseaux locaux, regroupant un nombre limité de machines. La seconde phase, plus ambitieuse, a consisté à permettre à des machines de coopérer dans un monde plus démocratique. On parle encore de clients et de serveurs, mais un serveur peut se retrouver lui-même client et vice-versa. L'objectif est ici de concevoir des applications mettant en œuvre plusieurs réseaux locaux, dans une structure ouverte, où des machines peuvent se connecter pendant l'exécution d'une application.

Pour d'une part mieux structurer et faciliter la maintenance des programmes répartis, considérés à juste titre comme particulièrement complexes, et d'autre part mieux modéliser l'autonomie et la communication entre composants répartis, l'union entre les concepts d'objet et de répartition était devenue inéluctable. Il y a eu deux mariages: un mariage suivant une approche appliquée, et un deuxième suivant une approche intégrée.

IV-C. Le mariage par l'application

Cette approche a consisté à appliquer les concepts de la programmation par objets, en tant que tels, pour structurer les systèmes informatiques répartis. Les différents composants de ces systèmes, tels que les processus, les sémaphores, les transactions, etc., sont représentés par des classes spécifiques d'objets. On parle alors de services répartis. La programmation reste séquentielle et on procède par extension des bibliothèques séquentielles, en modélisant les aspects relatifs à la répartition avec de nouvelles classes. L'objectif est en particulier d'apporter une certaine généricité aux architectures. Le programmeur peut alors appliquer le concept d'encapsulation, pour modifier certains composants du système de manière modulaire, en fonction d'une application ou d'une machine particulière, puis appliquer le concept d'héritage, pour spécialiser certains composants à travers des nouvelles classes. La figure 1 représente des classes modélisant des concepts de répartition tels que les transactions, les transactions emboîtées, les processus, les sémaphores, les verrous ou les moniteurs.

Image non disponible
Figure 1 : Approche appliquée

L'assemblage des différentes classes est soit laissé au bon soin du programmeur, soit préalablement réalisé par les concepteurs des classes. Dans le premier cas, on parle de boîte à outils, et le programme contrôle les connexions entre les classes, i.e., les communications entre les objets. Dans le second cas, le programmeur trouve une charpente préalablement construite, suivant un motif bien rodé (on parle respectivement de framework et de pattern). Sa tâche se réduit dans ce cas à mettre en œuvre certaines opérations appelées à son insu lors de l'exécution d'un programme réparti (on parle de call back), suivant le principe de Hollywood, où l'on répond aux jeunes qui se présentent pour un premier rôle « don't call us, we will call you !».

En résumé, le mariage par application consiste à utiliser un langage et une méthodologie de programmation à objets pour structurer un système réparti. En plus des objets séquentiels d'une application, on trouve des objets permettant de représenter les concepts de la répartition. Cela permet de bien structurer les mécanismes de répartition, mais laisse le programmeur en charge de deux tâches distinctes: d'une part la programmation des objets séquentiels et centralisés de l'application, et d'autre part la gestion de la répartition, également exprimée à l'aide d'objets, mais pas les mêmes !

IV-D. Le mariage par l'intégration

Au lieu de laisser ces dimensions relativement orthogonales, l'approche intégrée vise justement à les fusionner, et à étendre les concepts fondateurs des objets en y intégrant les concepts sous-jacents de la répartition. Plusieurs niveaux d'intégration complémentaires peuvent être considérés.

IV-D-1. Invocation d'objets à distance

Du fait qu'un objet contient ses propres données et opérations, il constitue une unité indépendante d'exécution et de répartition (fig. 2).

Image non disponible
Figure 2 : Approche intégrée

Cela permet de considérer une application répartie comme un ensemble d'objets, chacun situé sur une machine distincte. La métaphore de la communication par « envoi de message », dans Smalltalk par exemple, prend ainsi tout son sens lorsqu'il s'agit d'objets situés sur des machines différentes. On parle d'invocation d'objet à distance, et de nombreux systèmes assurent la transparence d'une telle invocation: tout se passe comme si l'objet était local. Pour prendre en compte l'inaccessibilité des objets, le système Argus du MIT dans les années 80 permet par exemple d'associer des exceptions à chaque invocation. Si un objet est situé sur une machine qui est inaccessible, à cause d'une panne du réseau de communication ou du processeur de la machine, l'exception est déclenchée. Cela permet par exemple d'invoquer un autre objet à la place.

IV-D-2. Objets mobiles

L'autonomie des objets, en tant que capsules de données et d'opérations associées, facilite la migration éventuelle. Lorsqu'un objet client désire invoquer un objet serveur distant, plutôt qu'une invocation distante, la migration permet de déplacer l'objet serveur (ou une copie de cet objet) chez le client (fig.2). Cela est particulièrement utile lorsque le client désire effectuer plusieurs opérations sur un même serveur.

IV-D-3. Objets actifs

En intégrant le concept de processus aux objets, ces derniers deviennent actifs. L'objet est alors doté d'une ressource de calcul, c'est-à-dire doué d'activité propre. Le concept d'objet actif a eu beaucoup de succès dans le domaine de l'intelligence artificielle, car il constitue une fondation assez naturelle pour construire des systèmes multiagents (les fameuses sociétés de fourmis en intelligence artificielle).

IV-D-4. Objets synchronisés

L'association de la synchronisation à la transmission de messages, c'est-à-dire à l'invocation, offre l'avantage de traiter de manière transparente une bonne partie de la synchronisation nécessaire pour assurer une sémantique correcte d'un programme réparti. On peut distinguer trois niveaux de synchronisation correspondant respectivement à la concurrence interne d'un objet, à son interface, et à la coordination entre plusieurs objets. Dans le premier cas (synchronisation intra-objet), on exprime les restrictions en termes d'exclusions entre opérations. Ainsi, par exemple, des lecteurs peuvent lire simultanément un même livre. Par contre, l'accès en écriture par un écrivain exclut tous les autres (écrivains comme lecteurs). Au 2e niveau (synchronisation comportementale), il se peut qu'un objet ne puisse temporairement traiter certains types de requêtes qui font pourtant partie de son interface. Par exemple, un tampon de taille bornée ne pourra accepter une requête d'insertion tant qu'il est plein. Plutôt que de signaler une erreur, il est en général plus judicieux de laisser en attente une telle requête tant que la condition n'est pas remplie. Enfin, au 3e niveau (synchronisation interobjets), on peut désirer assurer une cohérence, non plus seulement individuelle, mais globale entre de multiples objets. Prenons l'exemple d'un transfert de fond entre deux comptes bancaires. En l'occurrence, on veut assurer l'atomicité, au sens transactionnel, du transfert, entre les deux objets comptes bancaires. La synchronisation intra-objet ou comportementale n'est alors plus suffisante. On introduit une synchronisation qui met en œuvre les deux objets représentant les comptes bancaires.

V. Ils eurent beaucoup d'enfants

Le mariage des concepts d'objet et de répartition a donné naissance à un nombre impressionnant de langages, de systèmes et de bibliothèques d'objets répartis. A ma connaissance, tous les projets actuels d'architectures réparties sont basés sur le concept d'objet. D'une part, les chercheurs issus de la communauté langage de programmation à objets étendent les environnements de programmation vers des architectures réparties, et d'autre part, les chercheurs issus de la communauté système adoptent le modèle objet pour structurer les concepts de la répartition.

La notion d'encapsulation, fondamentale d'un point de vue conceptuel, devient tout aussi fondamentale d'un point de vue pratique. Si une société informatique vend à travers le réseau un service sous forme d'un objet invocable (e.g., un serveur Web), il est important pour cette société que les utilisateurs ne puissent pas connaître la mise en œuvre du service (ils pourraient se rendre compte qu'ils ont payé trop cher), et que les fonctionnalités du service soient les mêmes que celles d'une société concurrente, même si les deux utilisent des mises en œuvre différentes, des langages de programmation différents et des systèmes d'exploitation différents.

Bien que certains développements universitaires associent les objets et la répartition suivant une approche particulière (intégrée ou appliquée), la grande majorité des systèmes à objets répartis, et en particulier les produits commerciaux, font une synthèse pragmatique des deux approches. Parmi les rejetons du couple objet et répartition, les plus connus ont pour noms CORBA, DCOM, Java (Java RMI) ou encore ONE.

V-A. CORBA

Depuis 1989, une association internationale appelée l'OMG (Object Management Group), définit la spécification de l'architecture d'un système à objets répartis, appelée CORBA (Common Object Request Broker Architecture). Près de 700 sociétés sont actuellement membres de l'OMG, aussi bien des sociétés informatiques comme HP, Digital, Sun, Microsoft, ou IBM, que des utilisateurs comme Boeing ou Alcatel. A l'inverse d'ODP (Open Distributed Processing), un autre effort de standardisation d'architectures réparties, CORBA a été défini dans un but très pratique, et de nombreuses mises en œuvre de la spécification CORBA sont actuellement sur le marché, incluant SOM de IBM, ObjectBroker de Digital, Orbix de Iona, et Visibroker de Visigenic.

CORBA associe les concepts d'objet et de répartition dans une approche à la fois intégrée et appliquée. L'intégration se fait à travers la notion d'invocation à distance d'objet (l'objet est l'unité de répartition), et l'application se fait à travers les services de répartition qui sont organisés sous forme de bibliothèques de classes.

Les objets CORBA, dont les interfaces sont décrites dans un langage spécifique, nommé IDL (Interface Description Language), sont portables sur différents systèmes d'exploitation, et des objets d'une même application peuvent être écrits dans différents langages de programmation. Avec la spécification CORBA 2.0, et l'adoption du standard de communication IIOP (Internet InterORB Protocol), ces objets peuvent communiquer à partir de différentes mises en œuvre de CORBA. Cela répond à l'un des soucis majeurs de l'informatique de cette décennie, à savoir l'intégration de composants informatiques hétérogènes. Dans CORBA, le modèle objet est appliqué à tous les niveaux d'une application. Et en particulier, tous les services de répartition, comme le nommage, les transactions ou la persistance, sont spécifiés et mis en œuvre sous forme de classes d'objets CORBA. La notion de service CORBA explique, en grande partie, le succès commercial de CORBA, car elle permet à divers développeurs de logiciels de contribuer à la mise en œuvre de CORBA et d'en tirer les bénéfices. Des sociétés comme Oracle ou Ingres peuvent par exemple vendre leur technologie bases de données sous forme d'un service de persistance CORBA, alors qu'une société comme Transarc peut vendre un moniteur transactionnel sous la forme d'un service transactionnel CORBA.

V-B. DCOM

Bien que membre de l'OMG, Microsoft a développé son propre standard d'objets répartis, appelé DCOM (Distributed Component Object Model). Le terme standard revêt dans ce contexte un caractère particulier, car il signifie standard pour, et seulement pour, les produits Microsoft.

L'histoire a commencé en 1993 avec OLE 2.0 (Object Linking and Embedding), l'ensemble des mécanismes permettant aux utilisateurs d'un produit Microsoft (e.g., PowerPoint) d'intégrer des composants construits avec un autre produit Microsoft (e.g., des images Graph). Le fondement de OLE était COM (Component Object Model), un standard de compatibilité binaire entre objets, et qui unifie l'architecture des différents services OLE. Contrairement à CORBA, OLE n'a pas été créé à l'origine pour la programmation répartie. Depuis 1996 est apparu DCOM qui désigne les composants Windows qui peuvent être distribués sur différentes plates-formes (Windows) à travers Internet. Ces composants sont basés sur une extension du modèle objet COM aux environnements distribués, appelé DCOM. L'usage initial des composants DCOM était la mise en œuvre de documents composés. Ici, la notion de document remplace la notion d'application dans CORBA. Un document est composé de plusieurs composants répartis (tableaux, textes, graphiques).

On retrouve, comme dans CORBA, l'intégration des concepts d'objet et de répartition, à la fois suivant une approche intégrée et appliquée. L'approche intégrée se matérialise par le fait que les objets sont des unités de répartition qui communiquent en utilisant des invocations à distance, et l'approche appliquée par le fait de développer des services de répartition sous forme de bibliothèques de classes. Néanmoins, à la différence de CORBA, aucun mécanisme ne permet de mettre en œuvre l'héritage de classes. Ce mécanisme est remplacé par l'agrégation (la composition d'objets) et la délégation (un objet délègue à un autre objet ce qu'il ne sait pas faire).

V-C. Java, Java RMI et Java Beans

Après l'échec du projet initial OAK (premier nom du langage Java), visant à définir un langage de programmation pour la télévision interactive et les équipements de téléphonie, Sun Microsystems propulsa de nouveau Java sur le devant de la scène en automne 1995, et suscita l'enthousiasme qu'on connaît des utilisateurs et des programmeurs d'Internet en pleine expansion. Java élimine quelques aspects critiquables de C++ tels que les pointeurs et les templates, et introduit quelques aspects sympathiques de Smalltalk tels que le ramassage de miettes et une forme de manipulation (assez primitive) de classes en tant qu'objets. Les développements de Java et de ses bibliothèques sont désormais adoptés par tous les logiciels visant Internet, y compris par Microsoft qui créa Visual J++, une version de Java destinée aux environnements Windows, sans pour autant renoncer au développement de DCOM, ni à sa participation à l'OMG.

Java intègre les objets et la répartition à travers le mécanisme de migration. C'est le code qui se déplace: il n'y pas, du moins dans les premières versions des bibliothèques, d'invocation d'objet distant. Lorsqu'un fouineur comme Netscape charge une page Web et rencontre dans un code HTML (Hyper Text Markup Language) une étiquette désignant une applet Java (i.e., un programme Java qui peut se télécharger à travers le Web), il retrouve le code de l'applet et le fait migrer vers le site client (en établissant une connexion TCP/IP). La machine virtuelle Java du fouineur permet ensuite d'exécuter le code Java (en fait le byte code) migré chez le client. Le fouineur efface ensuite le code de la mémoire lorsqu'il quitte la page Web en question.

Plus récemment, JavaSoft, une filiale de Sun Microsystems, développa une bibliothèque de classes, appelée RMI (Remote Method Invocation), permettant la communication répartie, puis sous le nom de Java Beans (grains de café Java), un ensemble d'outils d'introspection, de visualisation de programmes répartis, de persistance, et de gestion d'événements. On retrouve, en plus de la possibilité de migration initiale des objets Java, la possibilité d'invocation à distance d'objets ainsi qu'un ensemble de services répartis comme dans CORBA. A la différence de CORBA, RMI présuppose que le client et le serveur sont développés en Java, et que tous deux sont exécutés sur une machine virtuelle Java.

Image non disponible
Figure 3 : Migration et invocation à distance sur le Web

V-D. ONE

Netscape communications a présenté en 1996 sa propre mise en œuvre de CORBA, en Java, baptisée ONE (Open Network Environment). ONE offre la possibilité à une page Web téléchargée à travers le fouineur Netscape de dialoguer ensuite avec un serveur CORBA. Une page Web peut ainsi contenir des objets CORBA (avec des interfaces IDL) qui peuvent à leur tour utiliser des objets (et des services) CORBA. La figure 3 présente les différentes étapes mises en jeu. Tout d'abord, le navigateur télécharge une page Web (1), l'affiche (2), puis télécharge le code Java de l'applet (3). Ensuite, l'applet est localement exécutée et un objet CORBA est ensuite invoqué à distance (4). Cet objet peut lui même invoquer d'autres objets, etc.

Image non disponible
Figure 4 : Les objets sur le Web

L'intérêt de l'approche ONE est le subtil mélange entre les avantages de Java et de CORBA, qui se traduit par la possibilité à la fois de migration des objets, et d'invocation à distance d'objets et de services (CORBA) hétérogènes. Une application peut ainsi avoir une partie applet Java téléchargeable à travers le Web, des parties serveurs, utilisant des bases de données (e.g., accédant à Oracle à travers CORBA), ainsi que des composants développés dans d'autres langages que Java (oui, il en existe encore !). De plus, le modèle de programmation des objets CORBA est très similaire à la programmation Java RMI. Le code IDL est directement généré à partir du code Java. Par ailleurs, les objets sont référencés par des adresses URL (comme n'importe quel document sur le Web). D'une certaine manière, cela traduit l'évolution des objets répartis sur le Web (fig. 4).

VI. Et ils vécurent heureux ? Non, et heureusement d'ailleurs …

Maintenant que la messe est dite, que le mariage entre les concepts d'objet et de répartition est consommé, et que les fruits de ce mariage sont l'objet de toutes les convoitises par les grands industriels de l'informatique, on est en droit de se demander, en tant que chercheur universitaire, s'il est vraiment raisonnable d'entreprendre, ou même de continuer, des activités de recherche dans le domaine des objets répartis.

Une première réponse consisterait à dire « mais oui justement, cela permettrait d'avoir des contrats industriels plus facilement, et d'être au courant des nouvelles technologies à enseigner aux étudiants ». D'une part, un laboratoire de recherche se retrouverait rapidement dans la situation d'intégrer des technologies sans les maîtriser vraiment, ou d'agir comme sous-contractant ponctuel, moins cher que des sociétés de services informatiques. J'ai du mal à imaginer la qualité des thèses qui s'en suivraient. D'autre part, et sans aller jusqu'à l'attitude extrême de ce grand professeur d'informatique américain qui aime à répéter « je n'enseigne jamais ce que l'industrie réclame, car ce qu'elle réclame, elle l'enseignera elle-même », il ne semble pas très académique de devoir modifier les manuels de cours au gré des changements de stratégies commerciales de Microsoft, IBM ou JavaSoft. Je viens d'apprendre par exemple que Microsoft vient de choisir comme nom pour son architecture répartie l'acronyme DNA (Distributed InterNet Applications):

VI-A. À la recherche d'abstractions standards

Comme mentionné précédemment, la première manière d'unir les concepts d'objet et de répartition consiste, suivant une approche appliquée, à décomposer un système réparti en bibliothèques de classes.

Bien que des tentatives soient entreprises dans ce sens, il est encore beaucoup trop tôt pour considérer qu'il existe une bibliothèque de classes susceptible de devenir un standard pour la programmation répartie. Dans un contexte séquentiel, il existe effectivement des abstractions fondamentales, telles que le tableau ou l'enregistrement. Dans un contexte concurrent, le sémaphore, est lui aussi devenu une abstraction fondamentale qui fait désormais partie de la plupart des bibliothèques de programmation concurrente. Dans un contexte réparti, aucune abstraction fondamentale ne se dégage vraiment. Cela souligne le fait que le domaine de la programmation répartie est relativement nouveau et assez complexe. Cela est d'autant plus vrai lorsqu'on considère des problèmes de tolérance aux défaillances ou des contraintes temporelles.

Les difficultés d'un tel exercice (i.e., trouver et organiser des abstractions adéquates) résident d'une part dans une bonne compréhension des mécanismes minimaux de la programmation répartie, et d'autre part dans un consensus sur ces mécanismes. Un tel consensus devrait mettre en jeu différentes communautés de chercheurs: langages, répartition, et parfois bases de données (pour des mécanismes transactionnels par exemple).

VI-B. L'intégration ne se fait pas toujours sans dégât

Certains mécanismes développés par la programmation par objets ont été fondés sur des hypothèses fortes d'informatique traditionnelle, c'est-à-dire séquentialité de l'exécution des programmes et espace mémoire unique. Ils peuvent ainsi atteindre leurs limites quand ils sont transposés directement dans l'univers de la programmation répartie, suivant l'approche applicative, où ils sont fusionnés avec des concepts de la répartition.

Particulièrement significatif est le cas du mécanisme d'héritage par exemple. La première limitation tient à la volonté d'appliquer le concept d'héritage à la spécialisation d'un nouvel aspect des objets: la synchronisation. Il se peut que dans certains cas la définition d'une sous-classe, rajoutant une seule méthode à la classe parente, impose la redéfinition de l'ensemble des spécifications de synchronisation, annulant ainsi le premier bénéfice de l'héritage: la réutilisabilité du code. Par ailleurs, la mise en œuvre de l'héritage dans un système réparti pose le problème de l'accès distant au code des classes parentes, à moins que celles-ci ne soient dupliquées sur toutes les machines, avec les coûts conséquents. De nombreux articles ont été écrits sur le sujet, qui reste néanmoins très ouvert.

La deuxième limitation tient cette fois aux hypothèses fortes des techniques de mise en œuvre des classes, et en particulier des variables de classe, ce qui limite leur transposition immédiate à un univers réparti. Il semble difficile, à moins d'introduire des mécanismes transactionnels compliqués, de garantir que la mise à jour d'une variable de classe soit immédiatement reflétée sur toutes les instances d'une classe, lorsque celles-ci sont situées sur plusieurs machines. Ce problème se pose pour des variables globales en général, mais est accentué dans les langages à objets car des variables de classes sont souvent implicitement utilisées par le programmeur, qui ne se rend pas toujours compte que ce sont des variables globales dont la mise en œuvre est très coûteuse dans un contexte réparti.

Enfin, la troisième limitation est relative à la notion de duplication, particulièrement utile pour tolérer les défaillances. Si elle est appliquée directement aux objets, la duplication provoque des incohérences d'exécution. Les protocoles de communication définis pour contrôler la duplication des services dans un système réparti considèrent un modèle client/serveur simple. L'application des mêmes protocoles aux objets pose le problème de la duplication des invocations. En effet, un objet agit généralement à la fois comme un client et un serveur. Autrement dit, s'il est dupliqué en tant que serveur, l'objet peut à son tour invoquer d'autres objets en tant que clients. Toutes les copies de l'objet invoqueront alors le même objet plusieurs fois. Le résultat est la duplication inutile des invocations. Cette duplication peut conduire au meilleur des cas à l'inefficacité du système, et au pire des cas à des incohérences. Une même opération (par exemple d'incrémentation) peut ainsi être exécutée plusieurs fois plutôt qu'une.

VI-C. Vers une troisième approche complémentaire

L'approche appliquée permet d'offrir au programmeur de systèmes des mécanismes ou/et des concepts pour gérer la répartition. Les concepts de généricité et de classe permettent de structurer ces mécanismes et concepts en une véritable palette de mécanismes et de solutions. Cependant, plus encore qu'une palette de solutions, il est judicieux de permettre une extensibilité plus générale, c'est-à-dire d'offrir une méthodologie et des moyens lui permettant d'exprimer et de construire des solutions spécifiques si nécessaire, sans pour cela modifier l'application préalablement développée, c'est-à-dire de manière transparente à l'application.

L'approche intégrée offre cette transparence en fusionnant les concepts d'objet et de répartition. Néanmoins, les systèmes intégrés peuvent fixer trop tôt leurs modèles d'exécution et de communication. Le langage de programmation délègue alors la gestion des ressources, telles que le placement des objets et le séquencement des tâches sur chaque processeur, au système d'exécution sous-jacent. La sémantique du système est sinon précâblée, du moins non modifiable au niveau du langage lui-même. Même si le langage offre des facilités de changement des caractéristiques du modèle de calcul, et de gestion des ressources, le programme devient alors moins lisible et surtout moins réutilisable, du fait du mélange du texte du programme même, avec les portions spécifiant le contrôle.

Une troisième approche se dégage pour combler ces lacunes: l'approche réflexive. Elle a pour objectif de faire apparaître, au niveau du langage de programmation, diverses caractéristiques de représentation (statiques) et d'exécution (dynamiques) du programme. Ces caractéristiques sont décrites et modifiables par l'intermédiaire d'un métaprogramme. La réflexion est une version de la métaprogrammation, où le métaprogramme est décrit dans le langage lui-même. Ceci offre ainsi l'avantage d'une approche plus homogène, le même langage étant employé, pour l'écriture des programmes, comme pour leur contrôle. L'approche réflexive est, en quelque sorte, un moyen terme entre l'approche intégrée et l'approche appliquée, car elle permet d'intégrer intimement les (méta) bibliothèques avec le langage, tout en les séparant du programme. De nombreuses architectures réflexives sont actuellement proposées et évaluées, mais il est trop tôt pour dégager, et valider, une architecture réflexive générale pour la programmation répartie. Un des problèmes est la complexité éventuelle des architectures réflexives, qui est en partie lié aux possibilités accrues de paramétrisation qu'elles offrent. Un autre problème est celui de l'efficacité, du fait des indirections et interprétations supplémentaires que la réflexion peut entraîner. L'évaluation partielle est actuellement proposée comme une des techniques permettant de réduire ces surcoûts. Les notions de filters ou de smart proxies dans certaines mises en œuvre de CORBA peuvent être vues comme un premier pas d'une approche réflexive pragmatique dans l'industrie.

VII. Pour en savoir plus

Sur les recherches dans le domaine des objets répartis, de bonnes sources d'informations sont les actes des conférences OOPSLA (International Conference on Object Oriented Programming Systems, Languages, and Applications), publiés par l'ACM dans la collection Sigplan, et les actes de la conférence ECOOP (European Conference on Object Oriented Programming), publiés par Springer Verlag dans la collection Lecture Notes in Computer Science. Pour en savoir plus sur les produits commerciaux, il suffit de demander à votre moteur de recherche préféré sur le Web de trouver Java RMI, ONE, CORBA, ou DCOM.

VIII. L'auteur

L'auteur Rachid Guerraoui est Professeur associé au Laboratoire de programmation distribuée à l'Ecole Polytechnique Fédérale de Lausanne.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2005 Rachid Guerraoui. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.