Back to index

1 Introduction

1.1 Motivation

While programming distributed systems, one has to bear several aspects in mind. Besides coding the real application, one has to take care of reliability, detect failures, calculate distributed consensus, handle replication, manage transactions and abide to synchronisation constraints. All of these additional concerns interweave with the application code. This reduces the clarity and maintainability of the code. Other examples of interweaved aspects are transport issues, such as transparent compression or encryption/decryption of transmitted data.
All of these aspects revolve around the semantics of method invocations. The commonly used synchronised remote method invocation semantic is just not flexible enough. Several projects already deal with this deficiency, e.g. the different standardisation efforts for middleware, e.g. OMG's CORBA, Sun's Java RMI and Microsoft's DCOM. The goal is to have a flexible layer below the application code that handles the aspects of distribution and/or concurrency. This includes the possibility to introduce arbitrary new message semantics, e.g. for asynchronous or atomic invocations ([LiSh83], [TrNo98]), replicated invocations ([GuSc97], [BiSS91) or automatic migration upon invocation ([Jul88], [OkI94]). Adaptability will be even more important in the future [WSSBS99].
The motivation for the work presented in this thesis stems from this recent shift in distributed systems that emphasises the separation of concerns. An earlier version of our distributed objects system, which only had marginal support for replaceable semantics, lacked good source code readability and usability ([Hof96b], [Hof97]).
As already mentioned, every distributed or concurrent application consists of the actual application code and code responsible for co-ordination. Today's distributed systems either entangle the co-ordination code very tightly with the application code or, separate it completely from the application code with the help of one or several transparent mechanisms, which are beyond the designer's control. Our work tries to offer architectural flexibility for developers to add and apply new semantics to his/her programming environment without penalising the performance of his/her application.
Another aspect which we wanted to investigate, was the possibility to simultaneously have several semantic views of one and the same object. Common object-oriented methods such as UML [RuJB98] cannot express multiple views of objects. On the other hand, in languages such as C++ [Stro86], Java [GoJS96] or Oberon [MöWi91], different views can be defined by the programmer with respect to the different categories of clients of an object. These mechanisms in general only distinguish between the class of the object itself, the subclasses of its class and other client objects (public, protected, private, É). However, they do not allow the definition of different semantics on arbitrary sets of objects. We wanted to investigate the possibilities and applications of different views regarding the applied invocation semantics (see also [Hof99a], [Hof99b], [Hof99c] and [Hof99d]).

1.2 Contributions

Our composable message semantics offer a number of advantages over languages/systems with fixed semantics:
  • Expressive Power: They increase the expressive power of the programming model, as they allow for tailoring the semantics of method invocations. This allows for flexible transport mechanisms for network transmissions, e.g. point-to-point or group communications.
  • Separation of Concerns: They can make the complexity of programs manageable by separating different aspects to different modules.
  • Reusability: With fixed semantics, co-ordination behaviour between several objects is coded within the objects themselves. Our composable semantics enable the programmer to separate the co-ordination from the basic functionality; e.g. one could change an access protocol from a simple solution to a two-phase commit protocol without affecting existing clients.
  • Enforcing Invariants: It is easier to enforce invariant assertions among objects, if there is a module explicitly representing this behaviour.
One of our major objectives was to achieve a clean separation of the application's functional code and the semantics of method invocations. We achieved this without introducing a new language or notation. Both, the basic functional code and the co-ordination code, are implemented and programmed in the same programming language. An application programmer does not need to learn additional language constructs. This allows us to merge the parts of the application programmers and the meta programmers, i.e. to treat them the same way. We do not try to hide distribution, but we try to make its use easier. Our composable message semantics promote the migration of co-ordination code into separate modules, thereby improving maintainability and reusability.
Another contribution of this thesis are the multiple views supported by the composable message semantics framework. Different clients may see the same object through different semantic filters.
Using just-in-time stub generation, we've built a prototypical framework for composable message semantics, which is smaller and more flexible than industrial middleware platforms. We built a distributed objects system using this framework. This objects system extends the simplicity and type-safety of the Oberon system onto the network and offers run-time flexibility on parameter passing modes.
Finally, this thesis provides feedback to programming language designers, which language features promote or inhibit distribution and separation of concerns.

1.3 Overview

We split this thesis into three parts. Part one describes our composable message semantics framework. Composable message semantics can be used locally within one address space. However, we see their main application area in distributed computing. Therefore, part two describes a distributed objects system based on the composable message semantics framework. Finally, part three concludes this thesis by summarising its results.

Chapter 2 presents some terminology and gives an overview of the area of different message passing semantics. Additionally, it elaborates on this area by examining alternative approaches.

Chapter 3 gives a short introduction into the Oberon system and language used for the implementation of our prototype.

Chapter 4 presents our composable message semantics framework. It introduces, step by step, the degrees of freedom available for newly written or composed message semantics. Finally, it describes a small layer on top of the framework that hides some details of the framework if it is used within a single address space.

Chapter 5 describes the implementation of our prototype. It emphasises the technique used to offer our flexible approach without decreasing the performance compared to an implementation that offers only a fixed semantic.

Chapter 6 gives two small application examples for our composable message semantics framework. The first example generates dynamic traces of method invocations and the second demonstrates a synchronisation mechanism built by using only the composable message semantics framework.

Chapter 7 presents a distributed objects system built on top of the composable message semantics framework. It first describes some basic building blocks and ends with a longer example and some performance measures.

Chapter 8 describes the implementation of the distributed objects system. It emphasises the aspects introduced by the distribution, i.e. network transport, parallel execution and distributed garbage collection.

Chapter 9 describes two applications developed using the distributed objects. Chapter 9.1 extends the synchronisation example presented in Chapter 6.2 by adding distribution. Chapter 9.2 presents a complete implementation of a distributed file system offering transparent access to remote files and directories.

Chapter 10 summarises and concludes the thesis and presents some implications of this work on the design of programming languages and systems.

Instead of splitting related work into several parts, we merged it into Chapter 2. Even though it deals with several different aspects, it seemed to be the best way to present similar ideas regardless of whether they deal with distribution or not.

Back to index