a framework for aspect–oriented multiparty coordination
Abstract
Separation of concerns has been presented as a promising tool to tackle the design of complex systems in which cross–cutting properties that do no fit into the scope of a class must be satisfied. In this paper, we show that interaction amongst a number of objects can also be described separately from functionality by means of the CAL language, and present a framework that provides the needed infrastructure. It is innovative because it supports open multiparty interactions.
Full text
A FRAMEWORK FOR ASPECT–ORIENTED MULTIPARTY COORDINATION José A. Pérez, Rafael Corchuelo, David Ruiz and Miguel Toro Dep. de Lenguajes y Sistemas Informáticos Universidad de Sevilla, Spain {jperez, corchu, druiz,mtoro}@ lsi.us.es Abstract Separation of concerns has been presented as a promising tool to tackle the design of complex systems in which cross–cutting properties that do no fit into the scope of a class must be satisfied. In this paper, we show that interaction amongst a number of objects can also be described separately from functionality by means of the CAL language, and present a framework that provides the needed infrastructure. It is innovative because it supports open multiparty interactions. Keywords: Multiparty interactions, coordination algorithms, aspect–oriented languages . 1. INTRODUCTION Isolating coordination from computation has been paid much attention because it benefits from enhancing modularity, understandability or reusability, but also from being the best way to solve difficult problems such as the wellknown inheritance anomaly. Unfortunately, aspect–oriented languages such as COOL, RIDL [Lopes, 1998], ASPECTJ [Lopes and Kiczales, 1998] or AML [Irwin et al., 1997] do not succeed in isolating computation from interaction with other objects in a system. COOL, for instance, allows us to define synchronisation policies, but interactions with other objects are embedded into the functional code. Therefore, objects are dependent on the interaction model used to coordinate them. This model relies on classical point–to–point communication primitives and, thus, emphasises a number of objects exchanging binary messages and requires a specific protocol for coordinating them that is usually scattered amongst functionality. Besides point–to–point communication, many other interaction models have been proposed in the literature [Papadopoulos and Arbab, 1998], and many researchers have centred their effort on the novel multiparty interaction model, which has been introduced in many languages [Joung and Smolka, 1996]. It has also attracted the attention of the designers of the well–known Catalysis method
[D’Souza and Wills, 1999]. Catalysis has been used by Fortune 500 companies in fields including finance, telecommunication, insurance, manufacturing, embedded systems, process control, flight simulation, travel and transportation, or systems management, thus proving the adequacy of this novel interaction model in so different application domains. Unfortunately, the languages that incorporate this powerful construct are usually intended to describe both functionality and coordination, thus producing components that are highly dependent on the environment in which they are intended to be integrated. We think that aspect–orientation is the key to describe coordinated behaviour separately from computation so that functional code can be kept clean. In this paper, we present a framework for implementing multiparty coordination as an aspect. It has been used to implement the CAL language [Corchuelo et al., 2000], which is, to the best of our knowledge, the first multiparty coordination–aspect language to appear in the literature. The rest is organised as follows: section 2 sketches the interaction model on which CAL relies; section 3 presents the framework that provides the needed run–time infrastructure to implement it, and section 4 shows a brief description of the underlying algorithms; section 5 glances at other authors' work, and section 6 shows our conclusions and future work. 2. CAL INTERACTION MODEL CAL [Corchuelo et al., 2000] is a language aimed at describing coordination patterns amongst a number of objects in a way that is independent from computation or other aspects. Coordination patterns are not dependent on the objects they coordinate, so that they can be easily reused. To achieve this, CAL uses multiparty interactions as the sole mean to express coordination. In CAL, each interaction has a name, a number of roles and a number of slots associated to it. The name of the interaction is a string which unambiguously identifies an interaction in the system. When an object is ready to coordinate with other objects, it offers to participate in one or more interactions by mean of their interaction names. So, every object can offer participation in one or more interactions simultaneously. In every offer, a participant states which role it plays in the interaction, and may establish constraints on what objects should play the other roles. An interaction may be executed as long as a set of objects satisfying the following constraints is found: (i) there is an object per role willing to participate in that interaction and play that role; (ii) those objects agree in interacting with each other, i.e., the constraints they stablish are satisfied. A set of objects which can execute an interaction is what we call a enablement .
Figure 1. Offers made to the coordinator of an interaction I. Figure 1 shows an example system with an interaction called I amongst three objects that must play roles P , Q and R . Objects and make offers to play role P, objects and make offers to play role Q, and object makes an offer to play role R. The objects and require that role Q must be played by and respectively, and vice versa. Neither nor establish constraints about what object should play role R. In the other hand, the object accepts that roles P and Q could be played by any object. Since exclusion must be guaranteed, an object cannot commit to more than one interaction at a time. But, since an object can offer participation simultaneously in more than one interaction, it can be in more than one enablement. So, when two or more enablements share objects, they cannot be executed simultaneously. The set of enablements that cannot be executed are said to be refused . When an enablement of an interaction is executed, the objects in it can communicate by means of the interaction slots. A slot is a shared variable among the objects in the enablement which is created when the enablement is executed. These slots make up a local state that simulates the temporary global combined state in IP [Francez and Forman, 1996], being the most important difference that an object does not need to have access to the local state of other objects in order to get the information it needs. Obviously, a multiparty interaction delays an object that tries to read a slot that has not been initialized yet by another object. 3. A FRAMEWORK FOR ASPECT–ORIENTED MULTIPARTY COORDINATION We have carefully designed a framework that offers a number of high-level services for providing CAL run–time support. This framework is extensible so that new middlewares or coordination algorithms may be easily incorporated.
Figure 2. The architecture of our solution. Figure 2 shows a snapshot of a running system that sketches the architecture of our implementation, which is composed of the following elements: The gatekeeper: It is one of the most important components of our architecture because it is responsible for tasks such as security policies, billing, generating and managing UUIDs, locating interaction coordinators or interacting with the system administrator. Interaction coordinators: They are responsible for detecting enabled interactions and umpiring amongst conflicting ones, i.e., interactions that cannot be executed simultaneously because they involve a common object. The algorithms we use are presented in section 4. Proxies: In our framework, objects are considered to be external entities that use proxies to interact. This makes a clean separation between functionality and coordination details and simplifies the framework because it does only need to care about proxies, independently from the objects they represent. Communication managers: They are responsible for managing communication amongst a number of objects that have committed to an interaction. They are also responsible for coping with faults during multiparty communication [Zorzo and Stroud, 1999]. At a first glance, it might seem that the gatekeeper is a bottleneck component of our framework, but it is not. The reason is that the functionality it offers is used only when new objects or interactions are added to the system, or when an object needs to fetch references to the coordinators responsible for the interactions in which it may be interested. It is also worth noting that nothing prevents us from creating several instances of the gatekeeper, thus reducing
the impact of a crash. However we usually refer to this component as “the gatekeeper” because all of its instances are functionally equivalent. It is also worth mentioning that having proxies does not amount to inefficiency because they reside in the same memory space as the objects they represent. Furthermore, separating coordination concerns from objects at run– time is worthwhile because this draws a clear line between the functionality they encapsulate and the way they interact with others. 4. IMPLEMENTING MULTIPARTY COORDINATION In this section, we describe the algorithm we have devised to implement multiparty coordination. It is called and it is scattered amongst coordinators and proxies. It is responsible for the following tasks: Enablement detection: The offers received from proxies are analysed sequentially to find sets of objects that agree in participating in an interaction, i.e, enablements. Enablement selection: When one or more enablements have been detected, as many as possible should be executed simultaneously. Thus, an election under conflicting enablements needs to be held. That is the reason why we have split into two parts called –solver and –core that are further explained in the following subsections. 4.1. The – solver Algorithm –solver is responsible for enablement detection, and the ideas behind it can be presented by means of the example in figure 1 at page 163. –solver processes offers as they arrive and form a consolidation graph that consists of tuples such as This tuple represents the offer made by and it means that it wants to play role P in interaction I , requires to play role Q, and does not care about which object should play role R. We say that role P is consolidated in this tuple, whereas role Q requires object and role R accepts any object. Figure 3 shows the consolidation graph built by our algorithm as the offers made by the objects in our example arrive at the coordinator responsible for interaction I . Assume that the offer made by p1 arrives first so that α –solver constructs a consolidation graph with only one node If the second offer is made by object a new node of the form is added to the graph, but no connecting node is constructed because the tuples so far processed cannot be consolidated, i.e., objects and cannot interact together. If the offer made by is then received, a node of the form is added. Since it consolidates with a connecting node of the form is
Figure 3 . Consolidation graph for the system in figure 1. added. It indicates that both and want to participate in interaction I and agree in committing to it together with any object playing role R. Notice that no enablement is found until object makes its offer. When this happens, two enablements are found simultaneously, but, unfortunately, they are conflicting because they share In order to present α –solver code, we first need to define a consolidation operator that is defined on both the tuples of the consolidation graph and its elements. We refer to this operator as and it is defined on tuples as It is defined on the elements of a tuple by means of the following axioms: 1 as long as 2 as long as 3 4 5 The entry–point to –solver is the routine called ProcessO f f er( T,G ) presented in figure 4. ( T is the offer being processed, and G is the current consolidation graph, which is built incrementally as new offers are received.) It simply iterates over the set of roots of graph G and calls routine Search( T,R ) presented in figure 5 on each one. ( T represents the current offer, and R a root of graph G. ) This routine first tries to consolidate tuples T and R , and if it is possible, the consolidated tuple is returned and inserted in the graph as a parent of both T and R. Otherwise, a recursive search is performed in the subgraph whose root is the left child of R. If a consolidation l e f t is found there, it then recursively tries to find a new consolidation of l e f t with a tuple in the subgraph
ProcessOffer (T: Tuple; G: Graph): Set of Tuple enablements: Set of Tuple roots: Set of Tuple C: Tuple enablements roots the roots of G add T to G as an unconnected leaf for every root R in graph G do C Search ( T , R ) if C is not null and every role in C is consolidated then enablements enablements end if end for return enablements end ProcessOffer Figure 4. –solver entry–point. Search ( T : Tuple; R : Tuple): Tuple result: Tuple; left, right: Tuple; if T and R can consolidate then result let result be the parent tuple of T and R else if T is not a leaf then left Search ( T , left child of R ) if left is not null then right Search (left, right child of R ) result (right is not null ? right: left) else right Search ( T , right child of R ) result (right is not null ? right: null) end if else result null end if end if return result end Search Figure 5. –solver recursive consolidation function. whose root is the right child of R. If such a consolidation if found, then it is returned because it is the most consolidated tuple that has been found; else, left is returned. If no consolidation is found while examining the left subgraph of R, then the right subgraph is also explored. If no consolidation is found, then null is returned.
4.2. The α – core Algorithm The –core algorithm takes the enablements detected by –solver and selects for execution as many as possible. If a enablement is rejected, that is because it conflicts with another that has already been selected. An enablement can be conflicting in two different ways: It may be locally conflicting with another enablement of the same interaction. This is the case of enablements c and d in the example in figure 3. It may be remotely conflicting with another enablement of another interaction. For the sake of simplicity, in this section, we assume that each coordinator is responsible for only one enablement. We drop this restriction in the next section. The idea behind –core is quite simple. Shared objects are considered to be shared resources amongst the coordinators which coordinate the enablement where they appear. In order for an enablement to be selected, its coordinator must ensure exclusive access to every shared object participating in it. So, a coordinator must lock every shared object in its enablement before it can be selected for execution. For instance, consider the example in figure 6: there are two coordinators for two interactions and that are conflicting because is offering participation in both. Figure 7 shows a scenario for this system, and table 1 describes the messages –core uses. Figure 6. Two conflicting coordinators with one enablement each one. In this scenario, is the first object ready to participate in Since it is only interested in this interaction, it notifies its offer to coordinator by means of a PARTICIPATE message, and then waits for a START message before beginning the execution of this interaction. Assume that gets then ready to participate in either or Since it offers participation to more than one coordinator, it sends two OFFER messages by means of which the
Figure 7. A possible scenario for the system in figure 6. coordinators that receive them can infer that this object is shared with others, although they need not know each other directly. When coordinator processes this offer, it detects enablement Since is a shared object it tries to lock by sending it a LOCK message. There is no need to lock because this object is interested in only one interaction; thus it is not a shared object. Assume that and decide then to participate in and send a PARTICIPATE message to its coordinator. It then detects enablement and tries to lock too. Unfortunately, the LOCK message sent to by is received before the LOCK from arrives. Thus, notifies that it accepts to be locked by means of an OK message,