| |
Objet et Répartition
Le Grand Mariage
Rachid Guerraoui,
Laboratoire de Systèmes d'Exploitation, Département d'Informatique
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.
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 moeurs, 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.
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 oeuvre, 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
oeuvre. 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é.
Le grand mariage
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.
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 oeuvre 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.
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.
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 oeuvre
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 !
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.
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).
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.
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.
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 multi-agents (les fameuses sociétés de
fourmis en intelligence artificielle).
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 terme
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 2ème 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 3ème niveau (synchronisation
inter-objets), 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'occurence, 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 oeuvre les deux objets
représentant les comptes bancaires.
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 invoquable (e.g., un
serveur Web), il est important pour cette société que les utilisateurs ne
puissent pas connaître la mise en oeuvre 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 oeuvre 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.
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 oeuvre 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
Inter-ORB Protocol), ces objets peuvent communiquer à partir de différentes
mises en oeuvre 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
oeuvre 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 oeuvre 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.
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 oeuvre 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 oeuvre 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).
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.
Figure 3 - Migration et invocation à distance sur le Web
ONE
Netscape communications a présenté en 1996 sa propre mise en oeuvre 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.
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).
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 Inter-Net Applications):Retour
à la table des matières
À 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).
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 oeuvre 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 oeuvre 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 oeuvre 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.
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é-cablé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éta-programme. La réflexion
est une version de la méta-programmation, où le méta-programme 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 oeuvre de CORBA peuvent être vues comme un premier pas d'une
approche réflexive pragmatique dans l'industrie.
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.
Notes
- Pour ceux qui ne le savent pas (encore), Java signifie café
en argot américain
- Comme me l'a fait remarqué Benoît Garbinato au LSE: Ça c'est du
marketing!
| |
Michel RIVEILL

Laboratoire I3S - Bât. ESSI
930 Route des Colles
06903 Sophia Antipolis CEDEX
email :
riveill at unice.fr
Généralité
Ressources en lignes
Les rubriques des cours :
dernière mise à jour
le 18 septembre 2003
|