a S e rvic e
a S e rv ice Acce p t Tra n sitio n
a S e rv ice Subnet
O th e r p a rts o f th e O b CS
< r>
a S e rv ice Re tu rn Tra n sitio n E nd_ a Se rvic e < r> P3
a S e rv ice O u tp u t Po rt }
Fig. 2. Syntax of a CO class definition
The interface and ObCS together fully define the behavior of instances: A service request will begin executing when one of its associated accept transitions is enabled by the current marking of the ObCS. Conversely, the execution of a service is modeled
by the occurrence of the associated macro-transitions, which states the side effect of the service execution on the object. 1.2
Timing in the ObCS nets
The net dialect used to describe the ObCS uses timing on the transition’s input arcs. An arc may feature an enabling time interval, which states the moments when a given token is available for the transition’s firing. The origin for this time interval is the time when the token has initially entered the place. Such a construct makes it easy to model « watchdogs », or time guarded actions that are frequent in distributed systems. Fig. 3 illustrates such a construct: Transition T1 represents the normal processing to be applied to tokens that enter place Waiting. However, if such a processing does not occur before a given amount of time (Delay) has elapsed, A default action, modeled by transition T2, will be triggered.
W aiting ]D elay, + ∞ [
[0, D elay]
T1
T2
Alarm
N orm al term ination Fig. 3. Modeling a « watchdog »
1.3
Invocation modes and their semantics
The ObCS are meant to describe the « server » behavior of objects (i.e. what their synchronization constraints are) but also their « client » behavior (i.e. how they request services from other Cooperative Objects in the system). The communication between Cooperative Objects is syntactically expressed using the conventional dot notation, by actions in the ObCS transitions. Such as service invocation is illustrated in Fig. 4: The class described here acts as a client of the aServer class described in Fig. 2. The ObCS descriptions includes the definition of the places type: for example, place PB is defined to hold references to instances of the aServer class, while the tokens contained in place PC will be 3-tuples holding an integer, a reference to an instance of aServer and a string.
Class aClient { // (excerpt) // Definition of the places’ type ObCS PA: PB: PC:
PA
PB
r = s .aS ervic e ( p );
PC }
Fig. 4. Synchronous Rendezvous
The variables on the arcs act as formal variables for the transition. The action of the transition is to call the service aService on the object bound to variable s, providing as a parameter the integer bound to variable p. A transition whose action is the invocation of another Cooperative Object is called an invocation transition. The default semantics for such a call is the synchronous rendezvous, whose operational semantics is described in Fig. 5. The semantics of the synchronous rendezvous is given within the framework of highlevel Petri nets, by enhancing the ObCS nets of both the client and the server of the rendezvous. Although the designer of the net only sees the ObCS descriptions as given in Fig. 2 and Fig. 4, the nets, before being actually executed in the running system, are expanded in the following way: Client-side semantics The following transformations have to be applied to each invocation transition: • The invocation transition is considered as a macro-transition extending from the request transition to the complete transition. The request transition constructs a parameter token, including the original parameters of the service, the identity of the caller (variable this) and a globally unique call-identifier. This token is deposited in the Invocation Parameter port. • A waiting place is introduced between the request transition and the complete transition. The presence of a token in this place indicates that a call is in progress. • The results from the service call will be return to the client in its Invocation Return Port. The arrival of a return token will enable the complete transition, and terminate the service call on the client’s side. It is important to note that the variable id is present on both input arcs of the complete transition: the transition is
only enabled if a substitution is possible between the token values held in the Waiting and Return Port places, meaning that the same id is found in both tokens. This construct is necessary to allow a client to issue concurrently several invocations, and to enable the client to match the results it receives with the parameters it has initially provided. Server-side semantics On the server’s side, the structure of the net is not altered, but only the definition of the places’ type and the inscriptions on the arcs. The only requirement for the server is to keep both the client’s identity and the call-id within the service subnet, so that the results of the service can be properly routed back to the caller. The synchronous rendezvous is thus implemented as two unidirectional asynchronous message sending. Only one primitive is required, and supposed to be provided by the implementation environment: the ability to deposit a structured token in a place of a remote Cooperative Object. This primitive is used to transport both the parameters and the results of an invocation. In the current implementation, this primitive is provided by a CORBA compliant system, which takes care of the marshaling and unmarshaling of call arguments, and of the routing of tokens. However, other implementations could be easily substituted, such as Java RMI (Remote Method Invocation) or lower level solutions based on sockets. PA
PB
R e q u e st Tra n sitio n
< s>
< p , this , id >
D e p o s it to k e n in a S e r v ic e in p u t p o rt fo r o b je c t s
< p , c, id >
< p , s, id >
P1
aSe rvic e In v o ca tio n Pa ra m e te r p o rt
W aiting
< p , c, id > a S e rv ice Subnet < r, c, id >
Expanded In v o ca tio n Tra n sitio n In v o ca tio n Re tu rn p o rt
< p ,s, id >
E nd_ aSe rvic e < r, id >
D e p o s it to k e n in in v o c a tio n re tu rn p o rt fo r o b je c t c
< r, id > P3
< p ,s, r> PC (a) c lie nt' side
C o m p le te Tra n sitio n (b) se rve r's side
Fig. 5. Operational semantics of synchronous rendezvous
Other invocation strategies can be described in the same way: The time-out rendezvous allows the client to specify the amount of time it accepts to wait for the result of the call, and to take a corrective action if the result is not provided within this delay. The syntax of the time-out rendezvous and the associated semantics are described in Fig. 6: the semantics of the inhibitor arc adjacent to transition discard must be noted: the transition is enabled only if no substitution can be made on the variable id, i.e. if the token holding the call-id has already left the Waiting place. PA
PB
PA
PB Inv ocation P aram eter port
r = s .aServic e ( p );
D elay
T IM EO UT
ELSE
Alarm
PC
O p eratio nal s emantic s (c lient sid e)
W aiting ]D elay, +∞ [
[0, Delay]
D is c ard
Alarm
PC
Inv ocation R eturn port
Fig. 6. Time-out Rendezvous and its associated semantics
Sometimes, the client may chose to simply ignore the possible results of a service, and to simply proceed as soon as the invocation has been issued, without any acknowledgment. This strategy is called asynchronous invocation, and its syntax and operational semantics are illustrated in Fig. 7. PA
PB
PA
s .aS ervic e ( p );
PC
PB
O perational s em antic s (c lient s ide)
PC Inv ocation P aram eter port
Fig. 7. Asynchronous invocation and its operational semantics
It must be noted that whatever invocation strategy is chosen only impacts on the structure of the client’s ObCS: the structure of the server’s ObCS is not modified, and any service can thus be called with any invocation strategy.
2
The case study
We will now present how the Cooperative Objects formalism can be applied to model the case study proposed as an exercise for the second edition of the OO-MC workshop, held in Osaka during ATPN'96. We present only a simplified solution to the initial requirements: the various styles of ownership have not been retained, but we show how this could be modeled if desired. Our solution focuses instead on the communication between the various users of the system and on the resource-locking protocol that allows to consistently edit and update the shared shapes. 2.1
The UML model
Cooperative Objects retain all of the features of classical object-oriented notations, notably their structural aspects (the various kinds of relationships that may relate two classes) and the use of inheritance as a fundamental organization and abstraction mechanism. To describe the classes involved in the solution of the case study and their relationship we will use the UML notation [11], which is essentially a derivative of the original OMT notation. Fig. 8 illustrates the UML model of the case study, stating the interface of the classes and their relationships. The semantics and behavior of the classes will be discussed further in the following sections. Note that the UML notation uses a Pascal-like notation for the method’s signature, while the CORBA-IDL that we use for the CO classes is more C++ - like. Dispatcher DispatchClient
0..* Add (c : DispatchClient) Remove (c : DispatchClient) Dispatch (o : DispatchObject, a : DispatchAction)
Refresh (o : DispatchObject, a : DispatchAction)
DispatchObject
1
Grab () : boolean Release () GraphicEditor CreateShape (c : GraphicShape) DeleteShape (c : GraphicShape) Select (c : GraphicShape) Unselect (c : GraphicShape)
GraphicShape
DispatchAction
0..*
Fig. 8. The UML model of the case study
In Fig. 8, the triangles denote generalization (the more general class being on top); The arrows between classes denote association, with the arrow end indicating the navigability of the association. The dotted arrows denote a dependency, stating that a
class depends in some way on another, yet without holding references to instances of that class (in our case, the dependency is due to the method’s signature). 2.2
Multicasting
The distributed and cooperative nature of the case study requires special communication primitives between the software components. For example, each time a user adds or updates a graphic shape, this action must be forwarded to the other users. Likewise, each time a new user joins the editing session, he must be made known to all the others. interface Dispatcher { void Add(in DispatchClient); // Add a client to the list of dispatch clients void Remove(in DispatchClient); // Remove a previously added client void Dispatch(in DispatchObject o, in DispatchAction a); // Dispatch the object o to all known clients, // to execute action a } class Dispatch_spec specifies Dispatch { ObCS // Definition of the places' type Clients: // The Clients place holds the list of clients StillDispatching: AlreadyDispatched: Add
D ispatching com plete
Clients
Re mov e
Still D ispatching
c .Refres h(o,a)
Dispatch A lready D ispatched
R eset clients
Fig. 9. The Dispatcher class
This kind of "one to many" communication is often known as multicasting: the same message is dispatched to a number of potential recipients, which will deal with it in
their own specialized way. The Cooperative Object formalism does not include a special modeling construct to represent such communication. The formalism is strictly based on the client-server approach, where a client must know a reference to the server before calling a method, and where methods calls and answers are strictly one to one. To emulate multicasting in the formalism, we define an interface called Dispatcher, and formally define its behavior through a CO class called Dispatch_spec. The purpose of this class is to maintain a list of potential clients, and to allow forwarding a same message to all the clients known by the dispatcher. The Cooperative Objects class for the dispatcher is given in Fig. 9. Basically, when a Dispatcher object receives an invocation for its Dispatch method, it calls the method Refresh for each of the clients it holds, forwarding them an objet o, and an action a to execute on that object. The methods Add and Remove are meant to manage the list of clients. The correct use of the Dispatcher class implies the use of polymorphic objects: Any objet that is to be called by the Dispatcher class must be an instance of a class that implements the DispatchClient interface (which features a Refresh method). This will be the case, for example, of the GraphicEditor class. Likewise, the objects to be dispatched must implement the DispatchObject interface, as this will be the case for the Shape class. The behavior of the Dispatch_spec class can also be reused in other contexts: instead of holding a list of clients and dispatching an object to each of them, the same structure could be used to hold a list of shapes, and dispatch each of the shapes to one client. This would be useful, for example, when a new user joins the group to let him know of the current set of edited shapes. 2.3
The GraphicEditor class
The GraphicEditor class models the behavior of the editing tool. Each user of the cooperative application will have a personal instance of GraphicEditor. The aim of this class is to allow users to create and manipulate shapes, while making sure that their actions are conform to the cooperation protocol defined in the requirements for the case study. Several of the service input ports (for the services CreateShape, DeleteShape, Select and Unselect) have a special « button-like » representation: this is to distinguish those services as being User Services, i.e. services that are not meant to be triggered by other Cooperative Objects but directly by the user of the system, through some userinterface mechanism. The Select service, for example, could be triggered by clicking with the mouse on the on-screen representation of the shape. The implementation of that kind of user-services has been discussed in [3].
The GraphicEditor class, as shown above, deviates in some ways from the initial requirements, and makes some other requirements more precise: interface GraphicEditor: DispatchClient { void CreateShape(in GraphicShape c); // Adds a new shape to the editor void DeleteShape(); // Removes selected shape from the editor void Select(in GraphicShape); // Select a free shape, for later edition or deletion void UnSelect(); // Unselect selected shape, freeing it for other editors void Refresh(in DispatchObject o, in DispatchAction a); // Refresh the shape o, for action a; inherited. } class Editor_spec specifies GraphicEditor { // Definition of the places' type ObCS OwnedShape: // The shapes I own FreeShapes: // The shapes owned by nobody UsedShapes: // The shapes owned by someone else Cre ate Sh ap e
De le te Shap e delete c ;
O wnedShape
not O K
UnSe le ct c .Releas e ( );
OK
Se le ct O K = c .G rab ( );
F reeShapes
Re fre sh
Re fre sh
U sedShapes Re fre sh
Re fre sh
}
Fig. 10. The GraphicEditor class
For example, at any moment an instance of the editor may own several shapes (their references are stored in the OwnedShape place). After an editor creates a shape, it initially owns it. Only owned shapes can be deleted. A free shape can become owned
by selecting it, and conversely an owned shape becomes free by unselecting it. From the initial requirements, we have not retained the various styles of ownership, but they could be included by adding other services with the same pattern as Select / Unselect. For simplicity, we have not modeled the updating of the shapes by the editor: this could be easily done by adding one or more updating services, with the same activation precondition as the DeleteShape service. 2.4
The GraphicShape class
The GraphicShape class essentially acts as a monitor, allowing to reliably lock and unlock a shape before deleting (or otherwise updating) it. The ObCS of the GraphicShape class is illustrated in Fig. 11. The shape is also responsible for forwarding the actions triggered on it to all the other editors, so that they are informed of the changing of the shape’s status. To this end, the shape uses an instance of the Dispatcher class described above. Two instances of the GraphicEditor class may concurrently try to select a shape, by calling it’s Grab service; only one of them, however, will actually lock the shape (the Grab service returning TRUE) while the other one will be informed that it’s locking attempt has been refused. This kind of synchronization protocol is sometimes called « pessimistic locking », but an « optimistic locking » scheme such as the one described in [7] could be modeled as well. class GraphicShape specifies DispatchObject { // Definition of the places' type ObCS Used: ; Free: ;
G rab < d is p > Cr e ate d is p .D is p atc h (th is , C R E AT E) ;
< F AL S E>
< d is p >
< d is p >
G rab d is p .D is p atc h ( th is , S EL );
< d is p >
< T R UE> U sed
De le te d is p .D is p atc h (th is , D EL);
< d is p >
F ree < d is p >
Re le ase d is p .D is p atc h ( th is , UN S E L);
< d is p >
}
Fig. 11. The GraphicShape class
Several of the requirements for the case study are not tackled in this presentation, for example the connection and deconnection of editors, or the hierarchical nature of the drawings. They could be handled by reusing the pattern of the Dispatcher class at various levels, so that a shape could for example hold references to all of its subshapes.
3
Conclusion
The language presented in this paper, aims at modeling concurrent and distributed systems following the OO approach. Objects are defined in a rather classical way, using most concepts of Object-Orientedness: class/object distinction, dynamic object creation, use relationship between objects by service call, inheritance and polymorphism. Each object may have a concurrent behavior, which is modeled by means of a High-Level Petri Net. Moreover, all objects may be simultaneously active and the service requests and the service results they send one to another synchronize them. Several important topics are not addressed in this paper for space reasons: • As the language allows for inheritance with specialization semantics, it is necessary to ensure that a derived class is compatible with its ancestor, behaviorwise. • Cooperative Objects are executable in essence, and several techniques for executing the models are devised in [1], at the system, the class or the object level.
References 1.
Bastide, Rémi. "Objets Coopératifs : Un Formalisme Pour La Modélisation Des Systèmes Concurrents." Ph.D. thesis, Université Toulouse III (1992).
2.
Bastide, Rémi, and Palanque, Philippe. "Cooperative Objects: a Concurrent, Petri-Net Based Object-Oriented Language." Systems Engineering in the Service of Humans, IEEE-SMC'93, Le Touquet, France, October 15-20, 1993. IEEE Press (1993)
3.
Bastide, Rémi, and Palanque, Philippe. "Petri Net Based Design of User-Driven Interfaces Using the Interactive Cooperative Objects Formalism." in Interactive Systems: Design, Specification, and Verification, DSV-IS'94. Fabio Paternò, Volume editor. Springer-Verlag (1994) 383-400.
4.
Bastide, Rémi, and Palanque, Philippe. "A Petri-Net Based Environment for the Design of EventDriven Interfaces." 16th International Conference on Applications and Theory of Petri Nets, ICATPN'95, Torino, Italy, June 1995. LNCS, no. 935. Springer (1995) 66-83.
5.
Bastide, Rémi, Palanque, Philippe, Sy, Ousmane, Le, Duc-Hoa, and Navarre, David. "Petri-Net Based Behavioural Specification of CORBA Systems." 20th International Conference on Applications and Theory of Petri Nets, ICATPN'99, Williamsburg, VA, USA, June 21-25, 1999.
6.
Bastide, Rémi, Sy, Ousmane, and Palanque, Philippe. "Formal Support for the Engineering of CORBA-Based Distributed Object Systems." Distributed Objects and Applications (DOA'99), Edinburgh, Scotland, September 5-6, 1999. IEEE (1999)
7.
Beaudouin-Lafon, Michel, and Karsenty, Alain. "Transparency and Awareness in a Real-Time Groupware System." ACM Symposium on User Interface Technology (UIST'92), Monterey, CA, USA, November 1992. ACM Press (1992)
8.
Booch, Grady. Object-Oriented Analysis and Design With Applications Benjamin/Cummings (1994).
9.
European Space Agency. HOOD Reference Manual. 3.0, WME/89-173/JB ed. (1989).
10.
Object Management Group. The Common Object Request Broker: Architecture and Specification. CORBA IIOP 2.2 /98-02-01, Framingham, MA (1998).
11.
Rational Software Corporation. UML Notation Guide. 1.1 ed.1997.
12.
Sibertin-Blanc, Christophe. "Cooperative Nets." 15th International Conference on Application and Theory of Petri Nets, ICATPN'94, June 1994. LNCS, no. 815. Springer (1994) 471-90.