Fichier PDF

Partagez, hébergez et archivez facilement vos documents au format PDF

Partager un fichier Mes fichiers Boite à outils PDF Recherche Aide Contact



nat thesis .pdf



Nom original: nat_thesis.pdf

Ce document au format PDF 1.2 a été généré par FrameMaker 5.5.3L15a / Acrobat Distiller 3.0 for Windows, et a été envoyé sur fichier-pdf.fr le 23/07/2011 à 09:58, depuis l'adresse IP 95.165.x.x. La présente page de téléchargement du fichier a été vue 1635 fois.
Taille du document: 1.5 Mo (176 pages).
Confidentialité: fichier public




Télécharger le fichier (PDF)









Aperçu du document


Imperial College of Science, Technology and Medicine
University of London
Department of Computing.

Component Interaction in Distributed Systems

Nathaniel G. Pryce.

A Thesis submitted in partial fulfilment of the requirements for the degree of Doctor of Philosophy in the Faculty
of Engineering of the University of London, and for the Diploma of the Imperial College of Science, Technology
and Medicine

January 2000

1

2

Abstract
Component based development is seen as a way to increase programmer productivity and reduce software maintenance costs through the reuse of off-the-shelf software components. Component-based development is distinguished from object-orientation in that systems are defined by the composition of black-box components that
interact according to well-defined protocols. Current component models define interaction protocols between components as object interfaces. Such an approach is limited: an interface can only describe bundles of synchronous,
request/reply operations, but cannot specify the protocol by which those operations must be invoked or how multiple interfaces are to be used in concert. Yet all but the simplest component models define interaction protocols
that involve multiple parties, many-to-one communication or concurrency between communicating parties.

We introduce a model of component interaction that addresses the limitations of object invocation. This interaction
model is used as the basis for a language, Midas, that is used to define interaction protocols between components.
Midas definitions can be annotated with formal specifications of properties of the protocol. We show how the use
of a notation to define the interaction protocol allows one to mechanically check the behaviour of the interaction
protocol over different transports, thereby catching errors at the design stage. Models can also be translated into
test code.

Midas definitions are compiled into runtime support code that makes use of the transport framework. This framework hides the platform-specific transport API and defines transport protocols as compositions of lightweight components. This componentisation of the transport protocol allows the designer to select the most appropriate protocol
for each binding and insert additional functionality, such as compression or encryption, above existing protocols.
Tests show that this componentisation does not effect the latency or throughput of a binding compared to the use
of a traditional implementation.

3

Acknowledgements
I would like to thank the members of the Distributed Software Engineering group for their advice and support. In
particular I would like to thank Naranker Dulay, my supervisor, Morris Sloman, Jeff Kramer and Jeff Magee, and
ex-members of the group, Steve Crane, Kevin Twidle and Hal Fossa, for many stimulating discussions. The research in presented in this thesis was funded by British Telecom through the Management of Multiservice Networks project. I would like to thank Ian Marshall, Paul McKee and Sohail Rana of British Telecom Laboratories,
for valuable feedback about the use of Midas and the Regent run-time frameworks.

The work presented in this thesis is built upon research performed over several years within the Distributed Software Engineering Group, especially the Darwin/Regis system and the TRACTA project.

The Regis system was originally developed by Jeff Magee, Stephen Crane and Kevin Twidle. The second version
of the Regis system was developed by Stephen Crane and the author. The runtime system presented in this thesis,
Regent, differs from Regis in several ways:
• Regis does not specify component interaction protocols separately from their implementation. Regis interaction protocols are defined solely by their implementation as C++ endpoint classes.
• Regis does not separate the concerns of application and presentation-layer protocols: endpoint classes are
responsible for marshalling messages and interfacing with the transport protocol stacks. Therefore, Regis
does not support the ability to plug application-layer protocol filters into a binding.
• Regis cannot generate marshalling code because there is no separate specification of the application-layer
protocol. Programmers writing endpoint classes must implement marshalling themselves. In practice, this
means that Regis endpoints can only transmit flat data structures.
The transport framework presented in this thesis is similar to that used by Regis. However, the model of control
and event interfaces is significantly different. Regis protocol layers pass control messages up and down the stack
to notify higher layers of significant events or request control operations from lower layers. Regent protocols provide control interfaces and JavaBean events that can be queried from higher in the stack. Regent allows bindings
to specific control and event interfaces to bypass layers that have no interest in those interfaces, while Regis control
messages must pass through all intermediate layers in the stack. The Regis transport framework does not support
the implementation of composite layers – layers defined solely as compositions of other layers – or provide a registry for giving stack descriptions well-known, human-friendly names.

The Darwin language was designed by Narankar Dulay, Jeff Kramer and Jeff Magee. The FSP notation and LTSA
model checker were designed and implemented by Jeff Magee, based on the work of Dimitra Giannakopolu, Jeff
Kramer and Sing-Chi Cheung.

4

For Dorothy Cannon.

5

Table of Contents

Table of Contents
Abstract. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Table of Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
List of Figures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
List of Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Chapter 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.1. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2. Example Scenario: An On-line Record Shop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3. Conclusions from the Example Scenario. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.4. Structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Chapter 2. Component Interaction in Distributed Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.1.1. A Brief History of Distributed Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2. Requirements of a Middleware Platform. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.3. Object Oriented Middleware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3.1. RM-ODP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3.2. CORBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3.3. COM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3.4. Java Beans, RMI, and Enterprise Java Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3.5. Reflective Middleware. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.4. Architecture Description Languages and Connectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.4.1. Polylith. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.4.2. Darwin/Regis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.4.3. OLAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.4.4. UniCon. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.4.5. Wright, Aesop and ACME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.5. Transport Protocol Frameworks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.6. Others. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.7. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Chapter 3. A Model of Component Interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.2. Abstract View of Component Interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.2.1. Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.2.2. Synchronisation Between Components over a Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.2.3. Control of Bindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.2.4. Transport Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.3. Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Chapter 4. Midas: A Language for Specifying Interaction Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.0.1. LongSlot Interaction Style. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.0.2. Slot Interaction Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.0.3. Mport Interaction Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.0.4. Func Interaction Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.0.5. Event Interaction Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.0.6. Attribute Interaction Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.1. Modelling Bindings in FSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
4.2. Modelling Components in FSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
4.3. Supporting Endpoint Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.3.1. Guiding Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

6

Table of Contents
4.3.2. Runtime Verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
4.4. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Chapter 5. Case Study: On-line Music Shop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.3. System Architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
5.4. Media Processing Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.5. Comparison with CORBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.6. Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Chapter 6. Mapping Midas To Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
6.1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
6.2. Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.3. Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.4. Basic Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
6.5. User-Defined Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
6.5.1. Marshalling Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
6.5.2. Enums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
6.5.3. Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
6.5.4. Typedefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
6.6. Interaction Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.6.1. Message Interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.6.2. Endpoint Stubs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
6.6.3. Support for Third-Party Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
6.6.4. Proxies and Service Access Points (SAPs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
6.6.5. Reference Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
6.7. Additional Mappings for Interaction Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
6.7.1. Reified Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
6.7.2. Datagram Proxies and SAPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
6.8. Generic Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
6.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Chapter 7. Transport Protocol Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
7.1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
7.2. Requirements of the Transport Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
7.3. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
7.4. Implementation of Protocol Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
7.5. Memory Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
7.6. Addressing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
7.7. Connection-Oriented Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
7.8. Transport Filters. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
7.9. Construction of Protocol Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
7.9.1. Automatic Stack Elaboration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
7.10. Protocol Registry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
7.11. Concurrency and Synchronisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
7.12. Available Protocol Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
7.13. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Chapter 8. Performance Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
8.1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
8.2. Comparing Middleware Platforms. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
8.2.1. Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
8.2.2. Relative Code Sizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
8.3. The Effect of Different Interaction and Transport Protocols. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
8.4. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Chapter 9. Conclusions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
9.1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
9.2. Contributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
9.3. Critical Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
7

Table of Contents
9.4. Further Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
9.4.1. A General Connector Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
9.4.2. Improved Support for Dynamic Composition of Transport Layers . . . . . . . . . . . . . . . . . . . . . . 159
9.4.3. QoS-Directed Transport Construction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
9.4.4. Runtime Visualisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
9.5. Closing Remarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Appendix A. Midas Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
A.1. Comments and Preprocessing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
A.2. Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
A.3. Interaction Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
A.4. Constant Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
A.5. Modules. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Appendix B. FSP Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
B.1. Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
B.2. Composite Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
B.3. Common Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
B.4. Properties. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

8

List of Figures

List of Figures
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.

Overview of the on-line record shop application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
CORBA interceptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
A graphical Java Bean development tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
An EJB deployment tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
The structure of a hierarchical open binding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
A simple filter pipeline in Darwin’s graphical and textual syntaxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
OLAN connector objects between collocated and distributed components . . . . . . . . . . . . . . . . . . . . . . . . 38
Abstract view of the interaction model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Binding from client endpoint to service, and backbinding from service to client . . . . . . . . . . . . . . . . . . . 52
Client and service proxies provide distribution transparency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
SAPs identify service endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Synchronisation between concurrent components using the Attribute interaction . . . . . . . . . . . . . . . . . . . 55
Control interfaces allow management of bindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Multicast used for an event interaction protocol. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
The endpoints of an interaction represented graphically as FSP processes . . . . . . . . . . . . . . . . . . . . . . . . 63
Behaviour of the LongSlot endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Java Implementation of Func client endpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Potential error caused by binding between address spaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Example executions of the Attribute interaction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Constraint properties of the Attribute interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
FSP model of the client endpoint of the Attribute interaction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
FSP model of the service endpoint of the Attribute interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
FSP model of the value held by an Attribute service.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
FSP model of how client requests are queued at an Attribute service. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
The property to check that the queue of an Attribute service does not overflow. . . . . . . . . . . . . . . . . . . . 82
A model of C clients bound to a server in the same address space. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Modelling bindings over a transport protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
One-slot buffer modelled in FSP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Reliable, ordered, simplex and duplex connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Unreliable, ordered, simplex connection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Reliable, Unordered Simplex Connection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Unreliable, unordered simplex connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
A primitive component modelled as FSP processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
An animator allowing interactive exploration of a Midas interaction protocol . . . . . . . . . . . . . . . . . . . . . 87
Test filters can be monitored by remote management agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Overview of the on-line record store application.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Architecture of the record shop server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Architecture of the record shop client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Instantiations of generic interaction types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Components used to stream audio data between address spaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Source component for streaming audio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Sink component for streaming audio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
An example system that streams media between two address spaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
The MediaStream interaction type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Model of the MediaStream client endpoint for 1-bit sequence numbers . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Model of the MediaStream service endpoint for 1-bit sequence numbers . . . . . . . . . . . . . . . . . . . . . . . . 100
Classes of the record shop application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Placement of CORBA objects onto servers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Sequence classes that hold primitive types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Classes for the Attribute interaction type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
The Binder class generated for the Attribute interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Generated classes that implement distribution transparency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

9

List of Figures
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.

Classes supporting generic types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Protocol layer interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Protocol layers composed into a stack, showing control and event connections . . . . . . . . . . . . . . . . . . . 128
Session layers created by a multiplexor for each of its clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
ProtocolService interface definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
MultiplexorService interface definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Static structure of the memory management classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Time taken to write data to a BufferOutputStream and ByteArrayOutputStream . . . . . . . . . . . . . . . . . . 134
Immutable address objects can be shared . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Address objects are constructed from header fields of received messages. . . . . . . . . . . . . . . . . . . . . . . . 136
Static Structure of TransportFilter Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Threads in the protocol stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Architecture of the Midas experiment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Comparison of CORBA, RMI and Midas performance.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Sizes of the three test programs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
The effect of transport layers on throughput. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
The effect of interaction style on throughput . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Modules used to group definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

10

List of Tables

List of Tables
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.

A common synchronisation error detected by static analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Midas modules mapped to java packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Midas constant declaration mapped to Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Primitive Midas types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Midas enum mapped to a Java class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Midas struct mapped to Java class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Midas typedefs mapped to Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Message interfaces generated from a Midas interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
A Midas interaction instance mapped to Java. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Type objects representing primitive types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
The type object generated for each user defined type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Genericity support generated from a Midas specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Example transport filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Protocol components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
CORBA and RMI interfaces for the performance experiment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Primitive Midas types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
An example Midas enumerated type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Basic structured Midas types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Data structure definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Generic structure declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Type aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
An example interaction definition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Constant definitions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Process operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
Composite process operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Common process operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Safety and progress properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

11

1. Introduction

Introduction

The last thing that we find in making a book
is to know what we must put first.
Blaise Pascal

1.1. Motivation
As the demand for distributed computer services rises, so does the need to easily construct, deploy and maintain
such services in heterogeneous environments, where multiple types of network, end system hardware, operating
system and programming language must be integrated. This has led to the development and standardisation of
“middleware” systems - software environments that hide platform and language specific details and provide runtime support for transparent distributed processing.

Current middleware systems focus mainly on supporting communication between modules of the system. The object oriented paradigm has become the most widely accepted model for middleware systems [ODP95, OMG98,
EE98]. An object-oriented system is composed of objects that make services available to other objects in the system
through polymorphic interfaces comprised of request/reply operations by which clients can request a service and
receive some reply. However, object-oriented systems do not provide much support for creating and managing the
bindings between objects: bindings are hidden within object implementations and are usually established by the
object that uses the binding searching a name service or trader or through out-of-band mechanisms. Such bindings
are known as “first-party bindings” and complicate the system by hiding the architectural details within objects
and including code to establish bindings and handle binding errors with the functional code within each component.

Component-based development [SG96] is a refinement of object orientation that aims to solve the problems inherent in the use of first party binding. A component is an object that supports a compositional approach to system
construction by exposing at its interface both the services it provides to and those it requires from other components, and providing operations to allow its required services to be bound to those provided elsewhere. Component
reuse is facilitated by defining standard inter-component protocols for application-independent tasks - serialisation
or database access for example - and tasks specific to some application domain - media processing or healthcare
management for example. Systems are constructed by a instantiating components and binding their interfaces together. A binding between two components is performed by some other party, usually a composite component that

12

1. Introduction
encapsulates the components being bound. This binding model, known as “third-party binding” [Fried87], separates the algorithmic details of the system encapsulated within components, from the architecture of the system encapsulated within the code performing the binding actions. The architecture of a system can be defined
declaratively using an architecture description language (ADL) [MDEK95] that is compiled into low-level code
that performs the binding actions to elaborate the architecture, or visualised graphically.

As they grow in sophistication, distributed systems will require more sophisticated and more varied styles of intercomponent interaction beyond the many-to-one, synchronous request/reply invocations provided by object-oriented middleware. For example:
• Financial systems use one-to-many event notification to announce stock-quotes to brokers’ terminals.
• Compute-intensive parallel processing tasks require components to execute concurrently as much as possible and so use asynchronous message passing between components.
• The rapid acceptance of the Internet, especially as a consumer medium, has led to demands for distributed
multimedia services, such as telephony and video, that differ radically from data processing, the traditional
application domain of distributed computing systems, and require different qualities of service, such as
reliability and timeliness.

A major weakness of current middleware platforms is that they typically only provide the programmer with a single
form of interaction between components. This makes it difficult to build a system that requires a richer set of interaction styles. Other interaction styles must be implemented either in terms of the interaction style provided by
the middleware platform or by using some lower level services so losing any advantages of using the middleware.

1.2. Example Scenario: An On-line Record Shop
As an example, let’s examine a potential application that is receiving a great deal of interest from consumers and
industry at the moment, that of selling music over the network. In such a scenario, multiple service providers maintain databases of digital music tracks. A client wanting to buy music browses the tracks available at an on-line
record store and can listen to streamed samples of tracks in which they are interested before paying for and downloading high-quality versions of the files onto their local computer or hi-fi.

From the short above description we can identify some of the high-level components of the system, as shown in
figure 1. The on-line record store is accessed through a component that maintains the database of information about
the music in the store. The music itself is stored in one or more media stores. Components can be instantiated on
these media stores to stream a low-resolution preview of the music or to download the file to the client’s hi-fi. The
client program is made up of components that allow the user to visually browse the contents in the store, receive

13

1. Introduction
and play streams of audio, and download purchased files onto the client’s computer or hi-fi. Further components
are used within the major application components to stream audio data to and from disk or audio devices and to
process audio streams, to convert between formats for example.
Client

Record Shop

Media Stores

Browse

Purchase

Control

Download
Music

HiFi

Preview Music

Download Music

Figure 1. Overview of the on-line record shop application.
These components must interact in different ways and different interactions, and even separate uses of the same
interaction type, need different qualities of service and levels of security. The client browses the contents of the
music store by invoking request/reply operations over a reliable connection. When requesting a preview of a track,
the client will receive a stream of continuous media, which does not have to be reliable but requires some guaranteed bandwidth and maximum jitter. When requesting purchase of one or more files, the client again uses a request/
reply transaction over a reliable connection; however, unlike the connection used for browsing, the connection used
for requesting a purchase must also be secure. Finally the music files are transferred to the client over a pipe that
efficiently transfers large amounts of data; this interaction also requires a reliable, secure connection.

It is easy to use CORBA [OMG98] to implement the services that allow clients to browse and purchase the available music tracks because the request/reply interaction style required for browsing is the(only) interaction style
supported by CORBA. The security required to handle on-line payment is complicates matters, but is implemented
by the CORBA security service, a standard that defines secure interoperability protocols and management interfaces implemented in terms of ORB mechanisms. The security service is not a standard component of the CORBA
platform, and so one must make sure to purchase an ORB that implements this standard.

Streaming preview versions of music to the client is more complex, however. The reliable request/reply interaction
abstraction used by CORBA objects is not appropriate for the streaming of continuous media because the reliability
mechanisms and the synchronisation between client and server reduce the smooth delivery of data and so disrupt
playback. Interfaces for controlling media streams are defined by the CORBA telephony standard, a domain-specific facility defined in terms of the CORBA ORB and base services, but there are currently no available implementations. Thus the programmer is forced either to integrate the CORBA ORB with another middleware platform
that provides support the media streams and other interaction styles they require, or to implement media streams
themselves, using non-portable operating system mechanisms, and integrate their own mechanisms with the ORB.

14

1. Introduction
We will develop this scenario in more detail in chapter 5, to illustrate how the demands of this application are met
by the software environment and tools resulting from this research.

1.3. Conclusions from the Example Scenario
We can see that even in this small example, components of a distributed system must communicate in a variety of
ways, but that current middleware platforms do not adequately support these requirements. Middleware, therefore,
must allow programmers to specify a wider variety of component interaction protocols than is currently possible.
As supported by current middleware, programmers must be able to compile these specifications into the runtime
support required to construct the system: support for binding, distribution transparency, monitoring and management. However, protocols that are more complex than sequences of synchronous request/reply pairs are both harder
to design correctly and harder for programmers using the protocol to understand. These drawbacks can be overcome by defining precise, formal specifications of each interaction protocol, both to unambiguously describe the
protocol to those who must implement it and to allow design-time error detection by mechanical means.

This thesis introduces a model of interaction between distributed components and a language that is used to define
interaction styles based upon this interaction model. A major advantage of this interaction model and language is
that it supports both the design-time analysis of interaction styles and the construction of components and systems
that make use of those interaction styles. Design is supported by including specifications of the interaction protocol
that can be checked mechanically for deadlock or violation of user-defined constraints. Construction is supported
by translating these specifications into implementation language constructs that provide the “glue” to connect components using the interaction style whether they are in within the same address space or distributed across the network. Moreover, our approach links the design and construction phases by translating interaction specifications
into objects that can be inserted into bindings to check that components interacting over those bindings conform to
the specified interaction protocol.

1.4. Structure
The rest of this thesis is structured as follows. In chapter 2 we examine the current state of the art in component
interaction models for distributed systems and highlight the advantages and shortcomings of the various approaches. This concludes with a set of requirements that a system should meet to support programmers in defining system
architecture in terms of communicating components. In chapter 3 we introduce our model of intercomponent interaction and the Midas language used to specify intercomponent interaction protocols and show how this model
and language meet the requirements identified in chapter 2. We show how the Midas language integrates with existing modelling and CASE tools to support design-time mechanical analysis of interaction protocols and entire
systems that follow our component model. Chapter 5 elaborates on the scenario of section 1.2, showing how a media-on-demand application is designed and built in terms of components communicating via Midas interaction
styles. Chapter 6 describes in detail how Midas definitions are translated into the Java programming language and
Chapter 7 describes the Java component framework for implementing transport protocols. Chapter 7 examines the

15

1. Introduction
effect our approach has on the performance of a system and shows that the approach has a negligible effect and can
in some cases improve performance. Finally, chapter 9 summarises the contributions of this thesis and examines
how the work can be taken further.

16

2. Component Interaction in Distributed Systems

Component Interaction in
Distributed Systems
I may not agree with what you say, but I'll defend to the
death your right to say it
Voltaire

2.1. Introduction
Distributed systems are constructed from components that interact together to perform common tasks. The architecture of a system can be viewed as the composition of its components and the bindings between them. This chapter examines how current distributed programming environments support the design of system architecture and
component interaction styles and the mechanisms that realise these architectures and interaction styles at run-time.

2.1.1. A Brief History of Distributed Programming
Computers were first connected by networks during the late 1960s. At the time, processing resources were limited
and operating systems simple. Programmers writing distributed programs were responsible for implementing all
of the required communication code, even to the level of driving the link-layer hardware. In the early 1970s, researchers on the ARPANET project recognised the need to pass messages between different network architectures
and formulated the “internet problem”: how to get computers to communicate across multiple packet networks
without knowing underlying the network technologies.

A year later, they published the TCP protocol to solve the internet problem. At the time TCP handled both transport
and internetwork concerns. The separate concepts of transport and internetwork protocol were developed later,
when TCP and IP were separated to allow the implementation of UDP over IP. Transport protocols simplify distributed programming by providing the programmer with higher-level communication abstractions, such as a reliable byte streams, hiding the unreliable, packet-based nature of the underlying internet protocols.

17

2. Component Interaction in Distributed Systems
Until the early 1980s, IP and TCP were typically implemented as user-level processes and programs used platform
specific interfaces to make use of these implementations. As operating systems became more sophisticated, the implementations of link-layer, internet and transport protocols became integrated into the kernel and provided to application programmers through standard APIs, such as the “sockets” API introduced in release 4.2 of Berkley
UNIX [Steve97].

The use of standard programming interfaces allow programmers to easily port applications to different architectures. However, in a heterogeneous internet, programmers have to handle communication between programs running on different architectures or written in different programming languages. Transport protocols only provide
data transmission services between applications and the application must translate data structures to and from raw
bytes and convert data between representations used by different architectures and languages. To address this requirement, standard presentation layer protocols, such as XDR [RFC1832], were developed to define a standard
format by which primitive and structured types are converted to and from bit strings. Types are defined in a specification language that is compiled into type definitions and marshalling code in some programming language. By
using a separate specification language, programs written in different languages can easily communicate structured
data.

For programmers familiar with procedural, structured programming, building distributed programs using only
presentation and transport protocols is complex. The abstraction by which local program modules are used – the
procedure call – is different that by which remote modules are used – message passing. Remote procedure call
(RPC) [BN84] was invented in the early 1980s to extend the procedure call abstraction between address spaces,
providing the same mechanism for invoking both local and remote services. An RPC server exposes its services
through a set of procedures. These procedures are defined using a definition language that specifies the names and
types of the server’s procedures. This definition is compiled into client side and server side stubs. Client side stubs
appear to be local procedures, but marshal and send arguments to a remote server and then wait for and unmarshal
the server’s reply. Server side stubs receive messages, unmarshal parameters, invoke the appropriate procedure of
the server and then marshal and send any returned data to the client.

RPC provided programmers with a familiar programming model for building distributed applications but had the
drawback that it was hard to build programs that were dynamic: those in which servers created and removed services during their lifetime, and didn’t match the object oriented style of programming that was becoming prevalent.
Object oriented middleware systems, developed during the late 1980s and early 1990s, have become the predominant form of distributed programming environment and procedural RPC is now used only rarely. OO middleware,
such as CORBA or DCOM, makes use of current programming language features, such as polymorphism and exception handling, to provide a simpler programming model for the construction of distributed programs.

18

2. Component Interaction in Distributed Systems

2.2. Requirements of a Middleware Platform
Although current object-oriented middleware platforms provide the programmer with a great deal of support in implementing the communication between modules of the system, they have a number of drawbacks. In particular,
object oriented middleware does not provide much support for deploying components onto nodes of a network or
for establishing communication paths (bindings) between those components. Because objects are defined by their
provided services only and do not expose the services that they require, objects must be responsible for connecting
themselves to services that are provided by other objects. This increases each object’s dependence on its context,
reducing the scope for its reuse, and pollutes its implementation with irrelevant structural details.

Furthermore, objects are limited to very few forms of interaction, typically either RPC-like object invocation or
asynchronous message passing. Some middleware platforms include other interaction mechanisms as ad-hoc extensions. Otherwise programmers must implement other interaction mechanisms in terms of the predominant style
or in terms of lower level mechanisms, such as platform specific networking APIs, that are more complex and error
prone to use.

Finally, no commercial distributed programming environments supports design-time modelling and analysis of
components, forms of interaction or systems composed from these architectural parts.

The requirements of a middleware platform are:
• Component Model. A middleware platform should present the programmer with a coherent component
model that defines how a system is composed from individual components of functionality. The component
model should defines how a component’s interface is defined in terms of the services provided and required
by the component. It should also define how components are packaged for deployment and instantiation,
and how instantiated components are composed by binding components that require a service to compatible
services provided by other components. The component model should provide some way of managing the
complexity of large systems, by hierarchical composition, for example. The component model should also
support visual programming, allowing the designer to specify compositions of components with graphical
tools.
• Binding. The middleware platform should support both first-party and third-party binding establishment.
First-party binding involves the client component locating and establishing a connection with the service
that it requires. Third-party binding involves a third party, neither the client nor the service provider, that
establishes bindings between the components that require a service and those that provide the service. A
middleware platform must support both static binding, creating connections between components that do
not change during the lifetime of those components, and dynamic binding, allowing components to be dynamically constructed and destroyed during the lifetime of the system or dynamically start and stop communicating with services during their lifetime. The middleware should be able to establish bindings over
different transport protocols, allowing the designer to select the most appropriate transport for each binding.

19

2. Component Interaction in Distributed Systems
• Open Interaction Styles. The system must not constrain the system designer to a single or limited number
of interaction styles between components. The designer should be able to select or design interaction styles
appropriate to their needs, choosing between synchronous or asynchronous communication and one-to-one,
many-to-one or one-to-many communication. Interaction styles should be independent of transport protocol, allowing transport functionality and quality of service to be selected independently for each binding.
• Interaction Style Specification. The designer should be able to specify new interaction styles. Specifications should not be tied to any specific programming language. The specification language should support
the requirements of open interaction styles, listed above. It should be possible for the programmer to compile interaction specifications into code that supports the implementation, composition and distribution of
components that use those interaction styles.
• Formal Modelling. Interaction styles that are more complex than synchronous request/reply will require
unambiguous definition. Formal modelling of interaction protocols allows interaction styles to be precisely
defined and supports design-time analysis of the protocols to check for errors, such as deadlock between
communicating parties or buffer overflow.
• Transport Protocols. As well as selecting appropriate transport protocols for individual bindings, a middleware platform should allow individual transport capabilities, such as encryption, compression, reliability, fragmentation and reassembly, to be easily combined and make it easy to extend the available transport
protocols with new functionality. This also necessitates the naming of transport protocols in terms of their
components and the dynamic construction protocols that are compatible with remote protocol stacks.
• Management and Adaption. The middleware platform should support runtime management by exposing
interfaces by which middleware layers can be controlled and announcing events when state changes and errors occur. These interfaces should be accessible to the application components, allowing runtime adaption
of its middleware platform, and to external management agents.

2.3. Object Oriented Middleware
OO middleware platforms define systems in terms of objects as the main unit of architectural structure. An object
encapsulates state and behaviour behind an abstract interface. An object’s interface is usually specified in an interface definition language (IDL) independently from the language used to implement its behaviour. The IDL definitions are used to generate runtime mechanisms that allow object invocations to be performed between address
spaces.

2.3.1. RM-ODP
RM-ODP [ODP95] is a joint ISO and ITU standard, defined during the early 1990s, to standardise architectural
concepts for distributed computing. It is intended to aid the development of future standards for distributed computing platforms rather than define a standard platform itself. RM-ODP presents distributed computing systems

20

2. Component Interaction in Distributed Systems
from five viewpoints, concepts in higher level viewpoints being mapped to one or more lower level concepts in
others. Of relevance to this thesis are the Computational Viewpoint, that defines the functional abstractions of a
distributed system in a distribution-transparent manner, and the Engineering Viewpoint that describes how the system implements the computational viewpoint.

The computation viewpoint views a distributed system as a set of interacting objects. An object provides one or
more interfaces through which it makes its services available to other objects in the system. RM-ODP defines three
types of interface: operational, stream and signal interfaces. An operational interface defines one or more one-way
and request/reply operations that can be invoked upon an object. A stream interface defines one or more flows of
continuous media accepted by the object. Both operational and stream interfaces are defined in terms of signals,
low level operations that correspond to local procedure calls; operations and streams are the only interactions that
are supported between address spaces.

In the computational viewpoint, objects interact via bindings between their interfaces. RM-ODP does not specify
who initiates the binding, thereby allowing both first-party and third-party binding to be supported by the model.
Bindings are either primitive, directly connecting two interfaces, or are compound, being supported by binding objects that are themselves bound between the two interfaces. In the engineering viewpoint, a binding object corresponds to a channel, a concept that represents the communication mechanism used by the distributed system. A
channel is composed of stubs, binders and protocols. Stubs perform processing that requires knowledge of application semantics, binders perform processing that does not require application semantics and can be performed on
raw bit-streams, and protocols transmit the bit-streams between address spaces.

Because RM-ODP defines only concepts, is understandably vague as to exactly how objects and systems are defined and deployed. It does not prescribe any interface definition language or any method of constructing systems
and does not define its model of object behaviour and interaction with any formality. A system could be constructed
by composing components using an architecture description language, or it could be constructed using first-party
binding with clients finding servers via naming and trading services. Considering this generality, it is strange that
the standard limits components to only two interaction styles and treats stream bindings as fundamentally different
from operation bindings at the engineering level when much of the infrastructure of a distributed system - such as
the transport protocol framework - is not fundamentally different for the two interaction styles.

The concepts of the RM-ODP were realised in the ANSA system [APM93]. ANSA provided an interface definition
language compiler and runtime support so that object interfaces defined in the IDL could be implemented in C programming language. Recent developments of the CORBA standard have specified features that are compatible
with the concepts of RM-ODP, including naming and trading services and facilities for controlling media streams,
and RM-ODP has adopted the CORBA IDL as an ISO standard. However, the main aim of RM-ODP is to provide
conceptual models rather than implementable standards that can be used to build interoperable distributed systems.

21

2. Component Interaction in Distributed Systems

2.3.2. CORBA
CORBA [OMG98] is a middleware standard defined by the Object Management Group (OMG). Implementations
of the CORBA standard are available from commercial vendors, such as Orbix by Iona [Iona99] and Visibroker by
Inprise [Inprise99], as free software, a list of which is published on the web by the OMG [OMG99], and as one of
the standard libraries of the Java programming language [AG98]. CORBA has been used to build systems ranging
from modular graphical user interfaces to large, distributed, secure, fault tolerant IT applications.

Interaction Styles. CORBA provides the programmer with an object-oriented model of distribution. Servers
export services to clients as objects that conform to abstract interfaces. Object interfaces are defined using the
CORBA Interface Definition Language (CORBA-IDL, or merely IDL), standardised by the OMG and ISO. CORBA-IDL supports the definition of constants and data structures as well as object interfaces. Object interfaces are
defined in terms of named, typed, read-write or read-only attributes and operations that can take multiple named,
typed parameters and return multiple values or throw exceptions. The CORBA standard defines mappings from
IDL to various programming languages, allowing the server and clients to be written in different languages. Each
mapping defines how constants, data types, interfaces and exceptions defined in IDL are represented in the target
language. Interface definitions are usually compiled into client side (proxy) and server side (skeleton) marshalling
code that is itself compiled and statically linked into the application.

The CORBA IDL language defines interfaces as sets of synchronous request/reply operations or asynchronous
one-way messages. This has several disadvantages. Clients are forced to synchronise with servers and cannot take
advantage of concurrency between the operation of the client and that of the server to improve performance. Oneway operations are not guaranteed to be issued asynchronously and the CORBA standard provides no guarantee of
their reliability, so they cannot be relied upon in a portable program unless that program implements reliability itself.

Clients bind to objects and invoke their operations to make use of the service. Binding is performed by the Object
Request Broker (ORB), the fundamental component of the CORBA architecture. The ORB identifies objects using
object references. Binding involves passing an object reference identifying a service from the server to the client.
The client uses the reference to initialise a proxy object that represents the remote object in the client’s address
space. Proxy implementations are generated from IDL specifications and compiled into the client program. Operations invoked on the proxy object are routed by the ORB to the implementation of the object. Proxy objects provide distribution transparency; an object and its proxy conform to the same interface and the ORB can return a
direct pointer to the object if the code performing the binding is in the same address space.

A more flexible method of invoking object operations is provided by the Dynamic Invocation Interface (DII) that
allows object requests to be created and issued dynamically. Requests are represented as objects with operations
for setting the name and parameters of the request and retrieving the returned values or an exception. To ensure
type safety when using the DII, the IDL compiler stores type information about the definitions it is compiling in a

22

2. Component Interaction in Distributed Systems
system wide Interface Repository which can be traversed by client code to ensure that it passes the correct values
as parameters of a dynamic request. The DII also allows greater control over concurrency between the client issuing
the request and the object serving it. However, issuing requests through the is less efficient, more complex and type
unsafe compared to making requests through compiled proxies.

Until version 2.2 of the CORBA standard, only the client-side interface of the ORB was standardised: programs
that made object requests over the ORB were portable between ORB implementations but programs that implemented CORBA objects were not. CORBA 2.2 introduced the notion of the portable object adapter (POA) that
makes object implementations available via the ORB. The POA encapsulates the mechanisms by which the ORB
identifies an object and routes operation requests to the object separately from the implementation of the object
itself, which is known as the servant. A server can create multiple POAs, organised hierarchically, to manage the
namespace of objects within the server. The ORB interacts with each POA through standard interfaces allowing
custom POAs to be implemented for different implementation strategies. For example, a POA that interfaces with
a database would identify objects by the key that indexes the record containing their state and would load that state
from the database on reception of a request for the object. The POA specification defines default POA implementations that link the POA and the servant by delegation or inheritance.

Interceptors. An object’s reference encapsulates the transport and presentation protocols used to communicate
with the object. These details are encapsulated by the ORB and not made available to the programmer through
standard APIs. CORBA 2.2 introduced the concept of the interceptor that can be used to extend or replace the protocols used to transfer operation requests. Two forms of interceptor are supported, corresponding to where they are
inserted in the binding and the form of processing they perform. Request interceptors process unmarshalled requests: they can be inserted at the client to process requests after they have been issued but before they have been
marshalled, or at the server to process requests after they have been unmarshalled but before they are invoked on
the servant. A request interceptor processes DII request and reply objects containing the information about the request or reply including the target object, operation name and arguments. Message interceptors process marshalled

23

2. Component Interaction in Distributed Systems
requests which are sent between address spaces: they can be inserted at the client after marshalling but before transmission, or at the server after reception but before unmarshalling. Message interceptors are used to perform lowlevel transformations of the marshalled data, such as compression or encryption.
request
Client

Object
reply

Request
Interceptors

Request
Interceptors

Marshalling

Marshalling

Message
Interceptors

Message
Interceptors

ORB Core
request
reply

Figure 2. CORBA interceptors
The interceptors that are required to communicate with an object are recorded in an ORB-specific manner in the
object reference of the object. The interceptors that are available are also ORB or application specific and the interceptor specification does not provide a standard way of querying or loading the interceptors required for a binding or checking the compatibility of interceptors at either end of a binding.

Services. In addition to the low-level binding and communication services provided by the ORB, the CORBA
standard also specifies a number of higher-level interaction mechanisms and services that are implemented in terms
of CORBA objects. These services include naming, trading, lifetime management and migration, concurrency control, transaction management and event dissemination. The CORBA standard also defines domain-specific services, known as facilities, that provide object models and services for particular application domains, such as financial
services or health-care.

Evaluation. A major drawback of the CORBA environment is that there is no standard component model by
which a system can be constructed in a compositional manner. Because CORBA does not have the concept of an
object’s required interfaces, CORBA applications must be constructed using a first-party binding model: it is up
to clients to get references for and bind to any other objects that they need to communicate with. This complicates
the code of the clients with large amounts of boiler-plate code that is tedious and error prone to write and increases
the amount of testing required. This also means that there is no way of visualising or analysing the architecture of
a CORBA-based system, either at design time or at run time via management tools.

24

2. Component Interaction in Distributed Systems
A request for proposals (RFP) was issued for a component model that would be standardised as part of CORBA
3.0. A proposal has been accepted but has not yet been completed. The component model, “CORBAComponents”,
is similar to Enterprise Java Beans (see section 2.3.4) in that it concentrates on making it easy for components to
be used with transaction monitors and database systems implemented by independent vendors. The CORBA 3.0
component model also extends the IDL with declarations of provided and required interfaces - it uses the term “facets” and “receptacles” respectively - and event sources and sinks, allowing a compositional approach to software
construction. Assemblies of components can be described in XML [BPS98] documents that are interpreted to instantiate and bind components; compared to an ADL, the XML document describing a configuration is excessively
wordy and difficult to read. There is currently no available implementation of CORBAComponents.

Because there is no way to specify an interaction protocol as anything but a set of operations, one cannot specify
the order in which operations must be called on a single interface. There is no way to define protocols in terms of
two or more interfaces, again because CORBA does not have the concept of the required interfaces of an object. A
request for proposals has been issued for a method of formally specifying object behaviour, but as yet there is no
standard.

Beyond the support for interceptors, there is no standard way to select a transport protocol or modify the QoS of a
binding. Even interceptors are next to useless; the OMG admits that “the concept of interceptors in CORBA 2.2 is
underspecified and not portable. This makes them largely useless as a mechanism for third parties to ‘plug into’ an
ORB.”

2.3.3. COM
The Component Object Model (COM) [EE98] is Microsoft’s object model and middleware platform for distributed
object computing and component-based development. As an object-oriented middleware platform it is similar to
CORBA in concept and operation, although with a few differences.

Interaction Styles. A COM object encapsulates state and behaviour and provides one or more interfaces to
other components in its environment. Interfaces are strongly typed and single inheritance can be used to extend
existing interface definitions. Interface types are defined using the Microsoft Interface Definition Language
(MIDL). This IDL allows more detailed type definitions than that of CORBA: data types can contain pointers and
support aliasing of structures. However, object operations are always synchronous and cannot throw exceptions to
report errors. Instead, a coding convention is used in which success or error indicators are returned as the result of
an operation and any returned values are passed to the compiler as “out” parameters.

Component Model. Unlike components in most architecture definition languages, a COM object can only
provide one interface of each type. All interfaces are derived from a base interface called IUnknown that supports
garbage collection through reference counting and provides a method, QueryInterface, for requesting the other

25

2. Component Interaction in Distributed Systems
interfaces provided by a component. Thus COM’s use of multiple interfaces is actually a language-independent
mechanism for implementing multiple interface inheritance; in CORBA this detail would be left to the language
mapping, allowing the use of language-specific multiple inheritance mechanisms if supported.

All COM objects are instances of a particular class. The COM runtime uses a database to map a class identifier to
a binary package, dynamically linked library or executable, that can be used to create instances of the class. COM
functions allow the instantiation of objects within the same address space, a different address space on the same
machine or on a remote machine. When instantiating objects in a different address space, the COM runtime transparently creates client-side proxies and server-side stubs to pass invocations between processes. COM uses reference counting and keep-alive messages to determine when to destroy an object; programmers have to be very
careful about increasing and decreasing reference counts and avoiding circular references. In this way, COM differs from CORBA, which layers lifetime management above the ORB and leaves garbage collection up to the application.

Unlike CORBA, COM supports different programming languages within the same address space. Object interfaces
are implemented as virtual function tables, similar to those of C++. As long as a language can manipulate arrays
of function pointers it can invoke the operations of a COM object but modifications to the compiler are required to
make COM objects appear to be “native” objects of the language.The MIDL language is only used to generate C
or C++ code that defines the interface vtables and stubs and proxies for distribution transparency: support for other
languages is meant to be generated by parsing the C code generated from the MIDL. If a language cannot support
the low-level interface model, it must invoke operations by calling an object’s IDispatch interface that provides
scripting languages with access to a subset of the object’s operations.

COM has no real equivalent to CORBA’s DII and DSI. The nearest equivalent is the Automation framework
[MSFT97], part of ActiveX [Chap96], that defines the IDispatch interface through which scripting languages
can invoke operations of an object. This interface was originally designed to support VisualBasic: operation arguments are passed to the automation interface in structures that are used in the internal implementation of the VisualBasic runtime. However, IDL can be used to define more data types than can be held in these structures, meaning
that only a subset of an object’s interface is available via scripting. A disadvantage of ActiveX Automation, compared to the CORBA DII, is that all scriptable objects must implement the conversion of argument types and the
dispatching of operation requests and each object can do this slightly differently. CORBA generates automatic support for the dispatching of operations from IDL definitions and leaves it up to the run-time of the scripting language
to convert from language-specific data types to those of IDL.

Evaluation. COM has a number of advantages and disadvantages compared to CORBA. The types available in
MIDL are more expressive than those in CORBA IDL, allowing general graph structures to be declared. However,
operation definitions are more primitive: one cannot define exceptions or return types, which makes invoking operations of COM objects tedious.

26

2. Component Interaction in Distributed Systems
COM defines how object classes are packaged for deployment, and can instantiate components in the same address
space as their clients, even if written in a different language. However, the packaging reduces platform independence: COM is tightly tied to Windows platform. Furthermore, although COM is being ported to other platforms,
most COM based component frameworks, such as ActiveX, rely on definitions from the Win32 API in their public
interfaces and COM has not been used to develop commercial components or component frameworks for any other
platform than Win32.

Like CORBA, COM does not support the specification of interaction protocols beyond defining each individual
interface as a set of methods and documenting how interfaces are to be used in conjunction in natural language.

2.3.4. Java Beans, RMI, and Enterprise Java Beans
Java Beans [Chap96] is the standard component model for the Java programming language [AG98]. Java Beans
are precompiled Java classes that can be instantiated, customised by changing values of exported properties, and
composed into an application within a graphical development environment, without access to the source code of
the component. A Java Bean is a serialisable Java class, allowing bean instances to be written to files or transmitted
across network connections, that is bundled with an introspector class that provides development tools with information about the bean so that they can wire it into an application and modify its properties. A bean, being a normal
Java object, encapsulates its state behind an interface defined as a set of methods. The bean framework provides
the developer with a higher-level view of the interface as being made up of operations that can be invoked on the
bean, properties that represent the outwardly visible state of the bean and events that the bean uses to notify other
components of changes to its state. These abstractions are presented to the graphical tool by the bean’s introspector;
a default introspector is provided that uses the Java Reflection API [CLK98] to query the names of a bean’s methods and determine the names of the bean’s events, properties and operations from the methods’ names. It is not
possible to define other ways for beans to interact.

Figure 3. A graphical Java Bean development tool

27

2. Component Interaction in Distributed Systems
Java Beans components gain a lot of advantages from the features of the Java language. They are platform independent because they are executed on a virtual machine, they can be dynamically loaded across a network, and the
reflective capabilities of the Java language can be used to determine their interface elements.

Java Beans have a number of limitations:
• They provide a limited number of interaction styles, all of which must be implemented by the programmer
in terms of individual Java methods, rather than being represented at a higher level of abstraction. For
example, to implement an event for a bean, the programmer must implement methods to add and remove
event listeners and maintain a list of registered listeners within the bean.
• There is no way of specifying or analysing the protocols by which bean operations may be invoked or bean
properties set.
• Because the bean interface is defined in terms of methods, the programmer cannot define new bean types
purely as compositions of simpler beans. They must write code to expose features of the composite bean as
methods that delegate to a method of a contained component.
• The Java Beans framework is designed to support composition of components at design time, rather than
run time. Java Beans tools usually generate source code of component configurations that is then compiled. Because the bean interface is defined in terms of methods, reflection must be used to make use of
dynamically instantiated components. The Reflection API is tedious to use and invoking a method by
reflection is about 100 times slower than invoking the method polymorphically, because of the additional
security checks that must be performed.
• The Java Beans framework is limited to the construction of systems that execute in a single address space.
Distributed applications must be constructed using other technologies.

Java supports a number of APIs for the development of distributed applications, including low level networking
and communication APIs that provide access to the TCP/IP and UDP/IP transport protocols and the serial and parallel ports of the machine, CORBA (see section 2.3.2), Java RMI, a Java-only mechanism for remote object invocation, and Enterprise Java Beans, a component model for writing multi-tier client/server applications.

Java RMI [WRW96] provides a mechanism for invoking operations on Java objects across the network. Because
of its tight integration with the Java programming language and virtual machine, RMI provides a much simpler
programming model that CORBA: RMI generates proxies and stubs from Java interface definitions and Java serialisation is used to marshal parameters, return types and exceptions, so there is no need for a separate IDL. Furthermore, RMI uses Java’s capabilities for dynamic linking to load the classes of parameters or returned objects
over the network, allowing clients or servers to receive objects of classes that were not known at compile time.
However, compared to CORBA, RMI makes inefficient use of system resources - for example, it keeps two TCP/
IP connections open for each separate binding to a remote server object - and does not provide services, such as
naming, trading, and transactions, that are required in a large distributed system.

28

2. Component Interaction in Distributed Systems
RMI provides limited support for multiple transport protocols. Each Java object that is made available over RMI
can be configured with a socket factory object that creates the sockets over which it receives invocations. By default, RMI objects use TCP/IP sockets, but socket factories can implement security protocols or compression over
TCP/IP or use a different transport protocol. When clients bind to a remote object over RMI, the class of the socket
factory for that object can be downloaded from the server, allowing the client to construct a compatible socket. This
use of socket factories allows RMI objects to be configured with monolithic protocols, but does not support the
construction of protocols from reusable components.

Enterprise Java Beans (EJB) [MH98] extends the Java Beans component model to support multi-tier client/server
computing in which application logic is separated from the concerns of the client-side user interface and back-end
database and is executed on one or more servers. An EJB encapsulates a part of the overall application logic and
is executed within an EJB “container” that manages concurrency, transactions, persistence, security and the protocol used to invoke operations of the bean. This allows application components to be portable between different
transaction monitors, databases, security environments and middleware platforms.

However, EJB does not support the use of graphical tools to compose
EJ beans but instead allows the developer only to configure the properties of the bean’s runtime environment provided by its container. EJ
beans are therefore self-contained components that are purely reactive,
reacting to operation requests from clients but not making distributed
requests themselves. This simplifies the programming model for a narrow range of tasks but severely limits the application domain of EJB
components. The default protocol used to access EJ beans is Java RMI

Figure 4. An EJB deployment tool

over TCP/IP, but extensions to the base specification support access to a subset of EJB functionality via CORBA
IIOP [OMG98], which allows clients to be written in any language.

2.3.5. Reflective Middleware
Reflection is the ability of a program to examine it’s own implementation and to modify the implementation in order to modify its own behaviour. Reflective object-oriented languages [KRB91] implement language mechanisms,
such as polymorphic dispatch and inheritance, as meta-level objects that conform to predefined interfaces, or “meta-object protocols”. Programs can modify language behaviour for specific application-level objects by replacing
the standard meta-objects for those application objects with application-specific meta-objects that conform to the
appropriate meta-object protocol.

The Multimedia Programming Group of the Department of Computing at Lancaster University have extended a
CORBA-based middleware platform with reflective interfaces to provide a facility through which distributed programs can adapt their behaviour to react to changing levels of network and end-system resources

29

2. Component Interaction in Distributed Systems
[BC97,BCRP97,CBC98]. This reflective middleware provides application objects with an object-oriented model
of the middleware environment in which they are executing. The object-model is “live”; by modifying the model
the application modifies the behaviour of its middleware.

Component Model. Each application object executing on the reflective middleware platform provides a
“service interface”, through which it provides services to other application objects, and a “meta-level interface”
through which meta-level information about the object can be obtained. The meta-level information for an object
is comprised of three meta-models, each describing separate concerns provided by the middleware platform.

The encapsulation meta-model describes the service interface of the object, exposing its methods and attributes
and providing access to the interface inheritance graph. The composition meta-model represents the implementation of an object as a graph of sub-objects and the bindings between them. These bindings may be “local bindings”
between objects in the same address space or “distributed bindings” between objects in different address spaces.
The environment meta-model represents the execution environment provided for each object interface by the middleware platform. In a distributed environment, this includes the marshalling and unmarshalling, transport protocols, message queuing and dispatching, and thread creation and scheduling.

The objects making up each meta-model themselves have a meta-meta-model. For example, the environment metamodel has a composition meta-meta-model that exposes the composition objects that perform the marshalling or
provide transport functionality. This meta-meta-model can be modified to change the composition

Binding. Bindings between objects are reflected as “open bindings” [WEH97,FGCDR98], an extension of the
RM-ODP concept of explicit bindings. Binding to a remote service returns an interface to a “binding object”
through which the quality of service (QoS) of the binding can be controlled. Two types of binding are supported,
“operation” bindings, used to invoke object operations, and “stream” bindings, used to transmit flows of continuous media. Thus CORBA is extended with a single additional interaction style and the programmer cannot define
new interaction styles.

Binding objects are composed hierarchically. Sub-objects perform processing at either end of the binding and are
themselves connected by a binding object or by a “local binding” - procedure calls or some equivalent mechanism.
Processing objects include media codecs, transport protocols, the network device and the network switches responsible for routing the traffic of the binding and maintaining the network QoS reserved for the binding.

The interface of the binding object is used to monitor and control the QoS provided by the binding and to alter the
configuration of the binding object if QoS degrades below an acceptable level. The component objects of a binding
also have control interfaces through which their operation can be modified. Control interfaces are type-specific;

30

2. Component Interaction in Distributed Systems
for example, the control interfaces of MPEG and H.263 codecs would be different, as would control interfaces of
UDP/IP and AALn/ATM transport protocols. The binding object implements its control operations by calling the
control operations of its component objects.
Control interface
Service interfaces

Application
Object

Binding object

Sub-objects

Application
Object

Figure 5. The structure of a hierarchical open binding

Evaluation. Reflection and open bindings are powerful tools to support the configuration of distributed programs and their middleware at both design-time and run-time. By reflecting and manipulating its own implementation details, a program can easily modify its behaviour to react to dynamic changes in its environment.

However, the open bindings model introduces scalability problems as programs grow in size and complexity. Because the control interfaces of sub-objects are type-specific, a different binding object implementation is required
for each combination of sub-objects. As new codecs and transport protocols are introduced the number of binding
object types required increases dramatically. It is also practically impossible to reconfigure a binding object because the binding object must have prior knowledge of its subobjects; one cannot replace a subobject that cannot
achieve the desired QoS with an object that can if that object is not understood by the binding. These disadvantages
could be avoided by separating the various concerns encapsulated by the meta-objects of the binding - codec or
marshalling, transport and network protocols - and defining standard interfaces through which each particular concern could be controlled.

Reflection has many of the same disadvantages as first-party binding: the functional aspects of the application are
intermixed with code that performs binding and meta-level manipulations. Attempting to simplify code by separating functional and meta-level concerns has led to the development of architecture description languages, that
allow the programmer to describe bindings between components declaratively, and aspect oriented programming
(see section 2.6) that uses multiple languages to specify the functional and various meta-level aspects of a program,
and translates meta-level descriptions into operations performed by a reflective implementation.

31

2. Component Interaction in Distributed Systems

2.4. Architecture Description Languages and Connectors
Object oriented systems provide programmers with support for encapsulation, abstraction and polymorphism.
However, they provide little support for system composition and evolution because system structure is hidden
within the implementations of the objects of the system. Component based systems are constructed from components that encapsulate the functional aspects of the system but do not encapsulate any of the structural aspects. The
system structure is made explicit by defining the bindings between components separately from the implementations of those components, often in a separate architecture description language (ADL). An explicit architecture
definition simplifies the implementation of individual components by allowing component developers to concentrate only on the algorithmic details of the implementation. An architecture description can also structure formal
models of the system for design and analysis, and can act as a representation of the structure of a deployed system
acting as a framework for management and evolution the system. A great many ADLs and component models have
been designed for research projects and commercial products. In this section we review those that are influential
or representative of the current state of the art.

2.4.1. Polylith
Polylith [Purt94] was a middleware platform developed at the University of Maryland during the late 1980s to support component based development of distributed systems. A Polylith component, known as a module, both provides services to and requires services from other modules. Polylith uses a module interconnection language (MIL)
to define the interfaces of modules in terms of named, typed service provisions and requirements. The MIL is used
to define systems as compositions of components and the bindings between their interfaces.

A service of a module is a procedure entry point. However, modules do not directly invoke the services of other
modules. Instead they invoke services by making calls to a software bus, a layer of software that is responsible for
transporting invocations between components. The software bus encapsulates details of the way in which modules
communicate separately from the functional aspects of the system encapsulated within modules. For example, a
bus may encapsulate how modules written in different languages communicate within the same address space or
how modules on different nodes communicate over a network. As such, a software bus is analogous to the CORBA
ORB. However the bus makes use of the structural information in the MIL description of the system to optimise
the communication paths between communicating modules.

The functionality of a software bus is tied closely to that of a respective packager that encapsulates how modules
are compiled and linked. The packager generates information that is used by the bus to establish bindings. For example, the packager might generate stubs to flatten data structures into network messages or coerce data between
the representations used by different languages.

32

2. Component Interaction in Distributed Systems
Polylith has the advantage of cleanly decomposing a system into components and defining explicitly specifying
the architecture of the system in terms of instantiated components and the bindings between their interface elements. However, components are limited to only two forms of interaction: synchronous (remote) procedure call
and asynchronous message passing; other interaction patterns must be built in terms of these primitives. The ADL
does not allow bindings to be annotated with the required quality of service or transport protocol, forcing all bindings to use the same transport protocol whether suitable or not. Finally, there is no support for design time modelling and analysis of systems.

2.4.2. Darwin/Regis
Darwin [MDEK95] is an architecture description language that is used to define the structure of systems implemented in the Regis distributed programming environment. However, the Darwin language strictly separates the
structural concerns of the system from those to do with computation and communication, and is therefore independent of any one runtime system. Darwin has also been used to configure distributed components written for the
CORBA and AnsaWare platforms, parallel programs, C++ objects within a single address space and C modules
interacting by procedure calls.

Component Model. Darwin defines program structure in terms of component instances and bindings between
their interfaces. Component interfaces are comprised of the services they provide to and those they require to be
provided by other components in their context. Services are typed, but the Darwin language does not define, or
limit, service types; it is up to the compiler to interpret types and check type safety of bindings.

Darwin manages structural complexity through the definition of composite components, the implementation of
which are defined in terms of component instances and bindings between them. Programs are thus structured as a
a hierarchy of components with the root composite component representing the entire program, leaf components
representing primitive components that encapsulate the computational concerns of the program, and mid-level
composite components encapsulating the structural concerns of the program. The semantics of Darwin is defined
such that composite components exist only during elaboration of the program’s structure: after elaboration primitive component interfaces are bound directly so that communication does not have to be routed through composite
components.

Darwin has some support for dynamic architectures. Components can contain arrays of subcomponents, the size of
which can be defined as a function of the parameters of the component. More dynamism is provided by support for
lazy and “worker” instantiation. Lazy instantiation of a component is performed in response to the first invocation
on one of its services. Worker instantiation is provided by a special form of service, the only service type defined
by the Darwin language, that can be invoked to create new component instances. How this service is implemented
and invoked is left up to the runtime environment.

33

2. Component Interaction in Distributed Systems
Darwin has both a textual and graphical syntax. The graphical syntax is used by CASE environments [NKM96]
and tools for runtime configuration management [FS97]. The CASE tools support simultaneous editing in both representations: it was found that using the textual syntax was easier when defining complex architectures. The graphical syntax represents component instances as rectangles, component types as rounded rectangles, provided
services as filled circles, required services as hollow circles and bindings as lines joining a required service to a
provided service. Names and types are represented as textual annotations. See the example in figure 6.

component Source {
require out : Pipe<string>;
}
component Filter {
provide in : Pipe<string>;
require out : Pipe<string>;
}
component Sink {
provide in : Pipe<string>;
}
component
inst s
inst f
inst t

System {
: Source;
: Filter;
: Sink;

System
s : Source
out : Pipe<string>
in : Pipe<string>
f : Filter
out : Pipe<string>
in : Pipe<string>
t : Sink

bind s.out -- f.in;
bind f.out -- t.in;
}

Figure 6. A simple filter pipeline in Darwin’s graphical and textual syntaxes

Modelling and Analysis. Darwin has a formal semantics, defined in the π−calculus [MPW92], that precisely
defines the concurrent algorithm by which Darwin elaborates configurations of components. Darwin can also be
used in the TRACTA method of modelling and analysis [Gian95,GJS96] to compose models of systems from models of components and their bindings. The behaviour of primitive components are modelled as a labelled transition
systems, expressed in FSP [MK99], a process calculus. Composition and binding statements in the ADL are translated into FSP relabelling and hiding operations that define how components synchronise on shared actions and
how actions of the subcomponents of a composite are hidden from that composite’s siblings. This approach models
component interactions as synchronous events shared by two or more processes: all processes perform the shared
transition in lock-step. This model is appropriate for procedure calls between objects within the same address space
or synchronous, reliable method invocations between distributed objects. However, modelling of the various interaction and transport protocols used by the Regis system is left up to the designer. There is no standard library of
protocol models or tool support for generating such models.

Runtime Support. Regis is a C++ framework for building distributed programs, the configuration of which
can be specified in Darwin. Primitive components are active objects that communicate through interaction objects.
Interaction objects correspond to Darwin’s provided and required services and the code to establish bindings be-

34

2. Component Interaction in Distributed Systems
tween them is generated from the Darwin specification. Unlike most middleware platforms, Regis allows the programmer to use multiple types of interaction between components, such as message ports, request-reply or one-tomany event dissemination, and to define new interaction styles as necessary.

The first version of Regis [MDK94,CT94] supported interaction styles with two template classes, one implementing the service side of the interaction and one implementing the client side and reference. By convention, the clientside interaction class was named after the service side class with the suffix “ref”. For example, portref objects
were used to access port services. “Ref” objects could be passed in messages to create dynamic binding structures,
and so doubled as both references and the programming interface to the interaction protocol. Regis provided a basic
port interaction type that implemented synchronous and asynchronous message passing. Other interaction abstractions were implemented in terms of ports by a mixture of inheritance and aggregation. Implementation of new interaction types in this way was complex and the use of interaction objects inconsistent. For example, the client side
“ref” objects of some interaction types contained local state, such as message queues and had to be cast to and from
portref values when transmitted in messages. Furthermore, Regis only supported a single transport protocol and

did not allow the selection of different levels of QoS appropriate for each binding.

A second version of Regis [CMP95,PC96,Crane96,Crane97] was developed to overcome some of the deficiencies
of the original platform. The framework for interaction objects was redesigned so that it was simple to define new
interaction styles. Interaction classes were separated from the transport protocol, allowing programmers to select
the most appropriate transport for each service. The concept of a reference was separated from that of a client-side
endpoint and identified the protocol used to communicate with the service. Transport protocol components were
dynamically loaded, allowing client and server programs to be evolved independently and make use of new protocol implementations as they became available.

Interaction Styles. The new Regis interaction framework defines each interaction type as a set of related
classes that implement the service and client endpoints, distribution transparency and reference format of the interaction protocol. These classes inherit from base classes defined by the Regis framework that define the interfaces
for transport communication endpoints or bindable objects. They also follow a naming convention so that the C++
template functions that perform binding can instantiate and manipulate the appropriate classes with full type safety.

Using the new interaction framework, it is much easier for a programmer to implement a new interaction type.
However, Regis still has a number of deficiencies. The details of the interaction protocol are completely encapsulated within the implementations classes for the protocol. Because an interaction protocol has no specification beyond the code it is difficult to reimplement the protocol in another language. The lack of an interaction
specifications from which marshalling code can be generated makes it difficult to transmit complex data structures:
Regis only supports the transmission of flat records that do not contain pointers and the programmer must implement functions to translate the fields of the record between representations used by different architectures.

35

2. Component Interaction in Distributed Systems

Evaluation. The Darwin/Regis system has many advantages over current middleware systems. Darwin is used
to explicitly define system architecture, freeing the programmer from the need to write code to deploy and bind
components. The set of potential interaction styles is completely open - programmers can define their own by extending base classes provided by the Regis system - and the transport protocol used for communication can be selected on a binding-by-binding basis and composed from primitive protocol components.

However, the system does not provide enough support for implementing new interaction styles; the programmer
must implement the code to marshal complex data structures and convert between representations used on different
systems. The TRACTA approach to modelling component interactions as synchronous events is appropriate for
procedure calls between objects within the same address space or synchronous, reliable method invocations between distributed objects. However, modelling of the various interaction and transport protocols used by the Regis
system is left up to the designer. There is no standard library of protocol models or tool support for generating such
models.

2.4.3. OLAN
OLAN [BBMV98a, BBMV98b, MBVR97] is a component-based programming environment for the development
of distributed systems. It is aimed specifically at building systems that integrate heterogeneous legacy software
components and deploy them across a distributed network of processing nodes. Systems are constructed from components and connectors: components encapsulate the algorithmic aspects of the system by wrapping legacy software and connectors manage communication between components.

Component Model. An OLAN component is an object that encapsulates state and behaviour behind a strict
interface, defined using the OLAN Interface Definition Language (OIL). As in the Darwin language, a component’s interface is comprised of services provided to other components and those required by the component to be
provided by others. Unlike Darwin, which does not prescribe the service types used by components, the only services that can be provided or required by an OLAN component are object operations; operations cannot be “bundled” into higher level abstractions. A component’s interface exposes some information about how the component
implements the operations at its interface: both provided and required operations must be marked as synchronous
or asynchronous, indicating whether threads expect to wait for a reply or for the operation to complete.

An OLAN system is defined using the Olan Configuration Language (OCL) as a hierarchy of components in which
the root component defines the entire system, intermediate components are themselves composed of components,
and leaf components are primitive, wrapping legacy code. The OCL “implementation” declaration is used to
define composite components in terms of instantiated sub-components and the bindings between their interfaces
via connectors. Like Darwin, an OLAN composite component can expose provided and required services of its subcomponents at its own interface. However, unlike Darwin, OCL requires connectors to be specified between the
interface element of the subcomponent and that at the interface of the composite component. When a composite
component is deployed these connectors remain in the system and communication between the components at the

36

2. Component Interaction in Distributed Systems
end of the bindings is routed through the tree of connectors. Compared to Darwin, which flattens composite component structures at runtime and creates direct bindings between the interfaces of subcomponents of different composite components, the use of composite OLAN components results in unavoidable communication overheads that
increase with greater use of hierarchical composition.

OCL ensures that bindings between components are type safe and that bindings are only established between provided and required services with compatible synchronisation constraints. The synchronisation constraints also constrain the connection patterns of bindings: many synchronous requirements can be bound to the same synchronous
service but each synchronous requirement can only be bound to one service; conversely an asynchronous requirement can be bound to multiple asynchronous services, but an asynchronous service can only be the target of a single
binding. However, both type and synchronisation constraints can be overridden by specific connector types.

OLAN primitive components are implemented as legacy software wrapped within packaging code and data structures that implement the OLAN component model and route invocations between the component’s interface and
the programming interface of the legacy software. This packaging is generated from OCL “primitive
implementation” declarations that describe the mapping between the component’s interface and the program-

ming interface to the legacy software. These descriptions are programming-language specific: primitive components can be constructed from legacy software written in C, C++ and Java and Python.

Connectors. OLAN connectors are responsible for transporting invocations between components. Connectors
can also perform computation on the data passed through them, including coercing parameter types to allow binding between incompatible services, converting between different presentation-layer formats, calculating new argument values and routing invocations based on their argument values. An important use of connectors is to mediate
interaction between components with some application-layer protocol, such as a floor-passing mechanism in a
groupware application.

In the same manner as primitive OLAN components are used to adapt legacy code to the OLAN component model,
so OLAN connectors are used to adapt legacy communication mechanisms, such as shared memory, TCP/IP connections or RPC calls, for use between OLAN components. A connector is separated into an adapter object and
sender and receiver objects. The adapter interfaces with the component packaging generated from OCL definitions, performs data type and control flow translations and can execute arbitrary user-defined computation on the
data flowing through it. When a connector is used to bind components in the same address space, the adapter is
connected directly between the components. However, when a connector is used between components in different

37

2. Component Interaction in Distributed Systems
address spaces, an adapter is instantiated for each component being bound and sender and receiver objects are instantiated to act as proxies for remote adapters, routing calls to the adapter across the communication mechanism
used by the connector.
Component

Adapter

Component

Connector
Code
Colocated Components

Component

Adapter

Sender

Receiver

Adapter

Component

Communication
Mechanism
Connector
Code
Distributed Components

Figure 7. OLAN connector objects between collocated and distributed components
OCL system descriptions can also include management declarations that describe how components are deployed
as a set of name/value pairs. Management attributes include the host on which to execute a component, the operating system required and the user name under which a component is to be run. Further control over deployment
is provided by distribution policies which specify constraints over the execution of components, such as whether
components must be collocated or executed on machines within the same domain.

Evaluation. The main drawbacks of the OLAN system are: the poorly delineated conceptual model of components vs. connectors, the inflexible connector model and the inefficient implementation. The simple model of components encapsulating algorithmic concerns and connectors mediating communication between components is
confused by the ability to encapsulate arbitrarily complex computation within connectors - it is no longer obvious
where computation is being performed within the system.

Although the concerns of adapters and proxies are separated within the implementation of connectors for reasons
of efficiency, this separation is not made visible to components: a connector type cannot be instantiated with a different transport protocol, for example, in order to select an appropriate QoS. Neither can the parameters controlling
the communication mechanism of the connector be controlled by the application.

The OLAN component packaging and connectors are implemented in Python [Rossum95], an interpreted scripting
language, which reduces performance. Also the way that bindings between subcomponents are routed through connectors up and then back down the component hierarchy reduces the performance of communication between subcomponents of different composites.

38

2. Component Interaction in Distributed Systems

2.4.4. UniCon
UniCon [SDKR95, SDZ96] is an architecture description language that focuses on building systems from existing
architectural parts - components and connectors - and supporting architectural styles that are already in use. UniCon components are pieces of software encapsulated behind strict interfaces and connectors define protocols by
which components interact, such as a procedure calls, shared variables, UNIX pipes or RPC invocations. An architectural style is defined by the potential set of components and connectors that may be instantiated as part of the
system and constraints on the topology in which they may be connected.

A component’s interface is comprised of the component’s type, such as a C library or UNIX process, properties
that specialise the component type and “players”, points at which the component interacts with connectors. A connector defines a protocol, specified by the connector type, properties that specialise the type and the points, known
as “roles”, through which components may interact according to the protocol. Both component players and connector roles are typed and may have properties that specialise their types.

A component may be primitive or composite. A primitive component is implemented as some element of software
defined outside the UniCon language, such as source code in some programming language, object code in a library,
a file in the file system or a process. Composite components are defined in terms of the components and connectors
used, the “connections” between component players and connector roles that define how internal components interact, and “bindings” that specify how the interface of the composite component is mapped to elements of its internal configuration.

Because UniCon is designed to build systems from existing parts, it does not itself define a component model and
run-time environment. Instead it makes use of component and connector types provided by the operating system
on which the system is to execute, such as UNIX processes or binary object files and pipes or shared files. A noteworthy aspect of UniCon is that its set of connectors include, in addition to those concerned with explicit intercomponent communication, indirect interactions caused by components competing for resources; an example of such
a connector is a scheduler in a real-time operating system.

The UniCon compiler analyses the architecture description to ensure that it is correct: that players are connected
to roles that they can fulfil and that the configuration of the implementation of a composite component fully implements its interface. If the checks are successful, the UniCon compiler generates the code for the components
and connectors, the glue code to attach component players to connector roles, and scripts to compile link the components, connectors and glue into an executable system. Like Darwin and OLAN, UniCon has both a textual and
graphical representation; the graphical representation is used by tools that provide the user with a simple interface
with which to specify system architectures.

39

2. Component Interaction in Distributed Systems
Specifications can be attached to architectural parts as name/value pairs. UniCon tools do not interpret these specifications but pass them to external analysis tools. The UniCon language is being modified to support “credentials”
[Shaw96], component specifications that can be incrementally evolved during the lifetime of a component, in order
to better support the real-world usage of components in which new specifications are required after the component
has been created or are created by analysis or synthesis of existing specifications. An important part of a component’s credential is the credibility of the specification, such as “asserted”, meaning that the specification is given
by the designer and taken on faith, or “verified” meaning that the component has been mechanically verified to
meet the specification.

The application domain of UniCon, that of building systems from existing, platform-specific parts, is also its main
drawback. The UniCon compiler and graphical tools support a fixed set of built-in connector types. Adding new
connectors requires extending the UniCon compiler, which, the designers admit, is not a trivial task, and also involves adding new icons representing the connector to the graphical tools. Implementing a new connector is performed by writing a “connector expert” for the toolset. A connector expert is comprised of data files and C source
code that specify the syntactic representation of the connector type, perform semantic checks specific to the connector and can generate code and build rules to integrate the connector into a final system. A specialised compiler
generator tool is used to integrate connector expert components into the UniCon compiler, raising the question as
to why UniCon itself wasn’t used for the task.

UniCon is limited to the construction of systems that execute on a single machine. There is no support for distribution and connectors that are used to cross address spaces are treated as different from those used within a single
address space, thereby ignoring issues of distribution transparency. For example, a player of type procedure call
cannot be connected to a player of type remote procedure call. The lack of distribution support is evident in the
way that connectors mix the concerns of transport, presentation and application layer issues. A pipe connector specifies the use of the UNIX pipe IPC mechanism, a transport protocol, but the players of a pipe are parameterised by
a regular expression defining the format of data passed across the pipe, a presentation layer issue; however, it is
impossible to specify that a procedure call or RPC can be routed across a pipe, even though it would be possible to
generate presentation-layer code to marshal the procedure call into a textual format that could be understood by a
pipe player.

Evaluation. UniCon provides designers with a rich component model in which components can interact in a variety of ways, and allows one to annotate component definitions with formal specifications, and provides tool support for analysing specifications and generating executable code from architecture descriptions. However, the set
of connector types available to the designer is limited to IPC mechanisms that provided by the platform on which
the system is to execute and supported by the UniCon compiler. UniCon does not provide the designer with any
support for implementing new connector and component types: connector types are hard-coded into the UniCon
compiler. A flexible way of specifying new interaction styles would be useful. The inability to build and deploy
distributed systems is a disadvantage.

40

2. Component Interaction in Distributed Systems

2.4.5. Wright, Aesop and ACME
Wright, Aesop and ACME are a set of languages and tools for specifying analysing and constructing system architectures, developed by the ABLE project at Carnegie Mellon University.

Wright [Allen97,AG97,ADG98], like UniCon and OLAN, is an architecture description language that structures
a system in terms of components and connectors with components interacting via connectors. However, unlike
UniCon and OLAN, Wright is purely descriptive: it is used only for modelling and analysing software systems and
cannot be used to build or deploy the system described. Wright defines the semantics of component and connector
behaviour in CSP. The syntax of the ADL acts as a structure in which to organise these CSP specifications.

Wright characterises a component by the ports at its interface through which it interacts with other components via
connectors. A port represents a role that the component can play in an interaction with other components. The protocol followed by the role is expressed in CSP. The behaviour of the component is also expressed in CSP in terms
of the component’s interactions with its ports. Wright characterises a connector by the roles that can be played by
components and a CSP specification of the protocol by which the roles communicate. Wright is open as to the set
of connector types that it supports.

System specifications are built by declaring named component and connector instances and the bindings between
the ports of the components to the roles of the connectors. From a system description Wright can generate a CSP
model of the system and pass it to an external theorem prover for analysis. Among the system properties that can
be checked in this manner are whether the system is deadlock free, whether a component’s implementation corresponds to the port protocols, whether the a component’s port protocol is compatible with the connector role to
which it is bound and whether any unbound ports of a component are actually required to be bound for the component to work correctly.

Aesop [GAO94, Monr96] is a toolkit to support the construction of graphical tools for the design and analysis of
architectures that conform to some architectural style. An architectural style is a set of component and connector
types together with rules as to how they can be composed into systems. Aesop represents an architecture as a system of objects stored in an object-oriented database. Classes are provided as part of the system to represent generic
components, connectors, ports and roles. Objects representing architectural parts can be annotated with specifications that are not themselves represented as objects but are interpreted by other tools.

A style is defined by extending the base classes that represent architectural parts to implement constraints on how
the parts can be connected. For example, a pipe-and-filters style is defined as the constraints that components interact only via pipes and that an output port of a component must be connected to the input role of a pipe and vice
versa. Styles can also be defined by extending the classes of an existing style. For example, a pipeline architectural
style can be defined by extending a pipe-and-filters style with the constraint that filters must have one input port
and one output port. However, this use of inheritance is inflexible: for example, although a component in the pipe-

41

2. Component Interaction in Distributed Systems
line style can be used as in the pipes-and-filters style, a component from the pipe-and-filters style that happens to
have a single input and output port cannot be used in the pipeline style. Styles would be better described as predicates or constraints over a configuration of components.

The Aesop tools interact by making reads and writes to the architecture database and announcing events over a
software bus to notify other tools that the database is modified. Aesop provides a generic graphical editor that can
draw representations of architectures of any style. Other tools are style specific: depending on the style, Aesop tools
can perform analysis of the model or generate code for a particular environment. For example, tools for a pipesand-filters style can generate Unix filter programs.

Architectures described in Aesop and Wright are not directly interchangeable: that is, the Aesop toolset cannot read
or write Wright architecture descriptions to be analysed by the Wright toolset. Instead, architecture descriptions
are translated into an intermediate language, ACME [GAO94], that was designed as a lingua franca ADL to support the interchange of architecture information. ACME defines syntax for those architectural elements that most
ADLs have in common: component types, connector types and configurations of component and connector instances. This syntax is used as a structure into which models are included. ACME itself does not interpret these
specifications but the ACME parser can extract them for processing by external tools.

Evaluation. Although Wright can be used to specify and analyse architectures of components that interact in an
extensible variety of ways, they have the drawback of being purely descriptive: one cannot generate the boilerplate
code required to instantiate and deploy a system defined using any of these ADLs. This limitation does have some
benefits: unlike UniCon, for example, it is trivial to integrate new connector types into a Wright architecture. However, the designer is completely on his own when it comes to implementing them. The Aesop tools can generate
the code required to instantiate and deploy a system, but cannot read an architectural description defined in Wright.
The use of ACME to pass information between the Wright and Aesop tools is rather superfluous. It would be better
to use a single ADL for all toolsets.

2.5. Transport Protocol Frameworks
Sophisticated distributed systems require control of the transport-protocols used for the bindings between their
components so that they may select appropriate reliability, security, compression, auditing and management properties. To allow the flexible combination of different transport-layer properties, the transport protocols used for a
binding must be composed from primitive components. This allows, for example, the same encryption algorithms
to be used with a reliable or unreliable transport. Protocol components must be dynamically loadable so that systems are not hard-coded with a limited set of protocols.

However, current object-oriented and component-based middleware systems provide only limited control over the
transport-layer concerns of bindings, allowing the transport protocol over which a service is made available to be
selected from a limited set when the service is initialised. Few allow the creation of new transport protocols for

42

2. Component Interaction in Distributed Systems
services or the dynamic loading of compatible transports by clients. The transport protocols supported typically
provide reliable, in-order delivery of messages, which is suitable for RPC and object invocation but not for other
forms of intercomponent interaction, such as streaming media. Systems that use “connectors” allow a connector to
encapsulate the use of different transport protocols but the connector is then used as a monolithic whole when constructing systems and the application layer protocol of the connector cannot be reused with different transport protocols.

A number of object oriented frameworks have been defined to support the implementation of transport protocol
software from lightweight components.

An influential early system is STREAMS [Ritchie84], initially designed to provide greater modularity in the design of Unix device drivers. Drivers are structured as a linear chain of “modules” that encapsulate protocol processing. Each module provides a uniform interface, through which messages are passed up and down the stack, and
execute concurrently as lightweight threads. STREAMS functionality is accessed through the standard UNIX file
I/O API. User processes that open a device can perform I/O control operations (ioctls) to push STREAMS modules
onto the top of the stack to modify the behaviour of the device. Because UNIX did not originally support dynamic
loading of code into the kernel, the set of available modules was fixed. Later versions of the STREAMS system
supported the construction of multiplexor trees and the dynamic loading of STREAMS modules into the kernel.
The performance of STREAMS is limited by the execution of each layer as a separate thread.

The x-kernel [OP92] is a C library for building protocol software developed by the University of Arizona and since
used in the OSF/1 Unix kernel. Protocols are implemented in terms of “layers” and “sessions”: a layer encapsulates
protocol functionality and creates a session to encapsulate the state needed for each user of the layer. Layers and
sessions are C data structures that provide uniform interfaces through which threads deliver messages containing
application data and control information. The use of uniform interfaces allows layers to be composed into arbitrary
directed graphs: the x-kernel encourages fine-grained composition in which lightweight protocol components encapsulate individual algorithms and are composed to implement transports with rich semantics. Protocol graphs are
defined statically and cannot be modified at run-time. The x-kernel introduced the concept of the “virtual protocol”
- a protocol layer that does not add headers to messages flowing through it but instead serves only to route messages
within the local protocol graph.

Further research based on the x-Kernel added the concept of the “micro-protocol” to those of layers and sessions
[Hiltu98]. A micro-protocol is a component of a layer that encapsulates part of a layer’s functionality and processes
the messages delivered up or down to the layer. Micro-protocols are not composed into an explicit structure; instead
they are added to a layer as “plug-ins” and communicate by manipulating data-structures within the layer. The semantics of a layer then depends on the selection of micro-protocols that have been plugged into it. Tools are provided to help a programmer select the appropriate micro-protocols to achieve the semantics required of the layer.
However, these tools do not help the programmer in constructing the protocol graph itself.

43

2. Component Interaction in Distributed Systems
Horus [RBFH95,RBM96] is a communication system supporting group communication. Multicast semantics,
such as reliability, stability and ordering, can be selected by composing protocol layers into a stack. Like the xkernel, Horus defines a common interface for protocol layers through which threads carry messages, but enriches
the interface with operations specifically supporting group communication. The protocol structures that can be constructed by Horus are limited to trees of multiplexors and Horus does not support the concept of virtual protocols
responsible for routing messages within the protocol graph. The Horus protocol software executes in user space
and is made available to user programs through a variety of APIs, including the UNIX sockets API and the Message
Passing Interface (MPI), through an RPC library and as commands for the Tcl scripting language.

OmniOrb2 [LP98] is an implementation of the CORBA 2.0 specification by the AT&T Cambridge Research Laboratories. OmniOrb2 extends CORBA with support for multiple transport protocols. However, the transport framework is designed to support only CORBA GIOP as a higher layer protocol and does not provide a compositional
approach to the construction of new transport protocols or support dynamic loading of protocols.

FlexiNet [HHD98] is a configurable middleware platform produced by APM. FlexiNet is based on Java, distributed services are made available as Java objects, and interaction with remote objects follows the semantics of Java
object invocation as closely as is possible in a distributed system. Bindings to remote objects are implemented by
stacks of protocol components. However, FlexiNet only supports linear stacks of protocols, and the protocol components are responsible only for presentation-layer marshalling. The base of any stack is responsible for sending
messages over a transport protocol, but the transport itself is not constructed from components.

Softwired’s iBus [Softw99] is a commercial middleware platform for building Java “publish/subscribe” applications that includes a communication subsystem very similar to that of Horus. IBus applications are comprised of
groups of components that communicate by sending asynchronous messages to shared multicast channels; a message can be any serialised Java object. All components connected to a channel receive all messages from that channel. Interaction protocols between members of a channel must be implemented in terms of individual messages but
are not defined separately from their implementation. Channels can use point-to-point UDP, IP-Multicast or TCP/
IP as their transport protocol. Other protocols can be layered above these to extend the semantics of the transport,
to provide reliable multicast or security for example. Protocols stacks are constructed dynamically based on information in the URLs identifying channels, but are limited to linear chains of layers.

Conduits+ [HJA95] is an object-oriented framework for the construction of network communication software in
C++. Protocol software is composed from conduits that perform protocol processing on information chunks. Conduits have a uniform interface through which they pass information chunks between each other and so can be connected into arbitrary configurations. Unlike the protocol components of the x-kernel and Horus, conduits are not
directional - they do not have a top and bottom - and so can be connected in any orientation. Multiplexing is implemented using two conduit types: a mux and a protocol factory. A mux performs (de)multiplexing by routing
information chunks to other conduit depending on the content of each chunk. A protocol factory creates a new conduit when it receives an information chunk. A mux can be configured to pass chunks to a protocol factory when it

44

2. Component Interaction in Distributed Systems
cannot determine the destination of the chunk, thus causing the instantiation of a conduit to process the chunk. Demultiplexing (i.e. message routing) can be implemented by instantiating a mux “upside down” in the protocol
graph. Unlike the x-kernel, Conduits+ is not used to compose fine grained components; for example, the entire TCP
protocol is implemented as a single conduit rather than conduits encapsulating individual reliability, flow control
and multiplexing algorithms. Conduit graphs can be constructed dynamically but the set of conduit types is fixed
when the application is constructed. Conduits+ has recently been ported to Java [NK98] and the conduit components implemented as Java Beans. This allows dynamic loading and configuration of conduit graphs at design time
but dynamic loading of conduit classes is not supported at runtime.

2.6. Others
MPI [MPIF93] is an API for the construction of parallel, message-passing programs. It was originally designed
for use on message-passing multiprocessors but has also been ported to networked clusters of workstations. An
MPI program is structured as a set of tasks that execute in parallel and communicate by message passing. To maximise the concurrency between tasks executing on different processors and minimise overhead due to context
switching between tasks on the same processor, message passing is asynchronous. Higher level interaction and synchronisation patterns between tasks must be implemented in terms of the low level message passing API calls.

Compared to MPI, object-oriented middleware forces the programmer to increase concurrency by spawning multiple threads of control within components, because objects communicate by synchronous object invocation. This
approach to concurrency complicates the implementation of objects with explicit synchronisation code.

Metaobject protocols of open languages have been used to implement connectors and distribution transparency
[CM93, ALP99]. In an open language, a program’s mapping onto lower level mechanisms, such as its compilation
or runtime support, is controlled by objects that conform to well defined protocols. These objects are termed “metaobjects” because they model the implementation of the program rather than the program’s application domain. Programmers can replace one or more metaobjects to control the implementation of specific parts of their program. To
define connectors, the metaobjects that implement method calls are replaced for specific application objects with
metaobjects that implement the connectors’ mechanisms. For example, the connectors’ metaobjects might filter or
redirect the method call or marshal and transmit the method invocation to a remote object. The main disadvantages
of defining connectors using metaobject protocols is that connectors are limited to communication between components written in a single language and that connectors must be implemented by manipulating the lowest levels
of the language’s implementation which is complex and can introduce subtle errors.

Aspect-oriented programming (AOP) [KLMM97, LK97] aims to provide the power of metaobject programming
with less of the drawbacks and has also been used to implement connectors for distributed programs. AOP separates a program into components of functionality, object classes, and definitions of the non-functional aspects of
the system, such as how data flows between distributed components and concurrency constraints. In traditional object-oriented languages, the code implementing an aspect is scattered throughout the code of the classes it affects,

45

2. Component Interaction in Distributed Systems
making it difficult to specify, understand and modify. By centralising details of each aspect in a single place, it is
easier to define and modify an aspect, and therefore easier to adapt programs to use new distribution of concurrency
strategies.

AOP components are written in a traditional object-oriented language, such as Java and definitions of each aspect
are written in distinct aspect languages. An “aspect weaver” compiles the functional components and aspects,
building runtime support for each aspect, and integrates the components with this runtime support by connecting
the components to the aspect runtimes at well defined “join points”, such where code invokes methods, passes parameters returns values or allocates new objects.

AOP has the same aims as component based programming using interface and architecture definition languages,
that of increasing the clarity of a system through clean separation of concerns. However, AOP is limited to a single
language: the aspect languages refer to constructs of the component implementation language and hook into the
metaobject protocol of that language. Although providing less flexibility, AOP removes one of the main drawbacks
of metaobject programming: it is no longer necessary to explicitly manipulate the implementation details of the
language; instead the programmer uses a high-level declarative notation that is translated into metaobjects or program transformations. As with the direct use of metaobject protocols, the intercomponent interaction protocols are
still defined only in the implementation of each component.

Aster [IBS98] is a toolset that aims to support the systematic customisation of middleware based on an application’s non-functional requirements. Aster programs are defined, using an ADL, as a configuration of components
that provide and require services. The interfaces of a component also define the non-functional requirementsof the
services of the component, such as reliability or transactional properties. Non-functional requirements are specified
by names that refer to definitions of the property specified in first-order predicate logic. A base middleware layer
is provided that can meet basic non-functional requirements; currently Aster supports CORBA or HTTP. The functionality of this layer is extended by middleware components. The non-functional properties provided by middleware components are also defined in first-order predicate logic. The Aster toolkit uses a theorem prover to
determine which middleware components must be used to meet the non-functional requirements of the application,
and then generates the C++ glue code to instantiate and deploy the application. Aster components can therefore
only interact through synchronous object invocation, and formal models are only used to select components that
mediate bindings between services in order to meet non-functional requirements, not to specify and check interaction protocols and the compatibility of bindings.

Rapide [LKAV95,LV95] is an ADL and set of specification languages for describing and simulating distributed
computer systems; Rapide architectures are not translated into executable code. Rapide models a system as a set
of interacting components that generate and react to events. A simulation of a Rapide architecture generates a partially ordered set of events (a “poset”); a poset represents causal relationships between events and is partially ordered in that not all events in a poset are causally related to each other. A poset generated by a simulation run can

46

2. Component Interaction in Distributed Systems
be checked for validity against a set of behavioural constraints defined by the system designer. Thus Rapide does
not exhaustively check a system model against its required properties; it is up to the designer to design simulation
traces that provide adequate test coverage.

Finesse [BK98] is a coordination language for specifying interaction protocols between multiple objects. A protocol defines a number of roles, the events that may be emitted or received by each roles, and causal and temporal
relationships between events. Events are parameterised, and Finesse allows the designer to specify how the parameters of received events are related to parameters of earlier emitted events. Notable features of Finesse include the
ability to define generic protocols that can be parameterised by role types, to define protocols in terms of sequential
iterations of messages or parallel message sends, and to support multiparty communication. However, Finesse does
not currently have a defined semantics and is, as yet, unimplemented.

2.7. Summary
Current object-oriented middleware platforms provide little or no support for composing systems from prebuilt
components. Components of a system, typically objects, are defined by their provided services only. This forces
clients to use first-party binding to connect to required services, and therefore increases components’ dependence
on their context, reducing the scope for their reuse, and pollutes their implementation with irrelevant structural details. Components are limited to very few forms of interaction, typically one of RPC-like object invocation or asynchronous message passing. Other interaction mechanisms are added as ad-hoc extensions, must be implemented in
terms of the predominant style or must be implemented above lower level mechanisms that are more complex and
error prone to use. For example, Open Bindings add media stream interactions as an extension to the CORBA
standard; Java Beans components interact via method calls, properties with change notification or event dissemination, but the latter two interaction styles are implemented in terms of the first; CORBA allows asynchronous invocations through the DII but this API is complex, slow and is not type safe. No commercial distributed
programming environments supports design-time modelling and analysis of components, interaction styles or systems composed from these architectural parts.

The use of an architecture description language (ADL) makes it easier to construct systems from prebuilt parts.
Unlike non-ADL approaches, the interface of a component used with an ADL includes specification of the services
required by the component to be implemented by other components in the system. Systems are built by composition: components are instantiated and their required services bound to those provided by others. Components can
typically make use of multiple interaction styles that are often encapsulated within connectors. However, component models that use connectors treat connectors as monolithic entities, encapsulating application and transport layer issues. As highlighted by Garlan, this makes connectors difficult to implement, modify and reuse [Garlan98].
There is little tool support for the definition of new connector types. Most current ADLs are either used to support
modelling and analysis or system construction and deployment; Darwin/Regis is a notable exception. However, no
ADL that supports system construction also supports the modelling and analysis of the connectors that are actually
used in constructed systems.

47

2. Component Interaction in Distributed Systems
This introduces the requirements met by the research presented in this thesis: to develop language and tool support
for the definition of component interaction styles. Such tools need to support both modelling and analysis of interactions at design time and generate the run-time support required to use the interaction style in an executable system. The interaction model must not be monolithic: the separation of application, presentation and transport layer
concerns will allow the difficulties identified in this chapter to be addressed.

48

3. A Model of Component Interaction

A Model of Component
Interaction
My own view is that we have been wrong in taking
communication as secondary. Many people seem to assume
as a matter of course that there is, first, reality, and then,
second, communication about it.
Raymond Williams

3.1. Introduction
As discussed in chapter 2, current interface and architecture description languages do not provide the support required for designing and building large distributed systems. Those languages that allow the programmer to define
new interaction styles either aid the programmer by generating the runtime support for those interactions but limit
the types of interaction that can be defined or allow complex interaction styles to be modelled but leave their implementation completely up to the programmer. There is a need for an approach that allows programmers to specify
an interaction style such that:
• The specification can be used at design time to analyse system behaviour
• The specification is used at build time to generate runtime support for distribution and binding.
• The transport protocol used for the interaction style can be selected when bindings are established.
• Management and monitoring functionality can be inserted into bindings.

Our approach is based upon a new model for component interaction [PC98a,PC98b] and a language, named Midas,
for its realisation. The advantages of this interaction model and language over those described in chapter 2 is that
it supports both the design-time analysis of interaction styles and the construction of components and systems that
make use of those interaction styles. Design is supported by including specifications of the interaction protocol that
can be checked mechanically for deadlock or violation of user-defined constraints. Construction is supported by
translating Midas definitions into implementation language constructs that provide the “glue” to connect components using the interaction style whether they are within the same address space or across the network. The runtime
support for interaction model overcomes the problems inherent in current middleware platforms through strict separation of concerns: programmers can select combinations of mechanisms within a binding to achieve the behav-

49


Documents similaires


Fichier PDF nat thesis
Fichier PDF project part 2 question c
Fichier PDF 07 e85 heating air cond
Fichier PDF wp ringcoin en page
Fichier PDF html partie 1
Fichier PDF wdpet9 manuel fr


Sur le même sujet..