Evolution of Code through Asynchronous Services

24
Evolution of Code through Asynchronous Services Manuel Oriol [email protected] PhD Thesis Preliminary Report for the obtention of the grade of ”Docteur ` es Sciences ´ Economiques et Sociales de l’Universit´ e de Gen` eve, mention Syst` emes d’Informations”

Transcript of Evolution of Code through Asynchronous Services

Evolution of Code through Asynchronous Services

Manuel [email protected]

PhD Thesis Preliminary Reportfor the obtention of the grade of

”Docteur es Sciences Economiques etSociales de l’Universite de Geneve,mention Systemes d’Informations”

Abstract

In this thesis preliminary report we advocate the fact that connections betweendifferent software entities is a stop to make application evolve at runtime. Ourgoal is then to free entities from connections. Therefore, we build a disconnectedcommunication architecture based on three main concepts: associative naming,late binding and asynchrony of communications. Communications occur follow-ing an all-service approach (e.g. a method is a service) where service requestand invocation occur through a semantic description. The choice of the servicethat best matches the description of the requested service is performed at themoment of the invocation.

1 Introduction

In current days, computation is everywhere. Programs exist to make choices,serve, and help people doing almost every common task. They are used for man-aging cars, portable phones, computers, nuclear power plants, satellites and alsomany other devices. Many of them are needed to have nearly one hundred per-cent availability. This would eventually be possible for a given program to runcontinuously without changes if it was perfect, which is impossible for two mainreasons. Firstly, programs are made by people. Perfection is then inaccessible aswell as bug-prone software. These bugous software, thus, need to be correctedin order to remove security holes or make them work better. Secondly, initialrequirements change over time as user needs evolve unexpectedly and also tech-nologies and knowledge in a particular field may change the way the softwarehas been envisioned to work.

The main point is probably that many programs are used continuously formanaging critical tasks. It is thus important to be able to maintain these ap-plications at runtime. In the object paradigm, it is possible to make programsevolve dynamically through the extensions of types by extending classes to spe-cialize them. Type-safety appears then as the main guarantee one can have forthe good functioning of a program. The problem for using this approach is thatit is very restrictive regarding to which changes may be made on classes. Typi-cally, it forces to keep the main inheritance structure. It also does not addressthe transformation of the old objects type into new ones.

Our approach does not participate of this trend and tries to consider theproblem by suppressing its main cause, namely connections between entitieswhich are the different links that may let a programmer to pass from one entityto another. Thus, we may make arbitrary changes. In this paper we thesis pre-liminary report a general model for code evolution, using interactions betweensoftware entities based on disconnected communications.

In section 2, we motivate more precisely our point of view, in section 3, wepresent the architecture itself and its mechanisms, in section 5, we mention somerelated work, and evoke future work, and finally conclude in section 7.

2 Toward Disconnection

Research on evolution of code consists on studying the different possibilities formaking programs evolve over the time. It is usually accepted that this studymay be split-ted in two different areas: static evolution and dynamic evolu-tion. The static evolution area consists in techniques and theories that ease themaintenance of programs through the controlled modifications of their sourcecode. Studying dynamic evolution consists in building operational models thatlet programmers modify programs without stopping them. This may includetechniques migrating objects/data belonging to an old version of a class/datastructure to a new version, as well as modifying at runtime the code bindings.Generally speaking, evolutions supported by an architecture (whether staticor dynamic) may be anticipated or unanticipated. Anticipated evolutions arepossible evolution that have been identified at the first design time of the ap-plication (e.g. functionalities that may be added through a plug-in mechanismeither statically or dynamically) but that are handled by the application design

1

itself rather than by the programming platform/infrastructure. It constitutesa proactive way of evolving for an application. Unanticipated evolutions areevolutions that may completely change the structure of the application and,potentially, its functionalities. These evolutions are typically handled by theprogramming platform and are generally reactive. In this thesis preliminaryreport, we consider the problem unanticipated dynamic software evolution inobject oriented programming languages.

We identify the problem of connection as a fundamental problems of unan-ticipated dynamic software evolution. Concretely, the connection effect arisesin few cases that we identify here. We say that a piece of code is connected toanother in the following case:

• When a class inherits from another.

• When an object is an instance of a class.

• When when there is a direct reference form an object to another.

• When there is a blocking method call from one class to another.

• When there are synchronization constraints between different pieces ofcode.

These connections between software entities make them dependent one ofeach other and thus complicate or limit severely updating of running applica-tions. For instance, programmers have to take into account the fact that defi-nitions changed and that called code may need wrappers to be correctly called,that data is coded in a particular way and need to be transformed accordingto a new format, that classes have changed and that objects need a significantmodification of structures, and maybe that we have to wait until a method re-turns. Each of these points presents in itself a difficult question that is still notsolved for strongly coupled structures of data and code (e.g. objects/classes)although it seems that functional programming have found satisfying solutions[17, 21] in defining checkpoints that allow to change running code and definingwrappers on data structures that evolved and then keep type-safety.

In order to alleviate the maintainer’s work from the burden of connectionsmanagement, we propose a solution that removes completely connections be-tween entities. This solution is based on the three following concepts:

Associative Naming. We provide a mechanism based on anonymity of enti-ties. This means that a calling entity cannot know a priori which entitywill answer a service invocation and, in fact, it does not matter as soon aswe know that the task to achieve is correctly done. This means also thatthere is no reference on other entities code (anonymity).

Late Binding. Because of anonymity, any entity asking for an invocation can-not know for sure which code will be executed. To achieve this, program-mers must specify the kind of action they want to be invoked and alsowhen creating components must describe the kind of action they provide.At our sense, it is most important to qualify a service and be sure of itsbehavior rather than simply reference its name without any assurance onits behavior.

2

Asynchronous Communications. All invocations will be one-way. This meansthat calling entities do not wait for an answer. Invocations are asyn-chronous: a service invocation returns immediately, the calling entity con-tinue its execution. The answer will possibly arrive later, once a corre-sponding service has been found. As a consequence, in case of missinganswers, entities will not know if the action has been taken into accountby the entity contacted.

An architecture, based on these concepts, frees the entities from connectionand enables easy software evolution at runtime compared to a traditional objectarchitecture because no reference has to be redirected. In the next section, wedescribe our architecture and its implications.

3 Architecture Description

In this section, we describe our architecture based on associative Naming, latebinding and asynchronous communications. We begin with a general descrip-tion, then we discuss how to describe services and how to find them, and finallygive an example of code. Connections between entities take the following form:

3.1 Communication Model

The proposed architecture we describe is based on entity and services (see figure1). An entity is a software coupling data and services.

Data

service 1

service 3

service 2

service n

... ...

Peer & Peer Services

Figure 1: Entity Presentation.

Informally this corresponds to the notion of objects and methods. Sinceour architecture is generic enough to be applied to small grained systems suchas object-method based architectures, but also to more coarse grained systemsas agents-Internet Services systems, we will use the terms calling/answeringentities and services for the request satisfied by the entities. A service is a pieceof code coupled with a formal description of it.

Applications we consider are an aggregate of entities that may need to re-quest services to other entities. Entities do not communicate directly, theyaddress their requests to the Service Manager (see figure 2) that is in charge offinding an adequate service to invoke. Available services have to be announcedto the Service Manager using a service description. The invocation process isdecomposed in the following steps (figure 2):

3

Peer Network

Service Manager

Request

Tag Return

Service Invocation?1

2

3

4Matching

&Tag Generation

Figure 2: Service Invocation.

1. Request for a service to the Service Manager. The message comprises thearguments, a description of the requested service, and a value quantifyingat what minimal point the called service has to match.

2. The Service Manager performs a matching and generates a unique tagassigned to the request.

3. The Service Manager sends immediately the tag to the caller. The tagwill, possibly, be used later for receiving the answer.

4. The Service Manager invokes immediately the callee with arguments anda description of how the service matched.

To fix ideas we show here how to write an invocation of service in a Java-likelanguage:

Tag T = Invoke(Description of service,Minimal Matching); where ”De-scription of service” consists in series of labels that have to match and ”minimalmatching” is the minimal adequacy between the desired service and the servicethat will be effectively invoked.

As we see in the invocation process, the call is associative because the callingentity requests a service by a description of it, and not by naming it explicitly,it is also asynchronous because the service invocation returns immediately, andfinally the binding of methods is made lately because the choice of the actualcode is done dynamically through a matching process.

The generation of a tag for each message may look inappropriate at firstsight, but these tags provide several features: to re-establish a communicationchannel in either way and to delegate answer collection to other entities (tonewer versions for instance).

To better understand how answers to requests are given and how the tagexistence enables asynchronous service satisfaction, we give here a small examplewhere there is a call of service that waits for an answer. In figure 3 the fourfirst steps are the same steps already presented in figure 1, we detail now thethree other steps, needed for the answer, that correspond to a mirrored versionof the steps necessary for the invocation:

5. In this scheme, the initial caller created and registered a service for collect-ing the answer and uses the tag T in the description of this service. Whenanswering, the initial callee uses the tag T, received at the invocation, in

4

Peer Network

Service Manager

RequestTag T Return

Service Invocation

?1

2

3

4

Matching&

Tag Generation

Answering RequestUsing T

5

Creation of Service using T

with announce to theService Manager

6

7 AnswerDelivered

Figure 3: Service Invocation and Answering

Services Manager

Request

Tag T Return

Service Invocation?1

2

3

4

Matching&

Tag Generation

Old Version New version

Figure 4: Service Evolution

order to call the service built on it (this part of the step is similar to step1).

6. The matching for the service related to the tag, and a new tag generationprocess are done (similar to step 2 and 3).

7. The answer is delivered to the initial calling entity by invoking service(thisstep is similar to step 4).

Replacing an entity by another (figure 4) for future calls is now straightfor-ward as it is only necessary to introduce the new entity with a state transferprotocol and the other entities remain unchanged. Actual invocations are thenredirected to the new answering entity, transparently for the calling entity. Insuch case, splitting an entity into several ones is made by splitting servicesinto two groups and then by affecting them to two different entities. Mergingtwo entities is done by merging the two groups of services. In fact, becauseof disconnection, and the late binding process we use, it is possible to make anapplication evolve just by introducing new entities that host services that matchbetter the service descriptions that are were provided by the older version.

3.2 Service Description

In this section, we explain how to describe services. In the previous section, weshowed that our communication model concentrates in disconnecting softwarecomponents. This means that we have to provide a way to describe services

5

that would allow not to have hidden references. This description model weprovide should let us bing names at runtime through an associative naming likein shared spaces (the Linda[4, 5, 6] model being a good representant of them).In our model, describing services, may be effected using tree-like structures.The matching is then effected on such structures as we show it in this section.

3.2.1 Service Description

In this work, the service description is probably one of the most importantfeatures of the architecture along with the matching (that uses it actively).Because of anonymity, calling peers must have a way to describe the servicethey request. There is no way to name either a peer or a service andthis is why descriptions are needed to characterize services without namingthem.

In this context, we need to know what kind of service we want, how theanswering peer satisfies the service, and how well it satisfies it. Informally,services may then be described in three parts answering respectively these threequestions:

Functionality. This is the semantic part of the message, describing the func-tionality of a service by characterizing its kind. An analogy with tra-ditional object programming could be the different names present in amethod signature. Another analogy made with sorting would be the factthat it is a sorting algorithm. In this analogy, because there are so manypossible sorting algorithm services and that they may be specified, we saythat the functionality may be described by a list of labels going from themost general to the most precise. For example, a service doing a BubbleSort has the following functionality: Functionality: "Sort": "BubbleSort".This syntax expresses the fact that we are characterizing a service func-tionality of the kind sort and more precisely: a BubbleSort.

Behaviour. This is the information that will guarantee the compliance of thefunctional check. Basically it contains arguments that propose to theservice to realize its task and the way the service should work (e.g. givesan answer, and if so, does it answer through a particular service or aservice built with the message tag...). An analogy with traditional objectprogramming could be the types of a method and its arguments. Anotheranalogy with sorting would be that it takes in parameter a table of integers,it returns a result and sends back the result using the tag. This behavior isexpressed as follows: Behavior: argument: int a[]: return: int[].

Quality of Service. This is the part of the message that allows to select a ser-vice from a group of corresponding services in order to match most exactlythe quality of service desired with the quality of service proposed. There isno analogy with traditional programming since the choice between meth-ods does not concern the programmers except if the method may be localor in a protection domain. For the sorting example it would eventuallyindicate computational complexity. Similarly to previous parts we expressthe quality of service as follows: QoS: "local": "Complexity": "Nlog(N)".

A service description is made of four fields: one for each aspect - Function-ality, Behaviour, and QoS; and a triple of numeric values [d1,d2,d3], indicating

6

Behavior QoSFunctionality

F1 F2 Fn B1 B2 Bq Q1 Q2 Qr... ... ...

F11 F12 Fn1 Fnm...

F121 F12p...

...

B21 B22 Q11 Q1t...

B221 F22s...

... ...

Q1tv

Figure 5: Description of Services

the minimum matching depth of each aspect.Each aspect is described in two parts: first a preamble, specifying the related

aspect: Functionality, Behavior, or QoS; second, a series of labels.In the case of the Functionality and QoS aspects, the sequence of labels,

serve to specify the functionality and the quality of service respectively, using anincreased level of details. For instance, a service offers the functionality Read,in a FileSystem application. In the case of the Behaviour aspect, two casesoccur: either the service description is a service publication, or it is a servicerequest. In the first case, the labels specify the types of the input parameters,the possible return value, and its type. In the second case, the labels specifytyped values, a possible expected returned answer, and its type. Parameterstypes are only primitive types, such as String, Integers, etc.

The fourth field of a service description is a triple of numeric values indicatingthe required minimum matching depth each aspect must reach, when a servicepublication and a service request are compared. The matching depth of eachaspect is the maximum number of consecutive labels that match.

For instance, following service publication:

(Functionality: "FileSystem": "Read",

Behavior: String: "return": String,

QoS: "local",

[3,2,1])

means that: the minimal functionality is 3, i.e., the service furnishes a readingfile service; the minimal behavior is 2, i.e., the service requires an input param-eter, but does not necessarily return an answer; and the quality of service is 1,i.e., the service prefers a local interaction, but it is not necessary.

Although, in the above example, we use a flat structure to represent eachaspect, the service description supports a tree-like structure enabling alterna-tives [32]. We advocate that using only one word or a flat structure to qualifyone of the parts is not sufficient for describing a service request, particularlywhen faced with unanticipated modifications in the structure of an application.

Each field of this description is defined as a tree (figure 5). Therefore, twobranches going out from a node correspond to an OR between the two subtrees,and a branch corresponds to an AND between the upper level and the subtreeassociated. The tree A in figure 6 is then translated as follows:

QoS ∧ ((Q1 ∧ (Q11 ∨ (Q12 ∧ (Q121 ∧Q1211)))) ∨Q2).

7

Q1 Q2

Q12

Q121

Q11

QoS

Q1

Q11

QoS

Tree ATree B

matches with Awith a depth of 3

Q1

Q12

QoS

Tree Cmatches with A

with a depth of 4

Q1211

Q121

Figure 6: Tree Matching

Even though the functionality describes the service using well-known names,such as ”sort”, it is important to note that it is not necessarily the actual nameof the service that will answer the request. It is simply a way of qualifying thekind of service.

In pseudo-code, the BubbleSort service working on integers and charactersmay be described as:

(Functionality: "Sort": "BubbleSort",

Behavior: argument: (int a[]: return int[],

char a[]: return char[]),

QoS: "local": "Complexity": "Nlog(N)")[2,4,2];

This means that we announce the service that sorts integer or characters andthat it should at least correspond to a sort request. The behavior is then fixed(takes integers and returns integers, or takes characters and returns characters),and should be a local invocation.

Even though labels are well-known, agreed names, such as complexity orlocal, it is important to note that it is not necessarily the actual name of theservice that will answer the request. It is simply a way of qualifying the kind ofservice, used in the service description.

When defining a service description containing alternatives, it is importantto avoid possible mismatches among the diverse branches belonging to differentaspect. Therefore, it is recommended that all branches of the Functionalityaspect be compatible with all branches of the Behaviour and QoS aspect (e.g.,accept the parameters types); it is the same between Behaviour and QoS.

The next subsection shows how to build relations that may allow us tomatch a service description, published in the Service Manager, with a servicedescription used to make requests.

3.2.2 Matching Mechanism

The matching mechanism constitutes the main solution both for dynamic choiceof code and for anonymity of services. The point we want to present is the abilityto match trees and make this matching process as intuitive as possible, giventhe informal explanation we expressed previously for trees.

We say that two trees match at a given depth when the depth is the lengthof the longest branch departing from the root that exists in common in the twotrees.

In this approach we build a matching mechanism between trees that issyntactically-based. To be semantically equivalent and at this point we fore-

8

Q1

Q11

QoS

Tree Dmatches with A

with a depth of 4

Q1

Q12

QoS

Tree Ematches with A

with a depth of 0

0

Q1

Q11

QoS

Tree Fmatches with A

with an infinite depth

0*

?

Q12

QoS

Tree Gmatches with A

with a depth of 4

Q121

Figure 7: Extended Tree Matching

see to use ontologies [16] and automatic provers to ensure that descriptionsmatch to the code itself. As an example, in figure 6, tree B matches with tree A

at depth 3 and tree C matches with tree A at a depth of 4.A problem with this approach is that it is impossible to specify the fact that

we would prefer a shorter branch if the matching occurs at a certain point. It isalso impossible to match a branch until a certain point, and to stop consider thematching after that point. That explains the reason why we define the following5 operators:

• ? means that there is a node and that this node may have any label.

• ∗ means a potentially infinite sequence of nodes.

• ⊥ means that the branch stops at the node where this label is attached:if the branch to match has instead a node at this place, the matching forthe whole branch has a depth of 0.

• ∅ adds 1 to the depth of the branch where it is attached given that itmatches.

• ∅∗ adds ∞ to the depth of the branch where it is attached.

Figure 7 shows examples of such matching.In this way, we can quantify the quality of matching between a requested

service Sr and a proposed service Sp. In this case, we say that Sp matchesthe functionality requested, the behaviour requested or the quality of servicerequested at a depth belonging to N∪ {∞}. The service that is then invoked isthe service having the most important depth matching (by order of preferencefunctionality, behaviour and quality of service). If several services have thesame matching depth, it means that they provide similar services regarding tothe requested service description and one of them is chosen randomly.

In this section, we presented our communication architecture and its princi-ples. This architecture allows us to build applications consisting of disconnectedsoftware peers, and allows us to make the application evolve dynamically.

3.3 Properties

We chose to have a model that is service-based which means that we have alookup mechanism that finds a service able to execute the request if possible.This implies the following points:

9

• It may not be possible to find a service that is effectively able to executethe service invocation.

• It may be possible to find several services able to execute the serviceinvocation.

• It may be possible to find a service and make an invocation and still donot know if the invocation correctly worked if, for example, there is noanswer or if the concerned entity had been removed while executing therequest.

• An entity does not know a priori how the lookup mechanism exactly worksand thus a piece of code have no idea, even if coming with all neededcomponents, that it is able to invoke a particular piece of code.

This means that we have to build components as disconnected as possible aswe would do for different parts of distributed applications. It is at this price thatwe build disconnected components based systems whose parts of code can bereplaced seamlessly. Properties we evoke in the following are meant to be provenin the future for some of them or should be built on top of the architecture wepropose and then proven. At this point they only constitute a guideline to followin the design of concepts and application.

3.3.1 Model Properties

Disconnection This is the basic property we want to have on our system. Inthis model:

There is no direct reference from one entity to another, either callees orcallers.

Being asynchronous, the communication model for components does notlead to synchronization constraints between callers and callees. The only syn-chronization constraint that exists is between a caller and the service managerduring the request process.

These features of the model that we propose then guarantee the disconnec-tion property in a platform implementing it.

Anonymity This is a direct consequence of disconnection as we build it. Anentity invoking a service only knows the service name it wants to invoke butdo not know in which entity the service is defined. The only other knowninformation is the tag received after the request and this allows to continue aconversation with the contacted service but not to know it. Thus, there is ananonymity between callers and callees.

Transparency of Evolution As requests are automatically redirected tonewer versions of the code, parts of the application may be evolved transparentlyto others.

In this section, we presented a communication model that relies on twomajor parts: a communication infrastructure that forces all inter-componentcommunication to be service calls, and a service description mechanism. Thecommunication model is anonymous, asynchronous, and associative:

10

• The service description model allows to have these associative and anony-mous of the communication model.

• The communication infrastructure forces anonymity, and asynchrony.

In next section, we show some of the application domains for this model.

4 Application Domains and Future Work

In this section we give an overview on the possible applicable fields where ourmodel could be used.

4.1 Evolution

Our model has been designed to ease unanticipated dynamic evolution by de-coupling entities dependencies as explain section 2. It is realized through theuse of our communication model along the service descriptions use. This worksquite well mainly because of few reasons:

1. There is no direct reference from one entity to another.

2. There is no direct reference from a piece of code to another.

3. Code failure is considered as a normal case.

This allow us to make arbitrary changes without perturbating the rest ofthe application. It is obvious that a part of the difficulty for handling seamlessevolution of programs will be left to the programmer unless some specific devel-opment interfaces are built. First of all, programmers have to use the inter-entityinfrastructure to make entities communicate. Secondly, programmers have tohandle themselves code failure.

Nevertheless, it addresses the problem of unanticipated dynamic evolutionbecause:

• the programming platform allows to make arbitrary changes anytime with-out stopping the application.

• changes are handled at the platform level.

To help programmers, we provided a certain number of facilities. Servicedescriptions are as lightweight as possible but may be extended at will in orderto have more complex objects to be matched rather than only compound ofprimitive types. The intensively used tags to handle long-term communications,as well as service announcements, allow to dispose of delegation mechanisms thatcould be used to build repositories of service calls.

These points allows us to build a complete framework that may be used tohandle evolution problems and test a large number of ideas. As far as it hasbeen tested, our solution appears to be a realistic one that gives good results aswe are able to address intensively discussed problems like code/data splitting,code/data unions.

Nevertheless it may be argued that our model is not applicable at an ob-ject/class granularity because of the very high cost in terms of computing power

11

for the matching mechanism. As far as we know, this may be absolutely true.Our main contribution in this field probably resides in the fact that we bringthe idea of modifying the object lookup mechanism. In a first approach, we willbuild a prototype that uses our interaction model at a composant granularitywhere accessing object-like structures is not very much fixed.

In future work, however, it would probably be interesting to adapt the modelwe described at a lower level of granularity. This idea implies a strong changein the object binding mechanism (which could be called object lookup mech-anism at this point). Indeed, traditionally, the object lookup is not a matterof discussion in the object-oriented programming languages paradigm: it is areference that allows to control the object. In the more general world of object-orientation, the field that had been interested in having a different object lookupmechanism is the object-oriented databases field. It is our guess that buildingan object lookup mechanism pending to the model we described in this the-sis preliminary report would benefit greatly to object-oriented programming interms of runtime evolution as well as modularity. Nevertheless, it is probablethat, to make it suitable in terms of performance, service descriptions shouldbe reworked and code failure treatments should be automated.

4.2 Web-Services

It is a more and more common trend that web-services constitutes the way ofconsidering software services on the Internet. At this moment web-services relieson the a complex task of calls that comes from server applications to end-userservices.

At this moment, research in this area is essentially concerned in describingservices. Though, they still use some operating mechanisms that hold backthere widespread. One of them is that the whole web-services stack relies on thesystem of yellow pages for effecting the lookup mechanism of service providers.This means that a program must follow the following steps:

1. Make a request on services that match a particular request.

2. Select one services that matches the best the request.

3. Link to this chosen service (using a fixed socket or a direct reference).

4. Use the service.

This approach has a major drawback for fast evolving environments like in-development environments or connectivity changing environments. This meansthat long-term running services are left untouched for a long period of time.They are made evolved only if there is an imperative reason to do so. Moreover,once the choice is made to use a service, it is rare for updates to be made inorder to find a newly arrived and, potentially better, service.

Although our model is too young to handle directly the complete stack ofweb services, our vision on future web services may use our model as a basicbuilding block. Indeed, in our approach, the choice made between services (step2) and the linking (step 3) are integrated in the request process (step 1). Theonly way to link for a longer period than just a method call, is to share a commondescription uniquely. This may simply be done using the tag generated at thebeginning of the communication. This means also that if a service code evolves

12

accordingly to its the description it provides, requests should still be valid andserved. An important point is that our mechanism could be used to delegate toother entities the service tasks. Indeed, an old service may delegate to a newservice the satisfaction of ”linked” requests by passing the tag to them.

Schematically, our approach frees also programmers of steps 2 and 3 andwe think that it is the way web services should behave in order to make themattractive to programmers.

4.3 Peer-to-Peer Programming and ad-hoc Networks Pro-gramming

Peer-to-Peer [30, 40] programming and network programming need to have flexi-ble ways to invoke code remotely. As an example in ad-hoc networks where peersmay only be in direct contacts for few seconds, it is not possible to considerthat traditional remote code invocation mechanisms will work. Middlewareapproaches are made of two different families of systems: remote invocationmechanisms (like CORBA, DCOM and RMI) and information storing throughrepositories (Linda-like systems [4]).

The first family usually considers components that allow programs to in-voke remotely methods on components that may be considered statically boundduring the discovery and use states. This family of systems provides also acomplete infrastructure that allows programmers to find components in orderto build some sort of reference to be able to invoke methods. P2P networksare very dynamic and a particularity is that peers may leave and come backat any time with different accessibility and computing power capabilities. Suchdynamic behavior is not considered as a normal feature and then cannot beadapted to P2P networks.

The second family of middleware approaches considers that informationshould be exchanged asynchronously through a repository. The problem withsuch an approach applied to P2P networks is that huge amount of data may beexchanged and any repository down-time may provoke major problems due tosuch message centralizing.

Our point of view is that the invocation process should pass informationneeded to process the query as soon as possible to the service provider and beresistant to disconnection. This means that calls have to be asynchronous andshould adapt to unanticipated disconnection. Following this lead, it is probablethat an approach like ours would benefit the field of peer-to-peer programmingand ad-hoc networks as we explained in previous article [32]. Indeed, in thiscase of figure, entering an ad-hoc network may be assimilated to introducingnew entities into the network service manager. new introduction of entities isthen seamless and my add functionalities/services to the ”global” set of availableservices.

4.4 Grid Computing

Grid computing [23, 2] is the subfield of distributed systems that studies thepossibilities to make simultaneous calculi on a potentially large number of in-dependent systems in order to obtain a global result. This approach has beendemocratized in recent years by the SETI [1] project that aimed at using unused

13

computing power from computers connected to the Internet that went to screensaving mode.

In such an environment, the most important factors are that failure is anormal case and that dynamicity of communicating computing units (peers,entities) is a pre-requisite. These constitute a part of the assumptions we madeon the behavior of the entities we described in section2. Our approach couldthen be used as an underlying middleware for grid networks.

Indeed, our model lets users and programmers build grid networks unseen atthis moment. Our model allows to share services across a large number of partic-ipants. The called service providers are the ones that are: reachable, providingservices that match the requested service. In this case what we could build is aglobal Internet computer which means that we could have services called fromone node on the network to another without noticing it. The main conditionfor building such a system would be to decentralized the service manager asthis constitutes the major backbone of such a system in terms of computingpower (during the matching process) needed and data storage (namely servicesdescriptions).

5 Related Work

In this section we present an sparse overview of the related work on evolution.In a first part, we describe some works on dynamic loading which constitutesan important building block for dynamic evolution of code. In a second part,we describe actual work on services which is at the heart of our work. In a thirdpart, we give an overview of few works on dynamic evolution platforms. In afourth part, we give a brief overview of works made on components technologiesthat we target to be the preferred level of granularity of our model and we finallyconclude with a description of works done on evolution of network topologieswhich constitute a target application domain of our work.

5.1 On Dynamic Loading.

As C++ [13] is a compiled language, it has been a real challenge to add dynam-ically code and to use it as it is difficult to make a call in a compiled languagewithout a specified reflexive module to handle the evolution behavior. In [37],Stroustrup writes: “Early experiments integrating C++ and dynamic linkingwere promising so I had expected dynamic linking to be common years ago.”(p. 206). As we will see in this section only few advances addressed the prob-lem for C++ but some features inspired the design of other languages (likeJava [15, 25, 26]) that accords to Stroustrup point of view : “I have reluctantlycome to accept that some system-related issues would have been better handledwithin C++”(p. 206).

In [11], Dorward, Sethi and Shopiro propose a system to add dynamicallycode to a running C++ program. Their system relies on lately linking codeof derived classes from already present classes in the program imposing to theclass newly loaded to have the same signature as its parent. They concentrateon keeping type-safety and have a portable system. The programmer thereuses a preprocessor to introduce the code to manage these possibilities and thuskeep a portable C++ code. Evolution is not only in the dynamic Loading of

14

C++ classes but also in the fact that programmers may “promote” objects toa subclass (transform an instance into an instance of a subclass) as it is “asafe direction” regarding to type safety although appearance of new potentiallyuninitialized variables may not be taken into account.

In [33], Palay describes ∆C++ which consists in a special compiler for un-modified C++ programs that allows compiled programs to load dynamicallylibraries that evolved without recompiling them. The supported (“compatible”)modifications are four: member-extension (adding new methods and fields to aclass), class-extension (adding a new base class to a class), member-promotion(moving a method or a field to a super-class) and override-changing (adding aoverriding method in a subclass). In fact, in general, ∆C++ allows program-mers to modify dynamic libraries if methods have the same signature and if themodification is type-safe with few restrictions. Technically, authors use a linkerthat is invoked at startup and then are able to handle “compatible” changesin the different libraries at startup. It is not possible to modify classes duringruntime and thus evolution is limited to extending libraries between programstartup and providing a mechanism that does not imply recompiling if changesare are made to dynamically linked libraries.

In [14], Goldstein and Sloane describe a way to support dynamically reload-able classes in C++ to address the problem of effective evolution in sharedlibraries. According to the authors, maintaining compatibility between versionsof a library is problematic and distributed objects technologies complicate li-brary implementations showing the need to have multiple versions of the sameclass linked into a same program. For achieving this, authors manipulate thelinkage mechanisms and this allows to call different classes with the same callsdepending on the versions of the dynamic libraries they use at this time. Onlyclasses that may evolve are written as dynamically relinkable. This work intendsto address transparently problems raised by the fact that objects of a newer ver-sion may be passed to a program that would like to use it. Thus, it chargesthe dynamic library defining it regardless the class has already be defined. Thesystem they propose needs a particular compiler and thus is highly platformdependent. As passing new objects to old versions do not pose many problemsdue to the algorithm building data structures (principally they append data andforbid to change order of previously defined methods and fields), passing olderobjects to newer versions of the code is likely not to work.

In [20], Hamilton and radia describe the Spring distributed environment inwhich they consider the problems linked to the fact that versions of the interfaceswith the environment may evolve. In the distributed framework they consider, itis impossible to update the whole system at once, different versions of interfacesmay then coexist in the system and may be linked to programs when needed.Authors separate the versions changes in major and minor revisions. If changesmade to an interface implies that this interface is now unusable by old clients,it is a major revision, otherwise it is a minor revision. Interfaces are describedusing the OMG’s IDL[9] and support multiple inheritance. The different ver-sions of an interface are classes that represents objects on which it is possibleto apply diverse methods. Each interface has a base type that corresponds tojust defining the name of the class, major revisions are subclasses of this basetype and minor revisions are successive subclasses of major revisions. Doingso means that compatibility of newer minor revisions is ensured because it ex-tends previous ones and thus it is not necessary to recompile client programs.

15

When new major revisions arrive in the system, both versions coexist as longas needed and client programs should not be stopped to be recompiled for theversion and have the time to be recompiled and corrected. The main problemswith this approach are the following : administrator has to be strongly involvedwith users to determine when have may effectively remove a major revision andits minor revisions ; another problem is that if an interface changes and if thatinterface is used in another interface, it will be the old version that is used andthere is no possibility but to recompile and adapt new code to the new inter-face. Another need that arose in this system was to use some interfaces thatmay possess a disjoint set of properties from different semantic fields but also touse some abstract interfaces as types to use by programs exactly the way Java[15] Interfaces. This work is only an extra infrastructure for realizing transpar-ent evolution and multi-versionning of code but gives a primary infrastructureto think of: transparent evolution is here done using subclassing to make smallupdates, major updates need reengeneering of the old code and thus, it is notsuitable to make major updates.

The actual C (and then C++) dynamic linking library for Unix and Linux isdlopen [35] that allows programmers to load dynamic libraries and to use themthrough manipulations primitives and to apply them just knowing the symbolsthey are referenced by. This system let users to load and unload shared librariesand thus to make them evolve during execution, but programmers need to havea strong knowledge of these possibilities and of the libraries involved in thisprocess as the primitives do not allow to get the complete list of the primitivesloaded from the library. Another problem that may arise when willing to usea library that evolve is the fact that it is not possible to force a library to bereloaded as the dynamic package maintains a counter on the library and unloadtit when it drops to 0 (and then it may be reread from the disk).

In [22], authors describe a way to provide dynamic loading of C++ classes.Mainly mechanisms used are similar to those proposed in [11] but possibilitiesgiven differ in two ways: they allow replacement of previously loaded classesand they allow multiple versions of the same class to coexist in the program.What is effectively is building an indirection level between client classes and thedynamic classes using a template class that allows the creation of objects of theclass desired. An object is then accessible directly through its handle and maybe used as if it had been defined inside the program. The first limitation tothis approach is that dynamic libraries may be only loaded once by name andthus it means that a new version needs to have a new name to be effectivelyloaded. Another limitation is that an inheritance tree needs to be present inits whole in the dynamic library to be taken into account due to the templateclass encapsulating the dynamic version of the class. The last limitation that isnot even identified in [22] is in security of functioning: as there may be manydifferent versions of the same class in the program, it is also possible to passreferences from an old version to the new one. This means that it requiresprogrammers to program knowing that their classes will be versionned and evenif an instance may know that it does not belong to the newest version, methodsshould not use the the particularities of the way the program stocks its instancesin the case an instance of a different version of the class is passed by referenceto code from a newer version of the class. In few words, the program should bewell programmed regarding to object standards, which does not constitute a socommon case in C++ programs.

16

In Java 2 [15] the dynamic loading is integrated in the language and consistsin having instances of the class ClassLoader that load classes. This is due tothe fact that at an early stage of development of the language, applets were aprimary concern for the language builders and thus several sources should havebeen to take into account when trying to get a class. In [25], Liang and Brachadescribe the dynamic class loading principles for Java 2. In Java 2, differentclasses may subclass ClassLoader and in particular SecureClassLoader from theAPI or NetworkClassLoader (example presented in the API). A ClassLoader

instance defines a name space where only one class may have a given name.Loaders are hierarchically organized and it is possible to delegate charging a classto another ClassLoader. Instanciating explicitely a class in a ClassLoader reserves the use of the name of the class and let no other class be referenced usingthis name in this ClassLoader. A possibility to have multiple versions of a classusable in a program is to delegate the loading of the different versions in differentclass loaders and, with the reflexive core package of Java 2, to instantiate themand apply methods to the defined classes (see [25] for an example). This is, atthis point, the only way to build programs that evolve in Java 2 and althoughevolution seems to be one of the goals of the class loading mechanism presentedin [25], it still lacks simplicity for programmers to use it as it needs to havean infrastructure built for it for effecting state transfer of objects and for usingmultiple versions of classes. Another problem when using simple structures asproposed in [25] is that they need to have a good knowledge of the newly loadedclass which means that it is only possible to make minor updates and correctingthis issue adds a great complexity to the program and needs to be previouslybuilt.

As far as we know, there is no work on runtime evolution that address all theobject problems. In particular, works often want to keep type-safety at any costin order to be sure that the platform will not fail and we consider that this isan error because many problems may also arise because considered applicationsmay not be type-safe during a time and come back to type-safety later once theproblem that forced administrator to break type-safety is solved.

5.2 On Dynamic Services, Web Services, and Service De-scription Languages.

Few service description languages have been described. As an exampel WSDL[7] is a norm for describing web services. The description is constituted by adocument that binds some parts to other documents (like protocols description).The goal of WSDL is mainly to allow programmers to describe services. Oncefound, active components have to decide if the described service corresponds toa valid possibility or not. UDDI [39] allows to fill the gap between describingand finding a service. It constitutes a phone-book used to find services. Ser-vices described using WSDL can be published and retrieved through UDDI [8].Adding WSCL to the whole system [3] allows to describe future interactions.This means that services match or do not match: there is no way to quantify thequality of matching. It is also not anonymous and components have referenceson each other when the server and the client have been defined.

17

5.3 Runtime Program Evolution Platforms.

In the past few years, several works have been realized in order to provideinfrastructures (i.e., runtime platforms) to programmers and system adminis-trators, allowing runtime evolution of applications. In compiled environmentsthe works of Gupta [18, 19] study the time points at which on-line software ver-sion change may occur depending on the threads execution. This work, however,cannot be applied to object programming [17] because of the many object inter-dependencies in such languages. Indeed, this model relies on state mapping,which is difficult to implement for dynamic object creation.

Hicks [21] proposes an infrastructure for allowing type-safe evolution of ap-plications programmed in a typed C by adding an indirection level for eachfunction call. It does not address object-orientation approach, and its solutionis not easily applicable to objects.

In the object-oriented world, most works are concerned: by safely trans-ferring state of objects from one class to another and vice-versa [36, 12]; bythe typed safe replacement of methods at runtime [10]; or possibly both [27].Changes imply that new classes are either sister classes, or sub-classes of oldclasses, restraining a lot the evolution possibilities which appears to be veryrestrictive.

5.4 On Components Platforms Evolution.

In component-oriented software development, approaches often consider thatthe key feature, to make an application evolve, is to be able to change the inter-component connectors and to replace components at runtime [31], possibly usingreflexive mechanisms [34].

In industrial approaches like Enterprise JavaBeans [38], CORBA [29], ser-vices are referenced through a naming service (namely JNDI [24] for JavaBeansor the naming and trading services [28] for CORBA) that have mainly the mainfunctionality: a component willing to use another unknown one must make aresearch through these services and, once found, it has to decide if it is the rightone given some specific informations and then use it in a potentially long-termcommunication process. This has several implications: (1) this means that aprogrammer should code the part that decides to use one service or not, (2) ifthe communication process is long enough, it should be stopped when updated.

6 Expected Contributions

This thesis is concerned with unanticipated evolution of applications whetherthey may be distributed or not. The intention is to have a framework thatseamless evolution of applications. The main expected contributions are thefollowing:

• A framework for making applications evolve at runtime in an unantici-pated way.

• A communication model between components that retains the followingproperties: it is disconnected, anonymous and uses associative naming.

18

• Three implementations of this model: a local one, a centralized distributedone, and a peer-to-peer one.

• Experiences reports on these implementations.

7 Conclusion

In this thesis preliminary report we advocate that connection between softwareentities is a major drawback for building completely evolvable applications. Weshow that disconnection between software entities is achievable with a commu-nication infrastructure based on three main concepts: associative naming, latebinding of code, and asynchrony. This architecture proposes an all-service ap-proach using an intermediary description of services in a way that allows toquantify which service is better adapted to the invocation request. Applicationsbuilt on top of the architecture we describe are then evolving by the simplepresence of new software entities in the application itself.

Acknowledgements

We would like to thank the Object System Group members and particularlyGiovana Di Marzo Serugendo for so many motivating discussions.

References

[1] http://setiathome.ssl.berkeley.edu/.

[2] K. Aberer. P-Grid: A self-organizing access structure for P2P informationsystems. Lecture Notes in Computer Science, 2172:179–??, 2001.

[3] D. Beringer, H. Kuno, and M. Lemon. Using WSCL in a UDDI registry1.02. http://www.uddi.org/pubs/wsclBPforUDDI 5 16 011.doc, may 2001.

[4] N. Carriero and D. Gelernter. Applications experience with Linda. ACMSympos. on Parallel Programming, July 1985.

[5] N. Carriero and D. Gelernter. Linda and message passing: What havewe Learned? Technical Report TR-984, Yale University Department ofComputer Science, Sept. 93.

[6] N. Carriero, D. Gelernter, and L. Zuck. Bauhaus linda. In P. Ciancarini,O. Nierstrasz, and A. Yonezawa, editors, Object-Based Models and Lan-guages for Concurrent Systems, LNCS 924, pages 66–76. Springer-Verlag,1995.

[7] E. Christensen, F. Curbera, G. Meredith, and S. Weer-awarana. Web services description language (WSDL) 1.1.http://www.w3.org/TR/2001/NOTE-wsdl-20010315, march 2001.

[8] F. Curbera, D. Ehnebuske, and D. Rogers. Using WSDL in aUDDI registry 1.05. UDDI Working Draft Best Practices Document,http://www.uddi.org/pubs/wsdlbestpractices-V1.05-Open-20010625.pdf,June 2001.

19

[9] Digital Equipment Corporation, Hewlett-Packard Company, HyperDeskCorporation, NCR Coporation, Object Design, Inc., and SunSoft, Inc. TheCommon Object Request Broker: Architecture and specification. TechnicalReport 91-12-1, Object Management Group, Framingham MA (USA), Dec.1991.

[10] M. Dmitriev. Towards flexible and safe technology for runtime evolution ofjava language applications. In OOPSLA Workshop on Engineering ComplexObject-Oriented Systems for Evolution., 2001.

[11] S. M. Dorward, R. Sethi, and J. E. Shopiro. Adding new code to a runningC++ program. In USENIX Association, editor, USENIX C++ confer-ence proceedings: C++ Conference, San Francisco, California, April 9–11,1990, pages 279–292, Berkeley, CA, USA, Spring 1990. USENIX.

[12] S. Drossopoulou, F. Damiani, M. Dezani-Ciancaglini, and P. Giannini.Fickle : Dynamic object re-classification. In Proceedings of ECOOP’01,pages 130–149, 2001.

[13] M. A. Ellis and B. Stroustrup. The Annotated C++ Reference Manual.Addison-Wesley, Reading, Massachusetts, U.S.A., reprinted with correc-tions edition, Dec. 1990.

[14] T. Goldstein and A. Sloane. The object binary interface: C++ objects forevolvable shared class libraries. In USENIX Association, editor, Proceedingsof the 1994 USENIX C++ Conference: April 11–14, 1994, Cambridge,MA, pages 1–19, Berkeley, CA, USA, Apr. 1994. USENIX.

[15] J. Gosling, B. Joy, and G. L. Steele. The (Java) Language Specification.Addison-Wesley, Reading, USA, 1996.

[16] T. R. Gruber. Toward principles for the design of ontologies used forknowledge sharing. International Journal of Human-Computer Studies,43(5/6):907–928, 1995.

[17] D. Gupta. On-line Software Version Change. PhD thesis, Department ofComputer Science and Engineering, Indian Institute of Technology, Kan-pur, November., 1994.

[18] D. Gupta and P. Jalote. On-line software version change using state transferbetween processes. Software/Practice and Experience, 23(9):949–964, Sept.1993.

[19] D. Gupta, P. Jalote, and G. Barua. A formal framework for on-line softwareversion change. IEEE Transactions on Software Engineering, 22(2):120–131, Feb. 1996.

[20] G. Hamilton and S. Radia. Using interface inheritance to address problemsin system software evolution. ACM SIGPLAN Notices, 29(8):119–128, Aug.1994.

[21] M. Hicks, J. Moore, and S. Nettles. Dynamic software updating. ACMSIGPLAN Notices, 36(5):13–23, May 2001.

20

[22] G. Hjalmtysson and R. Gray. Dynamic C++ classes. In Proceedings of theUSENIX 1998 Annual Technical Conference, pages 65–76, Berkeley, USA,June 15–19 1998. USENIX Association.

[23] W. Hoschek. Peer-to-peer grid databases for web service discovery. Con-currency: Practice and Experience, 00:1–7, 2002.

[24] R. Lee and S. Seligman. JNDI API tutorial and reference: buildingdirectory-enabled Java applications. Java series. Addison-Wesley, Reading,MA, USA, 2000.

[25] S. Liang and G. Bracha. Dynamic Class Loading in the JavaTM VirtualMachine. In Proceedings of the 13th Conference on Object-Oriented Pro-gramming, Systems, Languages, and Applications (OOPSLA-98), volume33, 10 of ACM SIGPLAN Notices, pages 36–44, New York, Oct. 18–221998. ACM Press.

[26] T. Lindholm and F. Yellin. The Java Virtual Machine Specification. TheJava Series. Addison Wesley Longman, Inc., second edition, Apr. 1999.

[27] S. Malabarba, R. Pandey, J. Gragg, E. Barr, and J. F. Barnes. RuntimeSupport for Type-Safe Dynamic Java Classes. In Proceedings of ECOOP’00,pages 337–361, 2000.

[28] Object Management Group. Naming service specification–revised edition.http://www.omg.org/cgi-bin/doc?formal/01-02-65, February 2001.

[29] OMG. The comon object request broker: Architecture and specification.Technical Report PTC/96-03-04, Object Management Group, 1996. Ver-sion 2.0.

[30] R. T. On. Project JXTA: An open, innovative collaboration.http://www.jxta.org/project/www/docs/OpenInnovative.pdf, 2001.

[31] P. Oreizy, N. Medvidovic, and R. N. Taylor. Architecture-based runtimesoftware evolution. In Proceedings of the 1998 International Conferenceon Software Engineering, pages 177–186. IEEE Computer Society Press /ACM Press, 1998.

[32] M. Oriol. Peer services: from description to invocation. In Proceed-ings of the International Workshop on Agents and Peer-to-Peer Computing(AP2PC 2002), volume 2530 of LNCS, pages 21–32. Springer-Verlag Hei-delberg, 2003.

[33] A. J. Palay. C++ in a changing environment. In USENIX Associa-tion, editor, Proceedings: USENIX C++ Technical Conference, August10–13, 1992, Portland, OR, pages 195–206, Berkeley, CA, USA, Aug. 1992.USENIX.

[34] B. Redmond and V. Cahill. Supporting unanticipated dynamic adaptationof application behaviour. In B. Magnusson, editor, Proceedings ECOOP’02- Object-Oriented Programming, volume 2374 of LNCS, pages 205–230,Malaga, Spain, July 2002. Springer-Verlag.

21

[35] A. Richter. Dlopen(3). Linux Programmer’s Manual, December 1995.

[36] M. Serrano. Wide classes. In R. Guerraoui, editor, ECOOP ’99 — Object-Oriented Programming 13th European Conference, Lisbon Portugal, vol-ume 1628 of Lecture Notes in Computer Science, pages 391–415. Springer-Verlag, New York, NY, June 1999.

[37] B. Stroustrup. The Design and Evolution of C++. Addison-Wesley, Read-ing, MA, USA, 1994.

[38] Sun Microsystems. Java Beans(TM), July 1997. Graham Hamilton (ed.).Version 1.0.1.

[39] uddi.org. UDDI technical white paper, September 2000.

[40] S. Waterhouse. JXTA search: Distributed search for distributed networks.http://spec.jxta.org/v1.0/docbook/JXTAProtocols.html, 2001.

22