• No results found

2.2 Example Centralized Synchronous Distributed Collaborative Systems

2.2.3 Weasel and Clock

Weasel[Urn92][GU92][UN94] (Figure 2.5) is a development environment support- ing synchronous distributed collaborative applications, from GMD and the Norwegian Institute of Technology. It uses an adaptation of the pull MVC paradigm.

Figure 2.5: Weasel

In Weasel, applications written in an imperative language (Turing) play the role of models. Views are constructed using a the Relational View Language (RVL), which creates a bi-directional relationship between application data structures and views.

When constructing views, functions (in the functional programming language sense) map from data structures in the application to view (user interface) components. Functions can be composed to produce composite views. Functions can also be anno- tated such that the view components they produce (e.g., buttons) are active. If such an active component is manipulated (e.g., a button is pressed), the Weasel infrastruc- ture stores a value in an argument of the function. This value can then be propagated back to the application. Thus, as in Rendezvous, views subsume the controller MVC function. Changes to application state trigger re-evaluation of the view function. In the course of re-evaluating this function, expressions are passed to the application for evaluation, so that the new view will correspond to the current application state.

Parameters to Weasel view functions can be either remote (i.e., they can come from the application) or local (from the view component itself). Thus Weasel, like Rendezvous, can implement different views of the same application by using different functions or local view state.

The authors of Weasel later developed the Clock architectural style and visual architecture language[GU96], and the associated ClockWorks[GMU96] visual pro- gramming environment. The components of a Clock architecture are programmed textually using a functional language based on Haskell[Bir98].

Clock architectures are designed visually using ClockWorks. On the left side of Figure 2.6 is a simplified drawing of a Clock architecture being designed in Clock- Works. On the right side of the figure is a drawing of the resulting user interface. This simple application represents a toggle switch labeled Press below a light that goes on or off each time the button is pressed (it is off at present). A Clock archi- tecture is a hierarchical structure matching the user interface containment hierarchy. Components are represented by rectangles, with a component name at the top of each rectangle and a class name at the bottom.

Figure 2.6: Clock Architecture Example

Figure 2.7 shows more detail of this simple clock architecture1. Boxes above components (Toggle and Depressed, in the figure) are Abstract Data Types (ADTs) associated with the components. Arrows to the left of components and ADTs denote the supported incoming event/update (single arrow) or request (double arrow) calls. Arrows to the right are outgoing calls that can be made by the respective components. Identifying these outgoing calls supports the Clock constraint maintenance system, described below. Rounded boxes show the code for the indicator (left) and button (right).

Assume the user depresses the button. When he does so, the mouseButtonUpdt

function is evaluated with the “Down” argument. It calls depress, and this call bub- bles up the tree to the Depressed ADT, changing its state. Since the button view function calls isDepressed, a constraint invokes the view function of the button, and the button is redrawn with a sunken relief. When the user releases the button,mouse- ButtonUpdtis called with the“Up”argument. This callsrelease, which bubbles up to the Depressed ADT again and resets its state, triggering the view function of the but- ton to be re-evaluated, restoring the button to raised relief. Then mouseButtonUpdt calls buttonClick. This bubbles all the way up to the Toggle ADT, toggling its value. Since the indicator view function callsgetValue, a constraint causes the re-evaluation

of this function, which turns the light on by filling the upper circle with the color “white”.

Clock’s call bubbling facility enforces data hiding because components can only make calls on components and ADTs that are their ancestors in the tree. ADTs should therefore be located at the lowest point in the tree covering all components accessing the ADT. Clock’s constraint facility enables communication among components that are not in an ancestor/descendant relationship. Both facilities are indirect means of communication, where components do not directly reference each other. This facil- itates reorganization of the architecture, which can be performed in ClockWorks by direct manipulation. Unlike XTV, Rendezvous, and Weasel, models are distributed throughout Clock architectures as ADTs, making the various Model/View relation- ships difficult to diagram.

Clock supports various annotations to the architecture, telling ClockWorks how to generate a particular implementation. Like Rendezvous, default implementations of Clock architectures are purely centralized, with views distributed using the X Window System. One annotation tells ClockWorks to divide the architecture into a client/server implementation (Figure 2.8). Various caching algorithms can be selected with this annotation. In the figure, the portion of the architecture above the annota- tion would be centralized, while the portion below (a copy of which would be created for each participant) would be distributed. Calls from client to server and constraint invocations from server to client will cross the network transparently. Clock annota- tions are (normally) semantics-preserving, meaning that only the implementation, not the functionality of the system is changed by an annotation. This allows applications to be developed without annotations and then optimized using annotations. Other annotations specify the type of concurrency control to use on particular ADTs, and which ADTs should be replicated. Replicated ADTs may be specified on the server

Figure 2.8: ClockWorks Client/Server Annotation

side of the diagram to denote more global call/constraint bindings, but replicas will be created for each client. A centralized replica will also be created to distribute updates from one replica to another and to support latecomers. (When ADTs are replicated, the developer asserts that the concurrency control implemented will not change the semantics of the application, since this is difficult to determine automatically.)

Like Weasel, Clock uses a pull MVC variant. However, some of the caching options implement push-like semantics, where the server anticipates model values that may be needed in the future based on past queries, and proactively pushes these values to the client cache[GUN96a]. Like XTV and Chung’s infrastructure, but unlike Rendezvous and Weasel, Clock provides no support for different views of the same model.