|Dream - Dream core technical documentation|
Dream Framework Core
Please send comments on this document to firstname.lastname@example.org. Authors would be glad to hear from people using or extending Dream.
Copyright 2003-2004 INRIA.
655 avenue de l'Europe, ZIRST, Montbonnot St Martin, 38334 Saint-Ismier Cedex, France.
All rights reserved.
All product names mentioned herein are trademarks of their respective owners.
1.1 MotivationsSeveral communication middleware (CMs) have been built in the past ten years [1, 2, 3, 4, 5, 6, 7]. The research work has primarily focused on providing various communication paradigms (RPC, message passing, event-reaction, publish-subscribe, ...) and on the support of various non functional properties like message ordering, reliability, security, scalability, etc. Less emphasis has been placed on configurability. From the functional point of view, existing CMs implement a fixed programming interface (API) that provides a fixed subset of communication models.
From the non-functional point of view, existing CMs often provide the same non-functional properties for all message exchanges. This reduces their performance and makes them difficult or impossible to use with devices having limited computational resources. As these non-functional properties have not been developed as independent (removable) modules, removing them often requires the code to be totally re-engineered.
To overcome these limitations, it is necessary to build modular and composable architectures. Work on configurable systems has lead, in particular, to the development of component-based and reflective middleware . The idea is to build a middleware as an assembly of interacting components, which can be statically or dynamically configured to meet different design requirements or environment constraints. While in principle applicable to different forms of middleware, existing component-based middleware have mostly been used to construct classical middleware with synchronous interactions, and with a few exceptions [9, 10], have not dealt systematically with resource configurability (i.e. the ability to control the use of resources within the middleware). Modular architectures have also been proposed to build routers  or communication sub-systems . The main limitation of these systems lies in their restricted component model, which can mainly be used for static configuration, does not support hierarchical composition, and which does not provide any control capabilitiy, thus making it hard to administer and configure systems during execution.
1.2 The DREAM frameworkDREAM is a software framework dedicated to the construction of CMs. It provides a component library and a set of tools to build middleware implementing various communication paradigms: message passing, event-reaction, publish-subscribe, etc. Figure 1 gives a general picture of the framework. DREAM builds upon JULIA, a Java implementation of the FRACTAL component model . FRACTAL provides support for hierarchical and dynamic composition. Hierarchical composition supports the construction of systems from the assembly of structured (hierarchical) sets of components. Dynamic composition provides the basis for dynamic reconfiguration, an essential feature for long-running systems.
DREAM defines 3 modules:
1.3 Structure of this documentThis document presents the core of the DREAM framework. TBD.
1.4 WarningA good knowledge of the Fractal component model and its Java reference implementation – JULIA – is necessary to understand this document. Documentation about FRACTAL and JULIA is freely available at the following URL: http://fractal.objectweb.org.
2 Component modelThis section describes the component model that is used to build DREAM components. This model, called FRACTAL [16, 17], is developed within the ObjectWeb consortium. It is a general component model that has been implemented in multiple languages. We focus on its Java reference implementation, JULIA, that is used to build DREAM components.
2.1 The FRACTAL component modelUnlike other Java-based component models such as Jiazzi  or ArchJava , FRACTAL is not a language extension but consists in a runtime library which supports the creation and manipulation of components and architectures.
FRACTAL distinguishes between two kinds of components: primitive components, which are essentially standard Java classes conforming to simple coding conventions, and composite components, which provide a means to deal with a group of components as a whole, while potentially hiding some of the features of the encapsulated subcomponents. An original feature of the Fractal component model is that a given component can be included in several other components. Such a component is said to be shared between these components. Shared components are useful, paradoxically, to preserve component encapsulation: there is no need to expose interfaces in higher-level components to allow access to a shared component by a lower-level one. Shared components are useful in particular to faithfully model access to low-level system resources.
A component is made of two parts: a controller part, which exposes the component interfaces and comprises controller and interceptor objects, and a content part, which can be either a standard Java class in the case of a primitive component, or other components (called subcomponents), in the case of a composite component.
Interfaces in Fractal correspond to access points to a component. They can be of two kinds: server interfaces, which correspond to access points accepting incoming method calls, and client interfaces, which correspond to access points supporting outgoing method calls. The signatures of both kinds of interface can be described by a standard Java interface declaration, with an additional role indication (server or client). Moreover the model allows particular client interfaces, called collection interfaces, to be bound to several server interfaces.
Communication between Fractal components is only possible if their interfaces are bound. Fractal supports both primitive bindings and composite bindings. A primitive binding is a binding between one client interface and one server interface in the same address space, which means that method calls emitted by the client interface should be accepted by the specified server interface. A primitive binding is called that way for it can be readily implemented by direct Java references. A composite binding is a communication path between an arbitrary number of component interfaces. These bindings are built out of a set of primitive bindings and binding components (stubs, skeletons, adapters, etc). The Fractal model thus provides two mechanisms to define the architecture of an application: bindings between component interfaces, and encapsulation of a group of components in a composite.
Fractal does not impose any limit on the levels of composition, and does not constrain the nature of component controllers. The Fractal library contains several kinds of controllers, which can be combined to yield components with different reflective features, and which can be extended or specialized to yield other forms of reflection and control over components. The following are examples of Fractal controllers.
2.2 ExampleThe following figure illustrates the different constructs in a typical Fractal component architecture. Thick grey boxes denote the controller part of a component, while the interior of these boxes correspond to the content part of a component. Arrows correspond to primitive bindings, and tau-like structures protruding from grey boxes are internal or external interfaces. Internal interfaces are only accessible from the content part of a component. Note that, by means of internal interfaces, a composite component can control the exposition of external interfaces of its subcomponents. External interfaces appearing on the top of a component represent controller interfaces such as AttributeController or ContentController interfaces. The two shaded boxes represent a shared component.
2.3 Julia: the Fractal's Java-based reference implementation
2.3.1 Main data structuresIn JULIA, a FRACTAL component is represented by several Java objects, which can be separated into three groups (Figure 3):
2.3.2 OptimizationsJULIA provides a continuum from static to dynamic configuration, i.e., from unreconfigurable but very efficient configurations, to fully dynamically reconfigurable but less efficient configurations. These optimizations take two forms. The first one consists in a selective merging of the objects that make up a component. The second one creates shortcut bindings between components that bypass controller objects that do not intercept any method calls. A component can only be optimized if its controllers follow some code conventions (in particular, a component cannot have two controllers that implement the same interface).
3 MessagesThis section describes the abstractions and tools provided in the DREAM framework for handling messages.
3.1 Structure of messagesMessages are Java objects that encapsulate chunks. Each chunk is a Java object that implements setters and getters. For instance, messages that need to be causally ordered have a chunk, called CausalityChunk, that encapsulates a stamp (i.e. a matrix clock), and that defines methods to set and get the stamp. Moreover, each chunk must extends the AbstractChunk class. This generic abstract class (figure 4) defines abstract methods to create a new instance of chunk of the same class, and to transfer the state of this chunk into another one.
A message may also encapsulate other messages, called submessages. Note that chunks and submessages are handled differently: messages can be considered as naming contexts for their chunks, they associate chunks with names; this is not true for submessages because they are not associated with names3.
DREAM components are not allowed to manipulate messages directly, any message operations (get, add, remove chunk and submessages) are made by the Message Manager component. This allows the Message Manager to implements complex mechanism such as persistency of message content.
3.2 Message managersMessage managers are components responsible for the life cycle and the manipulation of messages. They have a server interface, called MessageManager (figure 5, that defines methods to create, delete and duplicate chunks and messages; and methods to add, get, remove chunks and submessages from a message.
Chunks are created by Chunk Factory; these factories are managed internally by the Message Manager component. Components implementations only handle ChunkFactoryReference which are references (i.e. names) to Chunk Factory instances. The getChunkFactory allows to retrieve a ChunkFactoryReference for the given chunk class; which can be used to create a new chunk instance using the createChunk method. Each chunk instance keeps a reference to the ChunkFactoryReference that creates it, so when it is deleted the chunk may be recycled in an object pool managed by the chunk factory.
There exist two kinds of message duplication: the duplication by value returns a clone of the message; the duplication by reference returns the message itself. It is useful when the message manager pools instances of messages: this allows knowing the number of components that have a reference to a message.
3.3 Input/Output interfaces
In order to allow components to exchange messages, the DREAM framework defines Fractal interfaces called input and output. Messages are always sent from outputs to inputs (Figure 6 (a)). Output and input interfaces come in pairs corresponding to two kinds of connections: push and pull.
4 ActivitiesThis section describes the abstractions and tools provided in the DREAM framework for handling components' activities. We start this section by an overview of the activity management framework. Then we describe the components it involves. Finally, we describe the integration of activities with components' life-cycle management.
4.1 OverviewA DREAM component can either be passive or active. An active component defines tasks to be executed; a passive component doesn't; i.e. calls to other component interfaces can only be made in the tasks of a calling component. For a task to be executed, it must be registered to one of the dedicated shared components, called activity managers, that encapsulate tasks and schedulers. Schedulers are in charge of mapping higher-level tasks onto lower-level tasks. The number of scheduler levels is not limited. Tasks at the highest level are tasks registered by components. At the lowest-level, tasks wrap Java threads. These concepts are depicted in figure 9. Components A and B have registered three tasks that are scheduled by a FIFO scheduler, which maps them onto two lower-level tasks wrapping threads.
4.2 Scheduler, task and activity manager components
4.2.1 SchedulersScheduler are components with a Scheduler server interface, and a Task client collection interface. The role of a scheduler is to map higher-level tasks (to which its Task client interface is bound) onto lower-level tasks (that are bound to its Scheduler server interface).
The Scheduler interface (figure 10) defines a method schedule that is called by lower-level tasks to schedule the execution of a (set of) higher-level task(s). This method takes two parameters: executionQuanta specifies the amount of execution time the scheduler can use (a negative integer allows the schedule looping until it has no task to execute); hints specifies additional scheduling parameters. It returns an object representing the scheduling result.
The Task interface (figure 11) defines a method execute that is called by the scheduler to execute higher-level tasks. This method takes a parameter hints that allows specifying execution parameters, and returns an object representing the execution's result.
The DREAM framework currently provides the following schedulers:
4.2.2 TasksTasks are components that implement the Task interface (figure 11). We distinguish:
4.2.3 Activity managersFor performance reasons, tasks and schedulers are not Julia components but simple Java objects implementing the BindingController FRACTAL interface. They can still be considered as FRACTAL components.
The DREAM framework provides interfaces to manage tasks and schedulers. These interfaces can be used by application components or by a third party (e.g. a process deploying the middleware). The TaskManager interface (figure 12) defines methods for registering, unregistering, and interrupting tasks.
This document was translated from LATEX by HEVEA.
|Copyright © 1999-2007, OW2 Consortium | contact | webmaster | Last modified at 2008-01-28 11:51 AM|