Run-time adaptability of synchronization policies in concurrent object

0 downloads 0 Views 100KB Size Report
object-oriented languages do not provide enough support for the development of true ... mainly thought for a clear and consistent separation of the synchronization aspect from the ... nature of the resulting entity after the composition process?
Run-time adaptability of synchronization policies in concurrent objectoriented languages Fernando Sánchez, Juan Hernández, Juan Manuel Murillo, Enrique Pedraza Computer Science Department University of Extremadura Campus Universitario s/n 10.071 – Cáceres, Spain {fernando, juanher, juanmamu}@unex.es

ABSTRACT Adaptability has become one of the most important research areas in concurrent object-oriented systems in recent years. It tries to cope with system evolution by adding/replacing components without affecting other components of the same application. Nevertheless, at the present time, concurrent object-oriented languages do not provide enough support for the development of true adaptable software because either i) the different aspects that appear in these systems, synchronization and behavior, are mixed in the same component or, ii) if they are properly separated in different components, once these components are woven the resulting executable piece of software is too rigid to be adapted or reconfigured at run-time. In this paper, we present the Disguises Model, a model mainly thought for a clear and consistent separation of the synchronization aspect from the behavioral aspect. Whereas the model allows behavioral code to be written in a standard language like Java, it provides a different language for the specification of synchronization components and a third language for the specification of the composition rules between the synchronization and behavioral aspects. This composition language allows synchronization policies to be added, replaced or reconfigured at run-time, which is the main contribution of the proposed model. The techniques here presented have been satisfactorily integrated in Java.

1 Introduction Frequently, large and complex systems have to cope with a continuous change of requirements during their life. Consequently, these systems tend to grow and change after they have been developed. In order to adapt to changing requirements, the demand has risen for adaptable software. This research area has been recently named the adaptability [Tek96] of software, which can be defined as the ability to deal with new/changing requirements with minimum effort. In this definition, the meaning of effort must be understood as the number of modules that are created or modified when changes in the requirements are necessary. In practice, it is possible to obtain an adaptable object-oriented application if its software architecture allows its components to be removed, replaced or reconfigured without perturbing other parts of the application [Nie95]. Nevertheless, experience has demonstrated that the object-oriented model does not provide effective adaptability. It has been detected various interferences when several aspects must be introduced or modified in order to cope with the changing requirements. The introduction or modification of new requirements affecting a single aspect may involve the modification of the other aspects, thus expanding the number of modules that must be changed or modified. And this situation is clearly against the definition of adaptability given before. Recent works [Hur95, Aks96, Kic97] have demonstrated that the problem in the conventional object model is that the different concerns or aspects involved in an application are mixed. Since then, the separation of concerns principle has been recognized as an effective approach for increasing adaptability. In the research area we are moving around, COOLs, the two aspects to be considered are synchronization and basic object behavior. In the last few years there have been several proposals trying to separate the synchronization aspect from the basic behavior of the object [McH94, Ber94, Hol97, Lop97, Rei97]. A number of proposals deserve special mention which under the name of aspect-oriented programming (AOP) try to express each of a system’s aspects in a separate and natural form that will be automatically woven to form an executable code using automatic tools [Kic97]. All of these proposals have obtained a high degree of success, and they have proposed different programming techniques to separate both concerns (see related works section). But once these concerns are composed, what is the nature of the resulting entity after the composition process? Is it flexible enough to allow the synchronization aspect to be adapted not only at compile time but also at run-time? That is, is it flexible enough for adding, replacing or reconfiguring synchronization components at run-time? To our knowledge, the answer is no. Our contention is that this feature is very important in critical control systems where, due to unexpected environment changes, urgent and

1

not preestablished decisions must be taken at run-time. From security and economic point of views, it is not admissible to stop the application, adapt it to the new environment and re-run it. In this paper, we present the Disguises Model, a model mainly thought for a clear and consistent separation of the synchronization aspect from the behavioral aspect. Whereas the model allows behavioral code to be written in a standard language like Java, it provides a different language for the specification of synchronization components and a third language for the specification of the composition rules between the synchronization and behavioral aspects. This composition language allows synchronization policies to be added, replaced or reconfigured at run-time. That is what we call run-time adaptability, which is the main contribution of the proposed model. Run-time adaptability is provided even if the object has not been previously designed for such changes or the run-time added synchronization policies have not been previously defined. Although the techniques here presented have been satisfactorily integrated in Java, they can be easily applied to other languages. The rest of the paper is organized as follows. Section 2 fixes the discussion universe we are moving around and presents the main requirements for achieving adaptability in COOLs. In Section 3 the Disguises Model is presented. It will be shown how it separates and composes the different aspects with the aid of several examples. In section 4 related works are discussed and, finally, section 5 summarizes the paper with conclusions and future work.

2. Adaptability in COOLs The point of view we have about the desired adaptable concurrent object-oriented model is depicted in figure 1. Each synchronization component should ideally describe exactly one and well defined synchronization policy, and it may itself be a composition of other synchronization components. The basic behavior interface specifies the operations provided to the exterior. This interface may be implemented in various ways, and both the interface and the implementation are components themselves. The dotted line around the behavior and the synchronization policy 1 indicates the boundary of the resulting composed object. Such an object should be understood as an entity ready to be executed whose design should allow the other synchronization policies to be applied at run-time.

Synchronization 1

other implementations

Basic behavior interface

different synchroniza tion policies

they can be applied to other component beh aviors

Synchronization 2

composed to form other synchronization policies behavior im plem entation

Synchronization 3

Com posed Synchronization 4

Figure 1. Graphical view of adaptability in COOLs The following benefits and properties about the desired object model can be deduced from the figure: •

the set of components describing the basic behavior of the object may be reused in environments other than concurrent.



synchronization components are not attached to any specific behavior component. Conversely, they are independent from each other. Consequently, synchronization components may be applied to any other components with different behavior but the same synchronization rules.



As there is an independence between aspects at the implementation level, it is possible to specify the synchronization aspect in a specific language more suitable for describing synchronization than general purpose languages.

2



In the same way as the previous point, the composition mechanism for composing both concerns, synchronization and behavior, may be different from those used for composing individual concerns. This allows us to use a more adequate composition mechanism for run-time adaptability than inheritance or delegation.

2.1 Requirements for adaptability in COOLs From the previous point, a set of minimum and necessary requirements to be imposed in COOLs in order to address the demanded software adaptability can be easily followed. i)

modularity of synchronization constraints: this means that the synchronization aspect must be clearly/cleanly separated from the behavioral aspect. Moreover, SC must not refer to implementation details. Otherwise, substitutability of software is lost [San96, Ber96].

ii)

composability of synchronization constraints: this means the ability that a concurrent object-oriented model provides for reusing and extending the SC in an effective way. SC must be able to be freely combined to form other constraints [San96, Ber96]

iii)

expressiveness of synchronization constraints: this means that SC must be able to refer to the required information for a good expressive power in synchronization mechanisms [Blo79].

iv)

composition of SC and behavior: this means the ability that a COOL provides to freely combine or compose both components: synchronization and basic behavior. This composition mechanism must be able to be done at compile time as well as run-time. At least the following three features should be provided for the demanded run-time adaptation: • Addition of a new synchronization policy and its integration with the current applied policies. • Replacement of a currently applied synchronization policy with another one or none.

• Modification of a currently applied synchronization policy in order to restrict or extend its constraints. Whereas the requirements i), ii) and iv) are for adaptability, the third one is for expressive power in synchronization constraints. We claim that these requirements should be present in any COOL designed for largescale concurrent software development. Currently, different languages or proposals fulfil the three first requirements with a certain degree of success [McH94, Ber94, Hol97, Rei97, Lop97] but, to our knowledge, none of them has addressed the ability to change the synchronization aspect during the execution of the application. The reason for this is that once these separated components are woven, the resulting executable piece of software is too rigid to be adapted or reconfigured at run-time. What it means is that the fourth requirement has not been taken into account. In the Disguises Model presented below, the synchronization policies are allowed to be added, replaced or modified at run-time without affecting other parts of the object or application. The behavior component has no need to be coded taking into account what synchronization policies can be added in the future and the policies themselves can be adapted while the application is being executed.

3 The Disguises Model In [Lop97, San97] it is shown how difficult is to achieve an effective adaptability of SC in a popular concurrent object-oriented language like Java due to it not addressing the above established requirements for adaptability in COOLs. In [San97] the well known bounded buffer example with put and get methods to store and retrieve elements is used to show interferences between aspects when inheriting code: not only we have to redefine behavioral methods only to take into account synchronization purposes, but also we are not able to reuse SC previously defined to form new ones. Both problems arises because the modularity requirement i) and the composability requirement ii) identified above are not addressed. For more details the reader is referred to [San97]. In [Lea96] several hints for solving these problems in Java are proposed but, unfortunately, Java provides no means by which to specify synchronization policies independently. So, in the bounded-buffer example, there is nothing to do if the whole synchronization policy is needed to be replaced by another one and, of course, nothing to say if it is to be done at run-time. As a result, requirement iv) is not fulfilled. Next, the proposed model will be presented at two stages. On the one hand, the separation of the synchronization aspect in different components will be outlined in section 3.1 by introducing a particular language for the specification of synchronization and, on the other hand, the composition mechanism for weaving both components will be described in section 3.2.

3

3.1 Separating aspects: the synchronization language. The first requirement for adaptability in COOLs imposes a clear separation of SC from object behavior. This is the reason why the Disguises Model separates both aspects in different components. In order to specify the synchronization aspect, the model provides a specific language in the sense of aspect-oriented programming [Kic97]. The behavioral component becomes a normal object in Java but without specifying anything about synchronization. At a later stage, the behavior and synchronization components will be composed with a composition mechanism different from inheritance which will allow synchronization components to be dynamically changed at run-time. This mechanism is shown later in section 3.2. The main concepts of the proposed synchronization language rely on abstract states. The abstract states of an object are those exceptional states under which certain methods cannot be executed. They represent some relevant aspects of the real state of execution of an object but at a level of abstraction that makes independent the synchronization component from the behavioral component. Although abstract states do not refer to implementation details, they are thought to be able to reference the required information for a good expressive power in synchronization mechanisms [Blo77] coping thus with the expressiveness requirement iii) [San97]. For the bounded buffer example the abstract states would be: abstract_states: FULL: {δ.length()==δ.maximum()} EMPTY: {δ.length()==0 }

where the letter ‘δ’ denotes the object to be synchronized and length and maximum are properties of the δ object. In addition to abstract states, the proposed model provides preconditions which establish the SC for methods execution. These conditions are boolean expressions defined in terms of abstract states so they do not refer to particular implementations. For the example being considered: preconditions: put: !FULL; get: !EMPTY;

In practice, abstract states depend either on instance variables or conditions that cannot be distinguished with the set of instance variables (i.e. history-only sensitiveness of states). Thus, it is possible to identify two kind of abstract states: those involving instance variables and those not involving them. For the former a functional access is provided and for the latter variables only for synchronization purposes, synchronization variables, are granted. This variables will be managed by preactions and postactions. This solution for implementing abstract states ensures the separation of concerns and the encapsulation for the behavioral component. message queue external requests

PreConditions synch. variables functional access

abstract states

PreActions

instance variables and methods implementation. real invocation of method

basic behavior component

PostActions

synchronization component

Figure 2 Graphical representation of the model The outline of the framework is illustrated in figure 2. This mechanism provide a generic object-oriented synchronization model for achieving adaptability in COOLs. It makes up a layer that provides a complete abstract interface which isolates the synchronization component from the implementation details. This means modularity of 4

SC, that is, requirement i). All these features can be reused, extended or redefined, in synchronization subclasses. This allows the model to cope with composability of SC, that is, requirement ii). This two statements are exemplified below. Figure 3 illustrates the behavior component of the bounded buffer without specifying anything about synchronization. It defines public methods and a set of properties that characterize the buffer: its length and the maximum number of elements that it can contain. In figure 4, two possible synchronization specifications for the bounded buffer are shown. class B_buff {

for (i=0;i

Suggest Documents