An Infrastructure for Development of Dynamically Adaptable Distributed Components

18
An Infrastructure for Development of Dynamically Adaptable Distributed Components Renato Maia, Renato Cerqueira, and Noemi Rodriguez Pontif´ ıcia Universidade Cat´ olica do Rio de Janeiro, Departamento de Inform´ atica, Rua Marquˆ es de S˜ ao Vincente, 225 RDC, avea, Rio de Janeiro, RJ, Brazil. {maia,rcerq,noemi}@inf.puc-rio.br Abstract. Dynamic adaptation has become an essential feature in dis- tributed applications, mainly because current technology enables com- plex tasks to be performed by computers in application domains unsuited for service interruption. This paper presents an infrastructure that uses an interpreted language to provide simple but powerful features that en- able coarse and fine-grained adaptations in component-based systems, using the CORBA Component Model (CCM) as a basis. To extend the static nature of CCM, we propose dynamic containers, which enable de- velopment of dynamically adaptable components that admit changes on component structure and implementation. The extended set of mecha- nisms for component manipulation can be used to create adaptation ab- stractions that simplify the programmer’s task. In this paper, we present a tool that provides support for the protocols and roles abstractions, which allows programmers to adapt running applications, establishing new interactions among its components. 1 Introduction Much research work has focused on techniques that support software evolution, that is, techniques that allow changes to existing software to be introduced in faster and easier ways. However, most of the effort on this matter concentrates on providing flexibility statically, that is, on designing the source code used to generate the system with flexible architectures or structures [1, 2]. On the other hand, there are currently many software systems that should never be stopped, such as those for process control, e-business, life support or military applications. In these systems, interruption of service is highly undesirable, and the issue of software evolution becomes extremely expensive and troublesome. As a conse- quence, development of the first working version of the system becomes critical. Such projects are very risky, because of the high probability of underestimated time and cost constrains. In face of those problems, the software community has recognized the neces- sity of mechanisms to allow dynamic adaptation of computer systems [3], that is, the ability to change during execution. However, as in the static approach,

Transcript of An Infrastructure for Development of Dynamically Adaptable Distributed Components

An Infrastructure for Development ofDynamically Adaptable Distributed Components

Renato Maia, Renato Cerqueira, and Noemi Rodriguez

Pontifıcia Universidade Catolica do Rio de Janeiro,Departamento de Informatica,

Rua Marques de Sao Vincente, 225 RDC,Gavea, Rio de Janeiro, RJ, Brazil.

{maia,rcerq,noemi}@inf.puc-rio.br

Abstract. Dynamic adaptation has become an essential feature in dis-tributed applications, mainly because current technology enables com-plex tasks to be performed by computers in application domains unsuitedfor service interruption. This paper presents an infrastructure that usesan interpreted language to provide simple but powerful features that en-able coarse and fine-grained adaptations in component-based systems,using the CORBA Component Model (CCM) as a basis. To extend thestatic nature of CCM, we propose dynamic containers, which enable de-velopment of dynamically adaptable components that admit changes oncomponent structure and implementation. The extended set of mecha-nisms for component manipulation can be used to create adaptation ab-stractions that simplify the programmer’s task. In this paper, we presenta tool that provides support for the protocols and roles abstractions,which allows programmers to adapt running applications, establishingnew interactions among its components.

1 Introduction

Much research work has focused on techniques that support software evolution,that is, techniques that allow changes to existing software to be introduced infaster and easier ways. However, most of the effort on this matter concentrateson providing flexibility statically, that is, on designing the source code used togenerate the system with flexible architectures or structures [1, 2]. On the otherhand, there are currently many software systems that should never be stopped,such as those for process control, e-business, life support or military applications.In these systems, interruption of service is highly undesirable, and the issue ofsoftware evolution becomes extremely expensive and troublesome. As a conse-quence, development of the first working version of the system becomes critical.Such projects are very risky, because of the high probability of underestimatedtime and cost constrains.

In face of those problems, the software community has recognized the neces-sity of mechanisms to allow dynamic adaptation of computer systems [3], thatis, the ability to change during execution. However, as in the static approach,

most of the proposed solutions are based on architectures or structures that areapplied to specific portions of the system: those related to a given set of pos-sible anticipated changes. This adds extra effort on system design, which nowmust predict possible points of modification; this effort can prove useless in thefuture if none of the predicted modifications are necessary. Besides, the use ofthose techniques generally increases the complexity of system design. The mainreason for this is the lack of appropriate abstractions: mechanisms that provideflexibility are generally added to the system by merging new, adaptation-relatedcomponents with those related to the application domain.

We propose a framework for the development of components that uses com-putational reflection features as an abstraction to hide the details of dynamicadaptation mechanisms. This framework is built with the interpreted languageLua [4]. The use of a dynamically-typed interpreted language allows us to com-bine flexibility and simplicity. As a basic layer, our framework provides LuaCCM,an implementation of the CORBA Component Model (CCM). CCM extends theOMG object model with introspective interfaces and entities that allow devel-opers to implement, configure, and manage component-based applications in astandardized way. One important advantage of using CCM as a basic layer isthat the adaptation code produced with our framework can be mapped to otherCCM implementations. However, CCM is a complex model and remains in theclass of techniques that add complexity to the development process. The ideaof our framework is to use LuaCCM as a basis for the construction of differentadaptation abstractions. In this paper, we illustrate this layered approach withthe discussion of a tool that supports the protocols and roles abstractions asproposed in [5].

This paper is organized as follows: Sect. 2 presents a brief overview of themain CCM concepts; Sect. 3 presents some details about the features providedby LuaCCM; In Sect. 4 we discuss how these features can be used to implementabstractions to perform dynamic adaptations, as well as the implementation ofa tool based on the concept of protocols and roles and examples of its use toperform dynamic adaptation of a system; In Sect. 5 some related works arediscussed and, finally, some final remarks are presented in Sect. 6.

2 CORBA Component Model

The last version of CORBA defines the new CCM specification [6], which is acomponent model defined on top of CORBA architecture and is primarily in-tended to solve some problems of CORBA related to extension mechanisms andstandardization of common tasks involved in object handling, such as instantia-tion, activation, request dispatching, etc. [7]. A CCM component is defined as aset of ports and can additionally support interfaces and provide attributes likea usual CORBA object. The ports of a component are used to establish connec-tions and are divided into four categories: facets, receptacles, event sources, andevent sinks. Facets are ports that provide some interface and may be connectedto receptacles, which are ports where an object implementing some interface

may be registered. Similarly, event sources are ports that send events and maybe connected to event sinks to establish an event-based communication channel.Additionally, CCM also defines the concept of component homes that are somelimited form of component used specifically to retrieve and manage instancesof some component definition. Through a component home one can create newinstances or recover persistent component instances. Fig. 1 shows a graphicalrepresentation of the main CCM concepts and Fig. 2 shows an example of acomponent definition described using the extended version of IDL defined bythe new version of the CORBA specification.

Fig. 1. Graphical representation of CCM concepts.

1 component MyComponent supports SupportedInterface

2 : SuperComponent

3 {

4 attribute string my_atribute ;

5 provides FacetInterface my_facet ;

6 uses ReceptacleInterface my_receptacle ;

7 publishes PublishedEvent my_event_source ;

8 consumes ConsumedEvent my_event_sink ;

9 };

Fig. 2. Example of component definition in IDL 3.0.

The central concept in CCM is that of container. The container provides anexecution environment for component instances with many features like man-agement of connections on ports or implementations of event channels. Besidesthat, the container also manages creation, activation and incarnation (in case ofpersistent components that are recovered by a new instance incarnating somepreviously saved state) of instances of component implementations, which arecalled executors. This management is defined by a set of different policies asspecified in CCM specification. However, taking into consideration the nature

of the CORBA architecture, the implementation of a container requires someprevious knowledge of component definition (e.g. for implementation of porthandling), as well as of the component implementation (like policies that definehow to activate instances). As a solution, CCM defines four different categoriesof components and a set of policies that may be used to define how to handlecomponent instances of some component implementation. Additionally, specifictools are used to generate part of the container implementation related to somecomponent definition (e.g. management of ports); this generated code is incor-porated into the component implementation. This way, the same component canbe deployed in different container implementations.

3 LuaCCM

LuaCCM is an implementation of CCM using the Lua programming language.Lua is a general-purpose dynamically-typed interpreted language with usual con-trol structures (while, if, etc.), function definitions with parameters, local vari-ables, and data-description facilities. Initially, Lua was devised to be an extensionlanguage to customize industrial applications, but today it is being used in thou-sands of products and prototypes worldwide. Its success is partially related toone of its main characteristics: extensibility. Lua provides reflective facilities thatenable the extension of its semantics, making it extremely flexible.

Another important feature are the data-description facilities provided by Luathat are based on a single data structure called table. Lua tables are associativearrays that can hold values indexed by any valid value of the language. Thisfeature can be used to represent objects by tables containing values that repre-sent attributes, as well as functions that represent methods, since Lua functionsare first-class values. Object-oriented facilities are partially supported by syn-tactic sugar that simplifies invocation and declaration. Additionally, using theextension facilities of Lua, it is also possible to define object behavior-sharingmechanisms though hierarchies of object classes or prototypes [8]. In spite of allits flexibility, Lua is also a very small and simple language.

Our group investigates how the features of Lua can be used to improve thedevelopment of dynamically adaptable systems [9–13]. One of the products ofthis work is LuaOrb, which uses the extension mechanisms of Lua to definea dynamic binding of CORBA. With LuaOrb, it is possible to invoke CORBAobject operations as common Lua object methods. Additionally, LuaOrb enablesthe development of CORBA objects using Lua. LuaOrb is implemented on topof a C++ ORB (any one compatible with CORBA 2.3 specification) and usesthe CORBA Dynamic Invocation Interface to dynamically generate requests toCORBA objects according to the information provided by the CORBA InterfaceRepository. Similarly, it uses the Dynamic Skeleton Interface to receive anddispatch requests to the corresponding implementation of a particular servant.A LuaOrb servant implementation is a simple Lua object, i.e. a table containingvalues and functions. This way, we are able to dynamically change objects byreplacing the functions that implement their operations.

LuaCCM extends LuaOrb with the concepts defined in the CCM specifica-tion. However, CCM is tightly coupled with the idea of statically defined compo-nents. Unlike other language mappings, LuaCCM defines the idea of a dynamiccomponent, i.e. a component that can be changed at runtime. To allow that, wedefine the concept of a dynamic container, which can self-adapt to implementthe facilities required by some component deployed at runtime. Additionally, dy-namic containers also provide reflective facilities to adapt deployed componentinstances by changing their implementation, as well as changing the facilitiesprovided according to the new implementation. We next present the details ofthe LuaCCM dynamic container and the reflective facilities provided to performfine-grained adaptations on LuaCCM components.

3.1 Dynamic Containers

LuaCCM dynamic containers are entirely implemented in Lua, as sets of Luaobjects and LuaOrb servants. LuaOrb servants implement the external containerinterfaces, i.e. interfaces provided to component clients. The container creates aLuaOrb servant for each component instance. This LuaOrb servant implementsthe component main interface, which provides the operations of the supportedinterfaces, as well as operations to manipulate its ports. When the request of afacet is received, the container also creates a LuaOrb servant that implementsthe facet interface and dispatches all requests to the implementation of the com-ponent instance. Similarly, the container creates a LuaOrb servant at the requestof each event sink of a deployed component instance. This servant implements anevent consumer that delivers all consumed events to the implementation of thecomponent instance. The container also creates a context object, i.e. an objectthat provides the interfaces used to access the facilities provided by the containerto the component implementation, such as retrieving the objects connected toits receptacles or sending events though its event sources. CCM component im-plementations can be separated in independently activated parts called segmentsthat implement different ports. Fig. 3 depicts the infrastructure created by theLuaCCM container for a component instance.

Basically, the facilities provided by the LuaCCM container to a componentinstance are implemented by two elements: a wrapper object and a contextobject. The wrapper object is responsible for creating LuaOrb servants thatrepresent the component, receiving requests or events and dispatching themto the component executor. Additionally, the wrapper object also implementsthe operations of the main component interface related to port handling, likethe operations used to get facets or connect objects to receptacles. The contextobject is responsible for holding the references of objects connected to componentreceptacles and delivering the events sent through component event sources.

Each time an implementation of a new component definition is installed, thecontainer creates a definition manager, which retrieves the component defini-tion (e.g. from a package descriptor or a component interface repository) anddynamically generates the implementation of the facilities provided to the newcomponent by defining a wrapper object class and a context object class. Every

Fig. 3. LuaCCM container structure.

time a new instance of that component definition is created, those classes areinstantiated to produce the wrapper object and the context object for that par-ticular instance. This behavior enables the dynamic adaptation of the container.Suppose that some component definition is modified and the corresponding def-inition manager is notified. Then, the wrapper and context object classes areadapted to implement new facilities according to the new component definition.As a result, every instance of the wrapper and context classes reflects the adap-tation and provides the new facilities to every instance of that component defi-nition installed in the container. Alternatively, the adaptation can be performedon a single instance of a component by adapting only the wrapper and contextobjects of that instance: that can be done replacing the functions provided bythe wrapper and context classes.

On the other hand, the dynamic container must also provide facilities toadapt the component executors. For example, if a new facet is added to thecomponent definition, then the component executor must provide the new facetimplementation. This is done by the definition of a segment constructor, i.e.a function used to create an object that implements an added facet or eventsink and is added to the component executor as a new segment. The segmentconstructor is added to the wrapper class definition as a new field and can beused by the wrapper object to retrieve a facet or event sink implementation whennecessary. When the adaptation is done only in a single instance of a component,the segment constructor is added directly as a field of the wrapper object.

It is worth noticing that all component interactions are done by means ofthe wrapper and context objects. This enables the introduction of interceptorsto handle the interactions of the component. The use of interceptors is usefulto change the current behavior of a component, e.g. the services provided by afacet. As segment constructors, interceptors are defined as fields in the wrapperobject or class. When a wrapper object receives a request to a port, it checks

if there is a defined field that specifies an interceptor for that port; if so, theinterceptor is invoked to treat the request properly. The next section describeshow the features of the dynamic container are used to implement the reflectivefacilities provided by LuaCCM components that allow fine-grained adaptationsby changes on component definition and implementation.

3.2 Reflective Components

LuaCCM dynamic containers can be dynamically adapted to provide the re-quired facilities for a new component definition. Similarly, the same feature canbe used to adapt the container to some modification on component definition.We propose the use of reflective facilities to manipulate components. Basically,we define mechanisms for introspection and intercession [14] of components def-inition and implementation. The CCM specification defines interfaces for intro-spection of component definition that are supported by all components. Thoseinterfaces are used to retrieve information about the ports of a component, liketheir names, interfaces provided or requited, events emitted or consumed, etc.Additionally, those interfaces provide generic operations to manipulate compo-nent ports, for example to connect an object to a component receptacle giventhe name of the receptacle.

However, CCM does not provide mechanisms to define changes on componentstructure (i.e. definition) or implementation. As a new intercession mechanism,we provide an interface called ::LuaCCM::Adaptable that provides operationsto add or remove component ports, as well as to attach interceptors to existingports. Fig. 4 illustrates the interfaces defined by LuaCCM, suppressing excep-tion statements for sake of simplicity. The operations on ::LuaCCM::Adaptableinterface for addition of ports receive as arguments the name of the new portand, in the case of facets or receptacles, the interface provided or required, and,in case of event sources and sinks, the event emitted or consumed. Notice thatadd facet and add consumer operations receive an additional parameter con-taining a piece of Lua code that defines the implementation of the added facetor event sink segment. Similarly, the operation intercept, used to attach aninterceptor to a component port, also receives a parameter containing a piece ofLua code that defines the implementation of the port interceptor.

LuaCCM interceptors are common Lua objects that provide interceptionoperations, namely a before operation and an after operation. Both operationsreceive the self parameter used to identify the interceptor object that is notifiedof the method called, plus the request parameter, which is a table containinginformation about the intercepted request, such as the port name, port segment,operation name and parameters, etc. As one may suppose, the before operationis invoked just before an interaction is started through the component port,such as the execution of an operation on a facet or on an object connected to areceptacle, or even before the processing of a received event, or the emission ofa new event. Additionally, the interaction can be cancelled and never passed tothe component executor. To do so, the before operation must define the returnvalues of the intercepted operation in the table containing information about the

1 module LuaCCM {

2 typedef string LuaCode;

3

4 interface Adaptable {

5 void add_facet(in string name, in string iface,

6 in LuaCode code);

7 void add_receptacle(in string name, in string iface,

8 in boolean ismultiple );

9 void add_emitter(in string name, in string event_type );

10 void add_publisher(in string name, in string event_type );

11 void add_consumer(in string name, in string event_type,

12 in LuaCode code);

13 void remove_port(in string name);

14 void intercept(in string point , in LuaCode code);

15 void unintercept(in string point );

16 };

17

18 interface AdaptableContainer : :: Components :: Container {

19 Adaptable get_component_adaptor (in string name);

20 };

21 };

Fig. 4. LuaCCM adaptation interface.

intercepted request. In case of intercepted event ports, since the event handlermethod returns no value, the before operation must define an empty list ofreturn values prior to canceling the processing of the event. Similarly, the afteroperation is invoked after an interaction is performed through the componentport. Fig. 5 illustrates the definition of an interceptor.

1 interceptor = {

2 before = function(self, request)

3 <implementation>4 end,

5 after = function(self, request)

6 <implementation>7 end,

8 }

Fig. 5. LuaCCM interceptor definition.

The reflective features of LuaCCM components can be used to provide aseamless mechanism of dynamic adaptation without additional effort of the sys-tem developer. However, dynamic adaptation is generally a complex task, mainly

because it is a peculiar form of system development that is done while the systemis running. Like usual system development, dynamic adaptation can be improvedby the use of programming abstractions and tools based on those abstractions.In the next section, we discuss how the features provided by LuaCCM infras-tructure can be used as a basis for implementation of programming abstractionsfor dynamic adaptation of computer systems.

4 Adaptation Abstractions

LuaCCM provides reflective mechanisms to perform fine-grained adaptationson component systems through the use of interfaces that can be used by anyCORBA application to introduce changes on the system. However, the directuse of these interfaces remains a complex task. Using Lua’s facilities, we canuse LuaCCM as a basis for providing the programmer with different abstrac-tions that organize the adaptation in a structured and modularized way. Thisorganization makes the adaptation easier to design and understand, since a setof changes related to some particular subject or purpose can be separated intogroups defining some particular aspect or functionality of the system. As a val-idation of this approach, we implemented a tool based on abstractions calledprotocols and roles.

4.1 Protocols and Roles

[5] proposes the abstractions of protocols and roles to describe dynamic adapta-tions of running applications developed using the middleware Comet. A role isan abstraction used to define a set of characteristics (defined as a set of changes)that a component must provide prior to producing new behavior (or “perform-ing a new role”). More specifically, those changes are defined as a set of newconnectors (i.e. ports) and changes on original connectors by use of interceptors.On the other hand, a protocol is an abstraction used to describe how a set ofroles are applied to different components, and how those modified componentsare connected to produce the new aspect or functionality of the system. Theprotocol is defined by a set of scripts, each one defining how roles are appliedand components are combined to produce one different feature. The protocolscan optionally define an internal state.

With the data-description facilities of the Lua language, we can provide asimple way to describe roles for CCM components, i.e. describe a list of addedand intercepted ports, including the interfaces or events used, as well as the portor interceptor implementation when necessary. The structure of a role descriptionin Lua using our proposed tool is illustrated in Fig. 6, where the role definesa new facet called inspector, including its implementation code defined as astring (Lua uses the [[ ]] delimiters to declare multi-line spanning strings) thatcreates an object (table) with two operations. The added facet provides theoperation get field, which returns a string representation of the value of afield on the object implementing some component segment. Additionally, we

can use the extension mechanisms of Lua to define special semantics for roledefinitions, in such a way that the changes described can be translated to asequence of operation calls on the adaptable interface of a LuaCCM component.As an example, Fig. 7 shows the sequence of operation calls to apply the changesdefined by the role on Fig. 6 using the LuaCCM adaptable interface.

1 Inspectable = loaf.Role {

2 provides = {

3 inspector = {

4 interface = "eventflow :: distdebug :: Inspectable",

5 code = [[{

6 get_field = function(self, port, field)

7 local executor = self.context:get_executor(port)

8 return executor[field]

9 end,

10 }]],

11 },

12 },

13 }

Fig. 6. Example of role definition using LuaCCM that provides inspection facilities.

1 adaptor = component:provide_facet("adaptation")

2 adaptor:add_facet(

3 "inspector", "eventflow :: distdebug :: Inspectable",

4 [[{

5 evaluate = function(self, port, field)

6 return self.context:get_executor(port, field)

7 end,

8 }]])

Fig. 7. Example of role definition using LuaCCM that provides reflective facilities.

The implementation of the protocol abstraction in Lua is even simpler. Aprotocol can be described as a set of functions implementing the scripts usedto apply roles and connect components. Alternatively, those functions can bestored in a table or used to define an object. In the last case, the protocol canuse the internal state provided by the Lua object in the execution of protocolscripts. Fig. 8 illustrates the definition of a protocol, defined as a Lua object,that uses the Inspectable role of Fig. 6 to inspect components. The next sectionpresents a dynamic adaptation of a hypothetical event-based application using

our tool based on protocols and roles. All the examples illustrated in the currentand next sections are based on examples described in [5].

1 InspectionProtocol = {

2 inspect = function(self, component , port, field)

3 Inspectable:assign(component)

4 local inspector = component:provide_facet("inspector")

5 local value = inspector:get_field(port, field)

6 Inspectable:unassign(component)

7 return value

8 end,

9 }

Fig. 8. Example of protocol definition as a Lua object.

4.2 Use Examples

To illustrate the use of our tool, we implemented an event-based application usingour prototype of LuaCCM, which implements all the featured presented in thispaper. This example application consists of an event producer component andtwo other components that process the produced events. The component serverproduces events and sends them through an event source called produced. On theother side, the components client1 and client2 receive the produced eventsthrough an event sink called raw. The events are processed and sent back tothe server, as requests for a new event, through the event source done, which isconnected to the request event sink on the server. Fig. 10 shows the definitionof the example application components, interfaces and events in IDL 3.0.

As an example of a possible adaptation, we discuss the dynamic inclusion ofa mechanism for event flow synchronization that avoids that some client com-ponent gets stuck with an overloaded amount of unprocessed events. To do so,we define two roles: the FlowWatcher role that defines the new functionality re-quired by the synchronized processing component, and the FlowRegulator rolethat defines the new functionality required by the producer component. Theinterfaces used by the flow synchronization roles are listed in Fig. 11

The FlowWatcher adds the functionality needed to analyze the flow of eventsreceived by a processor component, in order to identify flow glitches, i.e. whenthe amount of received events is greater than the processing capacity of thecomponent. The new functionality is provided by the interception of port rawand addition of two ports: the facet limit, used to define a processing time upperlimit used to trigger the synchronization, and the receptacle regulator, thatprovides the interface used to regulate the event production rate at the serverwhen a glitch is identified. Fig. 12 shows the definition of the FlowWatcher.The flow analysis is done by the interception of port raw, which captures the

Fig. 9. Example event based application architecture.

1 module eventflow {

2 interface Instrumented {

3 attribute string name;

4 attribute float speed;

5 };

6 interface Controlable {

7 void start ();

8 void stop ();

9 void pause ();

10 void continue ();

11 };

12 eventtype SerialEvent {

13 public long seq_no;

14 };

15 component Producer supports Instrumented {

16 provides Controlable controller;

17 consumes SerialEvent request;

18 publishes SerialEvent produced;

19 };

20 home ProducerHome manages Producer {};

21

22 component Processor supports Instrumented {

23 consumes SerialEvent raw;

24 emits SerialEvent done;

25 };

26 home ProcessorHome manages Processor {};

27 };

Fig. 10. Example event based application using LuaCCM.

1 module eventflow {

2 module flowsync {

3 interface Rateable {

4 void set_rate(in double rate);

5 };

6 interface Limited {

7 attribute double value;

8 };

9 };

10 };

Fig. 11. Interface used by flow synchronization roles

time immediately before the event is processed by the component, and latercalculates the total processing time, when event processing is completed. If theevent processing time is larger than the limit defined at the limit facet executor(LuaOrb maps attributes to Lua object fields), then the object connected to theregulator receptacle is used to define a proper event production rate.

However, the original event producer component does not provide function-ality to regulate event production rate. Therefore, we define the FlowRegulatorrole to add this functionality to the server component. This is done by adding anew facet and the interception of port produced, that is used to send producedevents. The added facet is called rater and is used to define the rate of eventsproduced by the component, that is stored as a field of the context object (thecontext object can be used as a state shared by all component segments). Thisway, every time a new event is produced and sent through the produced port, itis intercepted by the FlowRegulator role that calculates the time elapsed sincethe last event was produced. If this time is shorter than the current event pro-duction rate, then a delay is inserted prior to sending the event. Fig. 13 showsthe definition of the FlowRegulator role.

In spite of the functionality provided by the roles appliance, to produce thedesired result we also need to establish new connections using the added ports.Therefore, to conclude our example we define a flow synchronization protocol asillustrated in Fig. 14. This protocol creates an object with the sync operationused to synchronize two components by applying the previously presented rolesand establishing the required connections between the modified components.LuaCCM provides simplifications to handle component ports as object fields asshown on sync operation. Those simplifications hide part of CCM complexityrelated to connection of ports.

5 Related Work

Several works address the problem of modifying computer systems at runtime [3].However most of the mechanisms proposed in literature are aimed at coarse-grained adaptations through the use of reconfigurations using different approaches,

1 FlowWatcher = loaf.Role {

2 provides = {

3 limit = {

4 interface = "eventflow :: flowsync :: Limited",

5 code = [[ { value = 0.05 } ]],

6 },

7 },

8 uses = {

9 regulator = { interface = "eventflow :: flowsync :: Rateable"},

10 },

11 before = {

12 raw = {

13 code = [[

14 function(self, request)

15 request.start_time = get_time ()

16 end

17 ]],

18 },

19 },

20 after = {

21 raw = {

22 code = [[

23 function(self, request)

24 local now = get_time ()

25 local time_spent = now - ( request.start_time or now)

26 local limit = request.context:get_executor("limit")

27 if time_spent > limit.value then

28 local regulator = request.context:get_connection_regulator ()

29 if regulator then regulator:set_rate(time_spent ) end

30 end

31 end

32 ]],

33 },

34 },

35 }

Fig. 12. FlowWatcher role definition.

1 FlowRegulator = loaf.Role {

2 before = {

3 produced = {

4 code = [[

5 function(self, request)

6 local now = get_time ()

7 local last = self.last or now

8 self.last = now

9 local time_spent = now - last

10 if request.context.rate and

11 time_spent < request.context.rate then

12 sleep(request.context.rate - time_spent)

13 end

14 end

15 ]],

16 },

17 },

18 provides = {

19 rater = {

20 interface = "eventflow :: flowsync :: Rateable",

21 code = [[{

22 set_rate = function(self, rate)

23 self.context.rate = rate

24 end,

25 }]],

26 },

27 },

28 }

Fig. 13. FlowRegulator role definition.

1 FlowSyncProtocol = {

2 sync = function(self, server , client)

3 FlowRegulator:assign(server)

4 FlowWatcher:assign(client)

5 client.regulator = server.rater

6 end,

7 unsync = function(self, server , client)

8 client.regulator = nil

9 FlowRegulator:unassign(server)

10 FlowWatcher:unassign(client)

11 end,

12 }

Fig. 14. Flow synchronization protocol definition.

as for instance the ones discussed in [15]. Our group have been investigating dif-ferent dynamic adaptation techniques based on the features provided by inter-preted languages. In that sense, using the features of the Lua language, we haveproposed many platforms and architectures using different approaches to per-form dynamic adaptations, such as LuaOrb [9] that provides a dynamic bindingfor CORBA that can be used to perform fine-grained adaptations on CORBAobjects [16]; ALua [10], an event-based asynchronous platform for parallel ap-plications that allows dynamic definition of code to be executed on differentcomputing nodes; and LuaTS [12], a reactive event-driven tuple space. Similarly,other works use the features of the Lua language to perform reconfigurations, likeLuaSpace [11], that provides features that add flexibility to perform reconfigura-tion of CORBA-based applications. The architecture for self-adaptive CORBAbased applications proposed in [13] provides mechanisms to start reconfigura-tions based on monitoring facilities.

Other groups have also proposed infrastructures to perform fine-grained adap-tations, like the Lasagne model presented in [17] that uses additional informationinserted on component requests to dynamically select different adaptations onsystem components by selection of wrappers that intercept component interac-tions. Every collaboration started by a new client request defines the set of wrap-pers that must be applied to the component prior to handling request properly.Differently from the LuaCCM model, Lasagne provides means to consistently ap-ply adaptations over a distributed environment, as well as to maintain differentclient-specific views of the performed changes.

Still on the subject of fine-grained adaptations, [5] points out the necessityof abstractions for such adaptations by the proposition of the protocol and rolesabstractions to describe dynamic adaptation of applications developed using theComet asynchronous event-based middleware. Our work uses the LuaCCM fea-tures to provide the same abstractions for CCM applications with a complexitycompatible to the original approach on Comet middleware, validating the appli-cability of those abstractions on more complex component models. By adoptinga layered approach, we hope to be able to provide a range of abstractions builton LuaCCM, instead of focusing only on one specific adaptation abstraction.

6 Final Remarks

In the past we have explored the flexibility that the use of an interpreted,dynamically-typed language can bring to component-based programming. Webelieve that the work in this paper goes one step further in this direction. Onone hand, we discussed how Lua (or an alternative language with similar fea-tures) allows simple adaptation abstractions to be built on top of a standardmodel for component management and configuration. On the other, we showedthat component models themselves can be more flexible and admit more powerfuladaptation mechanisms when designed with such a language. The basic LuaCCMfeatures, inherited directly from CCM, allow for coarse-grained adaptation, pro-viding mechanisms for application reconfiguration through the definition of new

connections. With dynamic containers and reflective components, we gain thepossibility of fine-grained adaptation, through changes on component definitionand implementation. Such adaptations are important to add more flexibilityprior to better adapt the system in face of requirement changes not predictedon its original design.

In this work we explored only the protocols and roles abstractions. However,we intend to implement other adaptation abstractions with similar purposes,such as the idea of dynamic contracts based on the coordination-oriented ap-proach proposed in [18]. A contract defines the computation related to coordi-nation of interactions between system components, which is merged into com-ponent implementation prior to result in a coordinated group of components.We intend to use the fine-grained adaptations mechanisms of LuaCCM to pro-vide means to specify and change contract definition at runtime. Alternatively,we plan to investigate the use of aspect-oriented abstractions that can be im-plemented using the interception facilities of LuaCCM components and may beuseful to define and adapt crosscutting concerns of component-based systems.We believe the mapping of these abstractions to LuaCCM will be easy, and willenable us to experiment with coordination, aspects and other abstractions incomponent-based applications.

The use of a C++ ORB in the implementation of LuaOrb provides meansof reducing performance problems due to the use of an interpreted language likeLua. Additionally, Lua presents good performance results if compared with otherscripting languages [19]. However, we intend to provide performance comparisonsof LuaCCM with other CCM implementations, like MICO and OpenCCM.

We would specifically like to study adaptations that need some type of atom-icity. One example is that of adaptations spanning different containers. Althoughit is possible to apply a sequence of modifications over different containers, thereis no guarantee of atomicity: it is possible that client applications “see” incon-sistent states where only some of the containers have been modified. Anotherexample is that of a sequence of modifications over one same container thatshould be viewed as a single adaptation step. We intend to study the require-ments of these adaptations and eventually include new mechanisms to supportthem in LuaCCM.

Finally, we believe that the features provided by LuaCCM compose an ap-propriate environment for experimentation on dynamic adaptation, especiallyon evaluation of different approaches considering aspects like simplicity or ap-plicability.

References

1. Gamma, E., Helm, R., Johnson, R., Vlissides, J.: Design Patterns — Elements ofReusable Object-Oriented Software. Addison-Wesley Professional, Boston, USA(1994)

2. Gouveia, J., Koutsoukos, G., Andrade, L., Fiadeiro, J.: Tool support forcoordination-based software evolution. In Pree, W., ed.: Proceedings of TOOLSEurope 2001, Zurich, Switzerland, IEEE Press (2001) 184–196

3. Liu, X., Yang, H., eds.: Proceedings of the International Symposium on Principlesof Software Evolution 2000, Kanazawa, Japan, IEEE Press (2000)

4. Ierusalimschy, R., Figueiredo, L.H., Celes, W.: Lua — an extensible extensionlanguage. Software: Practice and Experience 26 (1996) 635–652

5. Peschanski, F., Briot, J.P., Yonezawa, A.: Fine-grained dynamic adaptation of dis-tributed components. In Endler, M., Schmidt, D., eds.: Proceedings of Middleware2003. Volume 2672 of Lecture Notes in Computer Science., Rio de Janeiro, Brazil,Springer-Verlag (2003) 123–142

6. Object Management Group Needham, USA: CORBA Component Model - Version3.0. (2002) document: formal/2002-06-65.

7. Wang, N., Schmidt, D.C., O’Ryan, C.: An overview of the CORBA componentmodel. In Heineman, G., Councill, B., eds.: Component-Based Software Engineer-ing. Addison-Wesley Professional, Boston, USA (2000)

8. Stein, L.A., Lieberman, H., Ungar, D.: A shared view of sharing: The Treaty ofOrlando. In Kim, W., Lochovsky, F.H., eds.: Object-Oriented Concepts, Databasesand Applications. ACM Press/Addison-Wesley, Boston, USA (1989) 31–48

9. Cerqueira, R., Cassino, C., Ierusalimschy, R.: Dynamic component gluing acrossdifferent componentware systems. In: Proceedings of DOA’99, Edinburgh, Scot-land, IEEE Press (1999) 362–373

10. Ururahy, C., Rodriguez, N., Ierusalimschy, R.: ALua: Flexibility for parallel pro-gramming. Computer Languages 28 (2002) 155–180

11. Batista, T., Rodriguez, N.: Dynamic reconfiguration of component-based applica-tions. In: Proceedings of PDSE 2000, Limerick, Ireland, IEEE Press (2000) 32–39

12. Leal, M., Rodriguez, N., Ierusalimschy, R.: LuaTS - a reactive event-driven tuplespace. Journal of Universal Computer Science 9 (2003) 730–744

13. Moura, A.L., Ururahy, C., Cerqueira, R., Rodriguez, N.: Dynamic support fordistributed auto-adaptive applications. In Wagner, R., ed.: Proceedings of ICDCS2002, Vienna, Austria, IEEE Press (2002) 451–458

14. Demers, F.N., Malenfant, J.: Reflection in logic, functional and object-oriented pro-gramming: a short comparative study. In: Proceedings of Workshop on Reflectionand Metalevel Architectures and their Applications in AI (IJCAI’95), Montreal,Canada, IJCAII/AAAI/CSCSI, Morgan Kaufmann (1995) 29–38

15. Tosic, V., Pagurek, B., Esfandiari, B., Patel, K.: On various approaches to dynamicadaptation of distributed component compositions. Technical Report OCIECE-02-02, Ottawa-Carleton Institute for Electrical and Computer Engineering (OCIECE),Ottawa, Canada (2002)

16. Martins, M.C., Rodriguez, N., Ierusalimschy, R.: Dynamic extension of CORBAservers. In Amestoy, P., Berger, P., Dayde, M., Duff, I., Fraysse, V., Giraud,L., Ruiz, D., eds.: Proceedings of Euro-Par’99. Volume 1685 of Lecture Notes inComputer Science., Toulouse, France, Springer-Verlag (1999) 1369–1376

17. Truyen, E., Vanhaute, B., Jørgensen, B.N., Joosen, W., Verbaeton, P.: Dynamicand selective combination of extensions in component-based applications. In: Pro-ceedings of ICSE 2001, Toronto, Canada (2001) 233–242

18. Andrade, L.F., Fiadeiro, J.L.: Coordination: The evolutionary dimension. In Pree,W., ed.: Proceedings of TOOLS Europe 2001, Zurich, Switzerland, IEEE Press(2001) 136–147

19. Calpini, A.: Computer language shootout. http://dada.perl.it/shootout/ (2003)