Coordination in a Reflective Architecture Description ... - Springer Link

2 downloads 0 Views 518KB Size Report
Pablo de la Fuente. 1. , Manuel ... Universidad de Valladolid, Valladolid 47011, Spain. {cecuesta,pfuente,mbarrio}@infor.uva.es. 2. Universidad Pontificia de Salamanca, Salamanca 37002, Spain ..... Nicholas Carriero and David Gelernter.
Coordination in a Reflective Architecture Description Language Carlos E. Cuesta1 , Pablo de la Fuente1 , Manuel Barrio-Sol´orzano1 , and Encarnaci´on Beato2 1

2

Universidad de Valladolid, Valladolid 47011, Spain {cecuesta,pfuente,mbarrio}@infor.uva.es Universidad Pontificia de Salamanca, Salamanca 37002, Spain [email protected]

Abstract. Software Architecture studies the structure of software systems, as described by Architecture Description Languages (Adls). When these capture structures of change, they are comparable to Coordination Languages. Previous work suggests that the combination with Reflection concepts renders a general framework for the description of such evolving structures. This paper describes a reflective Adl named PiLar designed to provide such a framework. It consists of a structural part, which describes the static skeleton, and a dynamic part, which defines patterns of change. The major novelty is the reification relationship, which structures a description in several meta-layers, such that the architecture is able to reason and act upon itself. The paper includes a complete PiLar example, to show the language’s use and some of its most relevant features. It describes a Tuple Space model, illustrating the analogy with existing Coordination Models. We conclude by emphasizing PiLar’s generality and applicability.

1

Introduction

Research in Software Architecture and Coordination Theory is bound to converge. Their origins and purpose are quite different, yet they show some significant similarities, and use comparable concepts. This is even more apparent in their respective linguistic representations: Coordination and Architecture Description Languages (Adls) play often analogous roles, and sometimes even the same one [8,10] is used in both contexts. Linguistically, a system’s architecture is described as the complex composition of independent pieces named components. An Adl provides the means to join together these components, conceived as previously unrelated atomic entities. When this structure can evolve, we speak of Dynamic Architecture. Similarly, Coordination is about managing dependencies between concurrent agents. We can compare these agents to components; and then their dependencies comprise a dynamic architecture. Of course there are differences of emphasis, but quite often the analogy works perfectly. Languages in both fields provide a wide range of solutions for the description of dynamic structures; a common scheme is required to compare different alternatives. Our 

This work has been partially sponsored by the Spanish Comission of Science and Technology through the CICYT Project TEL99-0335-C04-04, and by the Autonomous Government of Castilla and Le´on through the Project JCYL VA61/00B.

F. Arbab and C. Talcott (Eds.): COORDINATION 2002, LNCS 2315, pp. 141–148, 2002. c Springer-Verlag Berlin Heidelberg 2002 

142

C.E. Cuesta et al.

previous work [7] uses the notion of Reflection as an unifying concept. Using this idea, we defined the reflective architectural framework Marmol; but it still lacked a linguistic counterpart. This paper describes such counterpart. We define here a reflective Adl named PiLar (“PiLar is a Language for architectural description”) loosely based on the Marmol framework. This will allow us to effectively test reflective notions in an architectural setting, by using them as a part of a system’s description. The language has been equipped with formal concurrent semantics –based on the π-calculus–, in the spirit of existing work combining architecture and process algebras [1,3,4], and was designed to combine reflection and most interesting constructions from other Adls, maintaining applicability while providing the greatest generality. Our purpose with PiLar is twofold. First, it is mainly intended to serve as the language to describe other Coordination models and Dynamic Architectures; so it should be expressive enough to define any known dynamic abstraction. Second, it is also meant to be useful as a standalone, dynamic Adl, able to specify evolving structures; as such, it needs to show a comfortable notation. In the following sections we review the basic concepts of reflection, to later describe the syntax of our Adl, divided in a Structural Language and a Dynamic Language. Special attention is paid to the concept of reification, which provides the reflective structure, and concurrent semantics are briefly outlined. To clarify concepts, we examine an example, consisting of a specification of the TupleSpace Model; this way, the proposal of PiLar as a coordination language is substantiated.

2

Reflection in Architecture

The concept of Reflection has already a long history [9] and has been used in many areas, such as artificial intelligence, object-orientation or programming; but the combination with Software Architecture has only been proposed recently [6,7]. Reflection is defined as “the capability of a system to reason and act upon itself” [9]. The concept has many implications, but here we will consider it just inside Software Architecture. Our previous work in the Marmol framework has already determined which notions are considered of interest to the field. The resulting model has a high expressive power, as proven by a comparison with the structure of dynamic Adls and Coordination Languages: each one of them has a reflective equivalent [7]. Reflection divides an architecture in two: the part which is controlled and the part which controls. These are respectively named base-level and meta-level. The meta-level can be described as the context in which the base-level is defined; this defines a causal connection between them, expressed as a reification link. Each level is also divided in components. A normal, base-level component is named an avatar, and is reified by one or more meta-components in the meta-level. Components in the meta-level could be reified themselves, hence defining another level (a meta-meta-level). There’s no limit to this process, which implicitly divides an specification in several meta-layers. Details about the resulting model can be obtained from [7]. Thus reification is the main concept to introduce in PiLar. This is done in section 4.

Coordination in a Reflective Architecture Description Language

3

143

Structural Language

There are two different concerns in any dynamic Adl: the description of the static structure and the characterization of patterns of evolution. To provide the separation of concerns, PiLar itself is divided in two parts: a Structural Language describing the static skeleton of systems, and a Dynamic Language, defining the rules to make it change. In this section we briefly sketch the syntax of the former, which stems naturally from the concurrent semantics, but has been designed to be similar to other Adls’. There’s just one kind of element: the component, defined as a basic compositional unit, encapsulated and defined by one or more segmented interfaces, and present in a configuration through one or several instances. Hence it defines a type, and it is also known as archtype. It may be either primitive or composite. In the second case, the composition of several mutually interacting instances is hidden behind an interface, shaping a component hierarchy, typical of architectural description. In PiLar, a component definition has four parts, none of them strictly mandatory: interfaces, configurations, reifications and constraints. The latter two are described in sections 4 and 5; the other two are summarized below. An interface is a logically coherent aggregation of ports, which are in turn defined as the component’s interaction points, expressing both services and requirements. When just the interfaces are specified, we have a primitive component. A configuration defines a composite component. It consists of a set of component instances, interacting through bindings or attachments, defining a complete subsystem. There are four kinds of instance declarations in PiLar, namely typed instances, arrays of instances, parameterized components and reified types. The first is the most basic case: it defines a single instance of an archtype. The second is the usual array declaration of an indexed set of instances. Parameterized components support for the definition of generic abstractions. Finally, reified types refers to the use of types as instances in the meta-level, as we explain later (see section 4). On the other side, there are three kinds of bindings in PiLar, namely links, and hierarchic and typed bindings. They are very closely related. Links are simply attachments, describing a direct connection between two ports at the same level. Hierarchic bindings are nearly identical: but they connect ports in different levels, thus exporting them. Typed bindings are meant to provide complex connections. Their types are declared just like primitive components. They have an explicit name, and are declared with an argument: the set of ports to connect. Combined with reification, they acquire a great expressive power and, as explained in [7], can also be considered as meta-level connectors. We won’t focus on this in this paper, but anyway the specification of section 6 includes a simple example. The language, like other Adls [10], has also support for conditional and iterative constructs; and it allows even recursive component definitions.

4

Reification

Reification is the only reflective notion we need to introduce in the language, as stated in section 2. It’s a structural concept, but it’s also important for dynamism, as it defines how constraints will be combined.

144

C.E. Cuesta et al.

In PiLar, like in Marmol, reification expresses a bidirectional relationship: it can be seen as a link between an avatar (base-component) and a meta-component. Using it, a meta-component has access to the internal details of the avatar it reflects in; an avatar abstractions’ are reified as meta-components. Reification is a many-to-many relationship: a meta-component can reflect in many avatars; an avatar can be reified by many meta-components. There are two kinds of components in a meta-level: those which directly reflect in an avatar (meta-components) and those which don’t (meta-level components). A meta-level component interacts with meta-components at its level; thus it can affect also the behaviour of avatars [7]. Reification in PiLar can be either explicit or implicit. Explicit reification uses a specific syntax, namely a \reify construct; this can be found in a structural definition, composing the section for reifications, but also within dynamic constraints. The link can receive a name, hence making it possible to dynamically modify it later. Implicit reification simply consists of usual declarations: when an instance C of an archtype T is created, not only a component C, but also a meta-component T is declared. Hence, every declared archtype can be used anytime as a meta-component. Apart from that, implicit and explicit reification have exactly the same meaning. Combined with primitives of the Dynamic Language, this provides the language with a great power. Given that meta-components have access to internal details of avatars, dynamism, as many other interesting abstractions, is easily expressed.

5

Dynamic Language

Behaviour in PiLar is provided by a number of rules, scattered throughout component definitions in the \constraint section. They are then bound to an already defined structural skeleton, where they ensure properties and react to situations. A process algebraic syntax is a natural choice [1,3,4] for the Dynamic Language. Control constructs are then directly inspired by those of CCS [11], which is consistent with our π-calculus semantics, but easier to use. There are two notations for PiLar. The first one is purely algebraic, and is compact but complex. The second resembles a programming language, and is more readable. We only use the latter in this paper. A constraint consists on one or several rule definitions, forming a modular subsystem. The first one defines how they are combined and triggered. They describe how interactions are managed. Definitions may be recursive, and this is a way to express repetition. The other is replication (\bang), which creates a new copy of a finite process each time its first action is triggered. There are two atomic actions: sending (c!(x)) and receiving (c?(x)). The second one waits for a message, and thus is usually used as the guard (triggering event) of a process. Interaction points are ports and internal channels: to access them hierarchically, we use the well-known dot notation (Agent1.rd). Actions are combined by parallel composition, separated by the | symbol, or form a sequence, marked by the ; symbol. Parenthesis can be freely used. Control structures are also allowed here, hence we have convenient iterative and conditional constructs. Channels in a constraint are always private, except when they are specifically exported by declaring them as ports in the structural definition. Besides, there is an ex-

Coordination in a Reflective Architecture Description Language

145

Table 1. Most important reflective primitives in PiLar Keyword avatar self avatarSet portSet new del reify findr

Notation α γ Σα Σπ(a) ν(a : t) δa ρN (a : m) φN (a : m)

Global Meaning Reference to the avatar to which the constraint is applied. Reference to the component in which the constraint is defined. Set of all of the avatars reflected by this meta-component. Set of all the (public) ports in a component a. Creates a new avatar a of type t (if specified). Destroys (deletes) an entity a (a reification or an avatar). Creates a reification N between avatar a and meta-component m. Finds a reification link between avatar a and meta-component m.

trusion (\alias) and a hiding (\hide) construct to explicitly expose and restrict names when required. Bindings can be considered as the sharing of channels: when two ports are connected (a = b), data sent in one of them are received in the other, and vice versa. On the other hand, typed bindings are just like any other component definition: given their constraints, they are translated as processes. The basic Dynamic Language is just that: we only need to consider the support for reification, which is provided by means of several reflective primitives. The most interesting among them are summarized in Table 1. We should have in mind that these primitives are declared in an archtype, so they must be considered inside a meta-component, which limits their scope. This means that a meta-component can create or destroy avatars, but only those already under its control. A constraint is enforced by a meta-component and must be obeyed by all of its avatars. It should be read as a rule situated at the meta-level, where avatar is each one of the reflected components. This structure defines a very dynamic framework. A meta-component not only rules, but also creates and destroys avatars. This is true also for reified bindings, thus making possible to link and unlink components. A meta-component can trigger internal changes in response to base (or meta) events, and induce external reactions by communication with other meta-level components. This way, an event in an avatar can affect itself, all components of its kind, or even several components of several kinds. But this is when we deal with just one meta-level: when we consider further levels, even meta-components themselves are subject to change. 5.1

Brief Note about Semantics

PiLar semantics conceives an architecture as a set of concurrent processes, communicating by means of named channels, in which each component is a process. We consider that concurrency is both natural and essential in the description of systems. We also believe that, linguistically, the key aspect in an architectural description is the management of names, a global term to include ports, instances, archtypes and links. For this reason, the π-calculus [12] has been the perfect tool to specify PiLar’s formal semantics. PiLar’s semantics is then given by translation of an architectural description to a π-calculus algebraic specification. There’s no space here to comment this translation in detail, but we’ll give some overall indications. There is a direct correlation between

146

C.E. Cuesta et al.

architectural and process-algebraic concepts. Composition and interaction are basic notions in both fiels. Encapsulation is provided by name restriction. Ports are channels, and attachments are created by communication of ports; configurations correspond to topologies, and constraints are obviously translated as process definitions. Finally, we should consider the translation of reification. This is perhaps more complex, but it has been tackled with a standard interposition mechanism.

6

PiLar as a Coordination Language

PiLar is meant to be expressive enough to describe even the architecture of Coordination models; then, the example in Fig. 1 has been chosen to show the way it could deal with such a model. Specifically, it describes an architecture simulating the basic TupleSpace paradigm. For the sake of brevity, just the original Linda model [5] is considered: thus we have a single, flat tuplespace and the primitives in, rd, and out. The description could be simpler, but we have designed it to show some significant PiLar features, such as the way reification works and its relevance; the structure of meta-levels; the difference between meta-components and meta-level components, or how a meta-level connector looks like. First, we can see there are five component definitions. Two of these (System, SysTS) are composite components. The other three (Store, Triple, AgTS) are primitive ones: just their interfaces are described. We sketch the intended meanings for these below. Store. Describes an interface to an ideal data store; for example, a database system. It receives requests for storing, deleting and locating some information. AgTS. The archtype of any agent inside a tuplespace. The three ports have the usual meaning of the corresponding Linda primitives. Triple. Defines a three-tier connection, which receives a query at res, looks for an answer through get, and provides it through both res and dele. The starting point to deduce the structure is the \base-level: tag. It states which components are in the base level, which is the lowest one in the hierarchy. In the Figure, this level consists of System, which is in turn a composite of Agent1 and Agent2, instances of AgTS. The composite is extremely simple: no ports are exported, no bindings are made; both agents are just “standing there”. But their archtype AgTS is also a meta-component. Even more, it is an active metaentity, as it uses the self keyword. There are then two components in the base level, reified by one component in the meta-level. All of them have three ports, which are completely unrelated. However, we are interested in this particular case in having these ports connected, so constraits are used to impose this. The four rules state that AgTS captures every message in every avatar, and sends it through its own ports. It is obvious then that AgTS interacts with other components in the meta-level. Looking at our other composite (SysTS) we can see the configuration contains an instance named AgTS. That’s the archtype used as a (meta-level) component, what we termed a reified type in section 3. Thus, the composite SysTS is a meta-level component, as it contains AgTS, which is a meta-component.

Coordination in a Reflective Architecture Description Language

147

Fig. 1. TupleSpace Model: a PiLar example specification

In fact, it is the whole meta-level, and it consists of two components: AgTS itself and a store, DB. Two of their ports are simply linked, while others are engaged in a threetier binding L1 of type Triple. We have enough information to deduce the outcoming behaviour: tuples sent in out are inserted in the store, rd receives a query (anti-tuple) and returns the result, and in does the same, but erasing the used (read) tuple from the store. The whole system’s behaviour is then already described. Thinking about Triple, we can see it is actually a meta-meta-level component, reifying binding L1. But the constraint just uses avatar names, so it’s not really an active metaentity. Anyway, it serves as a meta-level connector, enforcing a certain communication protocol. This is a very simple exhibit; a dynamic variant could make use of other meta-meta-level entities, as desired. To sum up, the system has three levels. The base level consists of a composite module System of two agents, Agent1 and Agent2 of type AgTS, which don’t know each other. The meta-level consists of a composite SysTS of two components, a store DB of type Store and the reified type AgTS. The former is a meta-level component, while the latter is a meta-component for the agents; and they are connected by two links and a typed binding –of type Triple–. Finally, the meta-meta-level contains the two remaining types: Store and Triple. Both are inactive, so they can be safely ignored. With this example, our main purpose was to show the use of the language and how a coordination model can be described with it. The key point is that the behaviour of agents and their coordination remain separated, at different levels in the architecture.

148

7

C.E. Cuesta et al.

Conclusions and Future Work

In [7], we compare the reflective model of Marmol with existing work in Coordination and Dynamic Architecture, and show the relationship between them in general terms. Future work on PiLar includes a detailed comparison of the different approaches, with much more detail and from a linguistic point of view. The combination of Architecture and Reflection is a recent idea [6,7] and its consequences have still to be explored. The example in this paper just give a taste of PiLar’s flexibility. The concept of metacomponent makes possible to cope with many architectural abstractions in a common framework. Our notion of reification can be compared to a form of control-driven coordination, specially when considering concurrent semantics. Because of this, a detailed comparison with control-driven models such as IWIM [2] is being carried out. The development of PiLar continues. The formal definition of its semantics into the untyped π-calculus is almost finished; the work on Turner’s polymorphic π-calculus, which would provide it with a consistent type system, has already begun. The language might seem complex, but actually it isn’t more difficult to use than Wright or Rapide. Reification appears just when it’s strictly required, and in turn it offers an useful tool for the description and comparison of different dynamic Adls.

References 1. Robert Allen. A Formal Approach to Software Architecture. PhD thesis, School of Computer Science, Carnegie Mellon University, May 1997. Technical report CMU-CS-97-144. 2. Farhad Arbab. The IWIM Model for Coordination of Concurrent Activities. In Paolo Ciancarini and Chris Hankin, editors, Coordination Languages and Models, volume 1061 of Lecture Notes in Computer Science, pages 24–56, Cesena, Italia, April 1996. Springer Verlag. 3. Marco Bernardo, Paolo Ciancarini, and Lorenzo Donatiello. Detecting Architectural Mismatches in Process Algebraic Descriptions of Software Systems. In Second Working IEEE/IFIP Conference on Software Architecture, August 2001. IEEE Press. 4. Carlos Canal, Ernesto Pimentel, and Jos´e Mar´ıa Troya. Specification and Refinement of Dynamic Software Architectures. In Software Architecture, pages 107–126. Kluwer, 1999. 5. Nicholas Carriero and David Gelernter. How to Write Parallel Programs: a Guide to the Perplexed. ACM Computing Surveys, 21(3):323–357, 1986. 6. Walter Cazzola, Andrea Savigni, Andrea Sosio, and Francesco Tisato. Architectural Reflection: Bridging the Gap Between a Running System and its Architectural Specification. In 6th Reengineering Forum (REF’98), pages 12–1–12–6. IEEE, March 1998. 7. Carlos E. Cuesta, Pablo de la Fuente, Manuel Barrio-Sol´orzano, and Encarnaci´on Beato. Dynamic Coordination Architecture through the use of Reflection. In 16th ACM Symposium on Applied Computing (SAC2001), pages 134–140, March 2001. ACM Press. 8. David C. Luckham and James Vera. An Event-Based Architecture Definition Language. IEEE Transactions on Software Engineering, 21(9):717–734, September 1995. 9. Pattie Maes. Concepts and Experiments in Computational Reflection. In Norman Meyrowitz, editor, OOPSLA’87 Conference Proceedings, pages 147–155. ACM Press, December 1987. 10. Jeff Magee and Jeff Kramer. Dynamic Structure in Software Architectures. Software Engineering Notes, 21(6):3–14, November 1996. 11. Robin Milner. Communication and Concurrency. Prentice-Hall, 1989. 12. Robin Milner. Communicating and Mobile Systems: the Pi-Calculus. CUP, June 1999.