Building distributed applications is hard because of several reasons. The availability of multiple processors inherently introduces concurrency. In addition, several non-functional requirements like reliability, security and physical distribution must be dealt with. Therefore, a clean and powerful development model is required to build such applications in a manageable way.
Correlate is a research project of the DistriNet group of the Department of Computer Science of the Katholieke Universiteit Leuven. The goal of the project is to support the development of distributed application software. Our approach is based on two fundamental themes.
In our approach, an application programmer first builds a conceptual model of his/her application as a set of interacting concurrent objects. This conceptual model is expressed in the Correlate language. In a second phase, and completely orthogonal to it, physical distribution aspects are taken into account and the appliciation is physically distributed over a distributed system and additional aspects like reliability and security are taken into account. In this physical model, the application programmer adds a set of metalevels that use the Correlate metaobject protocol to implement these non-functional requirements.
Prototypes for both Java and C++ have been built to validate our ideas. We have gathered experience in using the prototype with applications in the areas of High-Performance Computing (Molecular Dynamics simulation, PDE solvers), Network Applications (routing) and multi-agent systems. This iterative process of experimenting with real-world applications has been driving the continuous improvement of Correlate.
Correlate provides the application programmer with a model of active objects. Active objects control the synchronization of concurrent requests. In Correlate, active objects are units of concurrency; only one operation is allowed to execute on an object at the same time. The application programmer can specify preconditions (guard expressions) to define in which state a certain operation can be accepted.
In the Correlate object model an object can exhibit autonomous behaviour. This way an object can perform a spontaneous action which is not triggered by external stimuli (incoming messages). At the level of a class definition, the language's syntax makes a distinction between autonomous operations and interface operations. Interface operations represent the reactive behaviour and are conceptually the same as public operations in object-oriented languages like Java or Smalltalk. Autonomous operations are invoked as soon as the object has been created and they are re-invoked when the execution of the operation is terminated.
Active objects only interact by sending messages (invoking interface operations). Correlate supports both synchronous and asynchronous message passing. Active objects are created dynamically at run-time and need to be explicitly destroyed when they are no longer needed.
Correlate supports a heterogeneous object model. Both active and passive objects are supported. Passive objects do not have any control over synchronization of concurrent requests. Neither can they have autonomous behaviour. They are always encapsulated inside an active object and they can never be shared between active objects. Invocation parameters that are instances of passive classes are thus always passed by value. Passive objects are expressed mostly in the host language, but they can if necessary interact with, create and destroy active objects.Because of this heterogeneous object model, Correlate can make use of classes written in the host language (i.e. as passive objects).
Several authors stress the importance of separation of concerns to master the complexity of developing such software. They argue that non-functional aspects should be kept as separate as possible from the application's semantics. This way, local changes to a single subsystem do not propagate over the entire system and the development process stays manageable. The use of a metalevel architecture is proposed to support this idea.
A metalevel architecture is a software architecture that enables application programs to somehow manipulate the state of their own execution. In an object-oriented environment, the central theme in this research is the study of metaobject protocols (MOPs hereafter). For a given application, the state of execution is reified in a set of metaobjects. The MOP is the documented interface to these metaobjects. Metalevel objects (i.e. objects at the metalevel) use the MOP to adapt and tune the behaviour of the application (the baselevel) independently of its functionalities.
The Correlate MOP focuses on the run-time events object creation/deletion and object invocation. A Correlate metalevel is a program that reacts to these events and implements an execution environment for the baselevel application objects. Using this MOP, we have developed customized execution environments that implement a.o. distributed execution, object replication and checkpointing. The abstract interface defined by the MOP ensures a strict separation of concerns between application and execution environment. Therefore a given metalevel can be reused for several applications and vice versa an application can be executed in different environments.
An important characteristic of our MOP is flexibility: there are very little constraints on the structure of the metalevel. This leaves the metalevel programmer with the maximum freedom to choose an appropriate architecture for the metalevel objects. For instance, the mapping between base and metaobject is under control of the metalevel programmer and can be changed during execution. Executing an application in a different execution environment (read metalevel) does not require any recompilation.
A more in-depth description of the MOP can be found in the position paper for the ECOOP'98 Workshop on Reflective Object-Oriented Programming Systems (see also the publications section). Note that this MOP is supported only starting from Correlate 3.1.
In Correlate the ease of use of aspect languages is combined with the power of runtime reflection. Meta-programmers define a policy template following a simple, general syntax. This template expresses how the meta-program can be configured. Application programmers or deployers instantiate these templates to declare their specific requirements with respect to the meta-program. An important feature of this approach here is that it is not specific to a particular non-functional requirement. This means it can be applied to any meta-program.
For more detailed information on the syntax of templates and policies, on implementation issues and for example use of the approach, we would like to refer to the paper presented at the Reflection'99 conference, also available in the publications section. Please note that there is not yet a releasable version of Correlate with policy support. A demo will be given at the OOPSLA'99 conference.