MATERIAL Y METODOS
TABLA 11 TRATAMIENTO QUIRURGICO UTILIZADO EN LOS PACIENTES CON LITIASIS VESICAL POR AÑO DE ESTUDIO
Introduction The third case study implements event-loop actors5once with an ad hoc approach similar to the one used by JCoBox [Schäfer and Poetzsch- Heffter, 2010] and once based on the OMOP. The concurrency model is in-
spired by AmbientTalk [Van Cutsem et al., 2007], but this implementation
provides only isolation properties and asynchronous message send semantics between actors (cf. Sec. 2.4.4). Other aspects such as complete libraries and support for non-blocking interactions are disregarded.
Basic Guarantees The case study implements the notion of event-loop ac-
tors that are containers for an object graph. An actor provides a number of guarantees for all objects it contains. Essential to the notion of an event-loop is that only the actor performs operations on the objects it owns. This eliminates low-level data races. All other actors in the system have to communicate with the actor via asynchronous messages to affect its objects.
Thus, an implementation needs to enforce that no direct operations are performed on objects owned by other actors. The operations have to be reified and added to the event queue of the actor. The actor processes events one
5The implementation is referred to as AmbientTalkST despite its lack of many of the essential
features of AmbientTalk, because the name is a convenient metaphor to describe its main semantics of event-loop actors with proper isolation.
by one. Both of the presented implementations guarantee this basic aspect. Furthermore, both implementations guarantee the notion of safe messaging (cf.
Sec. 3.3.2). Thus, messages exchanged between actors are guaranteed not to
introduce shared state.
State encapsulation on the other hand is not supported by either of the im- plementation, even though it would be straightforward with the OMOP.
Ad Hoc Solution The ad hoc implementation strategy is similar to the one
described bySchäfer and Poetzsch-Heffter[2010], but kept much simpler. Sim-
ilar to their approach of wrapping objects, we use stratified [Bracha and Un- gar, 2004] proxies [Van Cutsem and Miller, 2010] to represent far references,
i. e., references between objects residing in different actors. The proxy wraps actual objects and reifies all operations on them to enforce safe messaging and asynchronous execution. This approach also provides coverage for Smalltalk’s reflection, because it is based on message sends to the object.
Safe messagingis realized by wrapping all objects in parameters and return values. Thus, this implementation comes with the performance drawbacks described inSec. 3.3.2. Each object needs to be wrapped with another object. However, it avoids the need for copying the entire object graph.
While not implemented, this approach can be extended to provide owner- ship transfer semantics upon message send. With Smalltalk’s #become: it is possible to ensure that the original actor does not hold on to the object it sent via a message. However, the #become: operation is expensive. It scans the whole heap to exchange object references of the receiver with the reference given as an argument. Furthermore, the #become: operation is not supported by VMs such as the JVM and CLI, and, it cannot be used as a general imple- mentation strategy.
Unfortunately, the approach of using proxies, i. e., wrapper objects does not account for global state. Thus, class variables are shared between actors and introduce undesired shared state. In Java, this could be avoided by using different class loaders for each actor. However, in Squeak/Pharo there are no facilities which could provide such functionality. Since the implementation with the described features is already larger than the OMOP-based imple- mentation, we decided to accept the limitation of partial state encapsulation only.
OMOP-based Solution The OMOP-based implementation uses the ATActor
ing actor. Upon creation, #initialize is invoked, which starts the actor’s thread, i. e., Smalltalk process, to execute inside itself by using #spawnHere.
The implementation realizes safe messaging by adapting the semantics of method executions. All requests from outside the domain, i. e., from out- side the actor, are served asynchronously (line 32). The result of such asyn- chronous sends is represented by a Promise (line 23). In this simple imple- mentation, the sending actor blocks on the promise if it requires the result of the message, and continues once the promise is resolved, i. e., once the result is delivered when the event-loop processes the message (line 7).
All requests inside the actor are performed directly (line 29). Note that this listing does not include definitions for field accesses, because Smalltalk offers object-based encapsulation (cf. Sec. 4.2.1). This object-based encapsula- tion guarantees that object fields can be accessed synchronously from within an actor only. In languages like Java, we would also need to take care of fields, since Java’s encapsulation is class-based. Thus, we would need to customize #readField:of:and #write:toField:of as well.
Wrapping of the objects sent via messages is unnecessary, because the own- ership notion and the corresponding domain of an object guarantee the ac- tor properties implicitly. The OMOP’s #adopt: method can also be used to change the owner of an object as part of the message send, if desired. By changing the owner, it becomes unnecessary to scan the full heap to ensure that other references to the object are no longer valid, because isolation is ensured by the new owner domain, i. e., actor. For the moment, ownership transfer needs to be used manually by asking the receiver domain to #adopt: the received object, and therefore it is in the application code but not part of the definition inLst. 6.7.
Note that Lst. 6.7 contains only a sketch and does not take care of state encapsulation in terms of global state, however, the ATActor domain can cus- tomize #readGlobal: and #write:toGlobal: to make sure that full isolation is guaranteed between actors. Thus, global state of classes could be replaced with domain local copies by customizing these two intercession handlers. This would be very similar to the working copies used in the STM implementation (cf. Sec. 6.2.2).
While Sec. 3.3.3discussed the issue of scheduling guarantees, Lst. 6.7does not include a corresponding solution. As summarized in Tab. 6.1, the main issue is the missing control over the execution of code. Specifically, custom schedulers built on top of a VM typically do not have the ability to reschedule an actor when it is executing computationally expensive code or primitives. With the OMOP, the reification of method invocations and primitives pro-
1 ATActor = Domain ( 2 | process mailbox t e r m i n a t e | 3 4 p r o c e s s I n c o m i n g M e s s a g e s = u n e n f o r c e d ( 5 | msg | 6 msg := mailbox next . 7 msg d e l i v e r P r o m i s e : msg send ) 8 9 i n i t i a l i z e = ( 10 mailbox := S h a r e d Q u e u e new . 11 t e r m i n a t e := false . 12 process := self s p a w n H e r e : [ 13 [ t e r m i n a t e ] w h i l e F a l s e : [ 14 self p r o c e s s I n c o m i n g M e s s a g e s ]] ) 15 16 s e n d A s A s y n c M e s s a g e : a S e l e c t o r to : anObj 17 with : a n A r g A r r a y i n L o o k u p C l a s s : cls = ( 18 | msg | 19 msg := A T M e s s a g e new . 20 msg s e t S e l e c t o r : a S e l e c t o r a r g u m e n t s : a n A r g A r r a y . 21 msg r e c e i v e r : anObj l o o k u p C l a s s : cls . 22 mailbox nextPut : msg . 23 ^ msg promise ) 24 25 r e q u e s t E x e c O f : a S e l e c t o r with : args 26 on : anObj lookup : cls = u n e n f o r c e d ( 27 | msg |
28 self == Domain c u r r e n t D o m a i n ifTrue : [ 29 ^ anObj p e r f o r m E n f o r c e d : a S e l e c t o r
30 w i t h A r g u m e n t s : args i n S u p e r c l a s s : cls ].
31
32 ^ self s e n d A s A s y n c M e s s a g e : a S e l e c t o r
33 to : anObj with : args i n L o o k u p C l a s s : cls )
34
35 r e q u e s t T h r e a d R e s u m e : process = u n e n f o r c e d ( 36 T h r e a d R e s u m p t i o n D e n i e d signal ) )
vide additional points where a scheduler can hook in to enforce scheduling semantics. While it is beyond the scope of this dissertation to compare this approach with the approach of using a monitoring thread as proposed by
Karmani et al. [2009] (cf. Sec. 3.3.3), additional intercession points provided
by the OMOP provide additional control that can ease the enforcement of desired scheduling properties.
Handled Challenges The implementation of complete isolation, i. e., state
encapsulation and safe messaging are commonly the most challenging aspects asSec. 3.3argues.
The OMOP-based implementation required all of the offered mechanisms. It uses ownership to distinguish local method executions and state accesses from remote ones. In conjunction with the intercession handlers to managed execution, the domain definition enforces that remote message sends are ex- ecuted using the actor’s event-loop only. This also covers reflective operations. The mechanisms provided to satisfy the requirements for managed state enable a domain to ensure that in languages that do not provide object-based encapsulation only the owning actor can access state. An example where the domain uses the mechanisms for controllable enforcement is the mes- sage queue of an actor. Since it is owned by the domain representing the actor, direct access to the message queue is not possible. Any kind of access while the actor semantics are enforced would lead to a recursion in the access han- dler. However, the domain can disable enforcement by executing the code at the meta level, and modify the message queue as desired.
As described, this case study relies on the notion of ownership to imple- ment custom execution policies and state access policies. Arguably, the explicitly available notion simplified the definition of these policies. Furthermore, it enables ownership transfer, which is a challenge on other platforms.
6.2.4. Conclusion
This section shows that Clojure agents, software transactional memory, and AmbientTalk’s actors can be implemented on top of the OMOP. Furthermore, it demonstrates how the case study implementations map onto the OMOP and how they relate to common problems inTab. 6.1and the requirements in
Tab. 6.2.
The agent case study shows how problems related to immutability can be solved and how the OMOP helps to customize execution policies. The STM case study shows how state access policies are customized and how primitives can
be adapted. The actor case study covers the remaining challenges of isolation, scheduling policies, and ownership. For each of these, this section either pro- vides an example implementation or discusses strategies on how the OMOP can be used to solve the issues.
Furthermore, the case studies demonstrate how the intercession handlers of the OMOP satisfies the requirements for managed state and managed execution. The evaluation shows how the OMOP’s support for ownership and object adoption can be used to define policies and therefore satisfy the ownershiprequirement. Finally, it demonstrates how unenforced methods and the #evaluateEnforced: of the OMOP can be used to control precisely when its semantics are enforced. Thus, the OMOP also satisfies the last of the requirements, i. e., it provides controlled enforcement.