at:tutorial:distribution
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
at:tutorial:distribution [2007/05/04 08:32] – * elisag | at:tutorial:distribution [2009/01/28 17:56] – elisag | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | < | + | ====== Distributed Programming ====== |
- | This tutorial is under heavy construction! | + | |
- | </ | + | |
- | ====== Distributed Programming ====== | + | Building on the actor-based concurrency model explained in the [[actors|previous chapter]], this chapter discusses the distribution provisions of AmbientTalk. For actors to communicate across the boundaries of a single device, actors need to be capable of discovering one another' |
- | This tutorial chapter discusses how AmbientTalk virtual machines can discover and communicate with each other over the network. | + | These requirements correspond to the cornerstones of the Ambient-Oriented Programming paradigm. The seamless |
- | The integration of distribution was one of the main concerns in the design of AmbientTalk | + | |
- | More specifically, as a distributed programming language that adheres | + | Before delving in these topics, we illustrate how to activate |
- | ===== Starting the Network.. | + | ===== Going Online |
AmbientTalk provides an unique native object, named '' | AmbientTalk provides an unique native object, named '' | ||
- | When the virtual machine goes online, | + | When the virtual machine goes online, the built-in |
+ | |||
+ | Taking a virtual machine | ||
< | < | ||
Line 24: | Line 23: | ||
AmbientTalk provides language support to make some objects available to other objects residing in remote actors by means of the '' | AmbientTalk provides language support to make some objects available to other objects residing in remote actors by means of the '' | ||
< | < | ||
- | defstripe | + | deftype |
def service := object: { | def service := object: { | ||
- | def print(aDoc) { | + | |
- | system.println(" | + | system.println(" |
- | } | + | } |
}; | }; | ||
export: service as: Printer; | export: service as: Printer; | ||
</ | </ | ||
- | When an object its exported by its actor, it becomes discoverable by other actors by means of the service type. Internally, this means that the object is placed in the export table of its actor. As shown in the example, a service type is represented by a [[actors# | + | When an object its exported by its actor, it becomes discoverable by other actors by means of the service type. Internally, this means that the object is placed in the export table of its actor. As shown in the example, a service type is represented by a type tag. This means that services types are not associated with a set of methods, but they denote an abstract publication topic that objects exports. As a type tag, a service type can thus be a subtype of one or more other service types. For example, an object could offer a color printing services by exporting the following |
< | < | ||
- | defstripe | + | deftype |
</ | </ | ||
Line 47: | Line 46: | ||
< | < | ||
when: InstantMessenger discovered: { |messenger| | when: InstantMessenger discovered: { |messenger| | ||
- | when: (messenger< | + | |
- | buddyList.put(name, | + | buddyList.put(name, |
- | system.println(" | + | system.println(" |
- | | + | }; |
}; | }; | ||
</ | </ | ||
Line 57: | Line 56: | ||
< | < | ||
- | We are using a future to get the return value of the '' | + | We are using a future to get the return value of the '' |
</ | </ | ||
Line 63: | Line 62: | ||
As '' | As '' | ||
- | |||
- | ===== Partial Failure Handling | + | ===== Dealing with Transient Failures |
- | Let us consider again the example instant messenger application described in previous section to further explain the semantics of AmbientTalk' | + | Let us consider again the example instant messenger application described in previous section to further explain the semantics of AmbientTalk' |
- | When an object discovers a service type, the '' | + | When an object discovers a service type, the '' |
- | - Objects are always passed by far reference, except for isolate objects which are passed by copy. | + | - Objects are always passed |
- Native data types are always passed by copy. | - Native data types are always passed by copy. | ||
- | |||
When a remote far reference receives a messages, it flushes the message to the remote object providing that it is connected. If the remote far reference is disconnected, | When a remote far reference receives a messages, it flushes the message to the remote object providing that it is connected. If the remote far reference is disconnected, | ||
- | Therefore, a remote far reference abstracts a client object from the actual network connection state. However, it is often useful for an application to be informed when a connection to a remote object is lost or reconnected. To this end, AmbientTalk offers language constructs to install observers on a far reference which are triggered | + | Therefore, a remote far reference abstracts a client object from the actual network connection state. However, it is often useful for an application to be informed when a connection to a remote object is lost or reconnected. To this end, AmbientTalk offers language constructs to install observers on a far reference which are triggered |
< | < | ||
when: InstantMessenger discovered: { |messenger| | when: InstantMessenger discovered: { |messenger| | ||
- | ... | + | |
- | when: messenger disconnected: | + | |
- | system.println(" | + | system.println(" |
- | }; | + | }; |
- | when: messenger reconnected: | + | |
- | system.println(" | + | system.println(" |
- | }; | + | }; |
}; | }; | ||
</ | </ | ||
This code illustrate how the instant messenger application notifies when a buddy goes online or offline. In the above code, '' | This code illustrate how the instant messenger application notifies when a buddy goes online or offline. In the above code, '' | ||
+ | |||
+ | In order to cope with partial failures, AmbientTalk also allows developers to retract all currently unsent messages from the remote far reference outbox by means of the '' | ||
+ | |||
+ | The '' | ||
+ | |||
+ | < | ||
+ | when: Service discovered: { | reference | | ||
+ | when: reference disconnected: | ||
+ | messages := retract: reference; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | The construct returns a table containing copies of all messenges that were sent to this far reference, but not yet transmitted by the far reference to the remote object pointed to. Note that this has the side effect that the returned messages will not be sent automatically anymore; the programmer is thus responsible to explicitly resend all messages that were retracted but still need to be sent. | ||
+ | |||
+ | The function '' | ||
+ | |||
+ | ===== Dealing with Permanent Failures ===== | ||
+ | |||
+ | As explained in the previous section, remote far references have been designed to be resilient to intermittent disconnections by default. This behaviour is desirable because it can be expected that many partial failures in mobile ad hoc networks are the result of transient network partitions. However, not all network partitions are transient. For example, a remote device has crashed or has moved out of the wireless communication range and does not return. Such permanent failures should also be dealt by means of compensating actions, e.g. application-level failure handling code. | ||
+ | |||
+ | To deal with permanent failures, AmbientTalk uses the concept of leasing. A lease denotes the right to access a resource for a specific duration that is negotiated by the owner of a resource and a resource claimant (called the lease grantor and lease holder, respectively) when the access is first requested. | ||
+ | |||
+ | ====Leased Object References==== | ||
+ | |||
+ | A leased object reference is a remote far reference that grants access to a remote object for a limited period of time. When the time period has elapsed, the access to the remote object is terminated and the leased reference is said to //expire//. Similarly to remote far references, a leased reference abstracts client objects from the actual network connection state. Client objects can send a message to the remote object even if a leased references is disconnected at that time. Message are accumulated in order to be transmitted when the reference becomes reconnected. When the leased reference expires it, messages are discarded since an expired leased reference behaves as a // | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | ====Working with leased object references==== | ||
+ | |||
+ | The code snippet below illustrates a leased far reference in the context of an online shopping application. In the example, a client object can ask a server to start a shopping session by sending it the '' | ||
+ | |||
+ | < | ||
+ | def openSession() { | ||
+ | def shoppingCart := Cart.new(); // to store purchased items | ||
+ | def session := object: { | ||
+ | def addItemToCart(anItem) { ... } | ||
+ | def checkOutCart() { ... } | ||
+ | }; | ||
+ | def leasedSession := lease: minutes(5) for: session; | ||
+ | leasedSession; | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | The '' | ||
+ | |||
+ | < | ||
+ | We assume the use of futures to get the return value of the '' | ||
+ | </ | ||
+ | |||
+ | At client side, a customer can ask a server to open a shopping session as follows: | ||
+ | |||
+ | < | ||
+ | def mySession := server< | ||
+ | ... | ||
+ | mySession< | ||
+ | </ | ||
+ | |||
+ | The future attached to the '' | ||
+ | |||
+ | < | ||
+ | renew: mySession for: minutes(5); | ||
+ | revoke: mySession; | ||
+ | </ | ||
+ | |||
+ | The '' | ||
+ | |||
+ | When no renewal is performed due to a network partition outlasting the lease time period or in absence of utilization, | ||
+ | |||
+ | < | ||
+ | when: mySession expired: { | ||
+ | ... // free up resources used by this session e.g. the cart | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | The construct takes as parameters a leased reference and a block of code that is asynchronously triggered upon the lease expiration. This allows client and service objects to treat a failure as permanent (i.e. to detect when the reference is permanently broken) and to perform application-level failure handling. At server side, this has important benefits for memory management. Once all leased references to a service object have expired, the object becomes subject to garbage collection once it is no longer locally referenced. | ||
+ | |||
+ | ====Leasing patterns==== | ||
+ | < | ||
+ | Under construction. | ||
+ | </ | ||
+ | As is the case in other leasing mechanisms, determining the proper lease renewal period is not straightforward and may even depend on system parameters such as the number of clients. In AmbientTalk, | ||
+ | |||
+ | The first variant is a renew-on-call leased reference which automatically prolongs the lease upon each method call received | ||
+ | by the remote object. In other words, as long as the client uses the remote object, the leased reference is transparently renewed by the interpreter. | ||
+ | |||
+ | < | ||
+ | def openSession() { | ||
+ | def shoppingCart := Cart.new(); // to store purchased items | ||
+ | def session := object: { | ||
+ | def addItemToCart(anItem) { ... } | ||
+ | def checkOutCart() { ... } | ||
+ | }; | ||
+ | def leasedSession := renewOnCallLease: | ||
+ | leasedSession; | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | Similar to lease:for: , this construct takes as parameters a time interval (in milliseconds) and the remote object to which it grants access, and returns a leased far reference that remains initially valid for 5 minutes but it is automatically renewed each time the remote object receives a message. The renewal time applied on every call is the initial interval of time specified at creation by default. | ||
+ | |||
+ | The second variant is a single-call leased reference which automatically revokes the lease upon performing a successful method call on the remote object. | ||
+ | |||
+ | < | ||
+ | def myObject: = object:{ | ||
+ | ... | ||
+ | }; | ||
+ | def leasedObject := singleCallLease: | ||
+ | </ | ||
+ | |||
+ | Similar to its other two counterparts , this construct takes as parameters a time interval (in milliseconds) and the remote object to which it grants access, and returns a leased far reference that remains valid for only a single call. In other words, the leased reference | ||
+ | expires after the remote object receives a single message. However, if no message has been received within the specified time interval, the leased reference also expires. | ||
+ | |||
+ | ====Integrating leasing with future-type message passing==== | ||
+ | |||
+ | Single-call leases are useful for objects adhering to a single call pattern, such as callback objects. Callback objects are often used in asynchronous message passing schemes in order for remote object to be able to return values. These callback objects are typically remotely accessed only once by remote objects with the computed return value. In AmbientTalk, | ||
+ | |||
+ | We have integrated leasing into futures by parameter-passing a future attached to an asynchronous message via a singe-call lease which either expires due to a timeout or upon the reception of the computed return value. The timeout for the implicit single-call lease on a future can be set by annotating the asynchronous message with a @Due annotation as follows: | ||
+ | |||
+ | < | ||
+ | def sessionFuture := server< | ||
+ | when: sessionFuture becomes: { |session| | ||
+ | // open session with server | ||
+ | }catch: TimeoutException using: { |e| | ||
+ | // unable to open a session, do some clean-up if necessary | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | If the future is resolved, the session variable stores a leased object reference to the remote session object. | ||
+ | |||
+ | < | ||
+ | Note that specifying a catch: block for the TimeoutException is equivalent to installing a when: | ||
+ | </ | ||
+ | |||
+ | ====Importing leased object references==== | ||
+ | |||
+ | Similar to futures, leased object references have been built reflectively on top of AmbientTalk. | ||
+ | |||
+ | To use the language constructs for leased references, you should import the leasedref module as follows: | ||
+ | import / | ||
+ | |||
+ | < | ||
+ | leasedref module exports support primitives to manipulate time intervals (i.e. minutes, seconds, millisecs) so that you do not need to explicitly import the timer module. Remember to exclude those methods from the leasedref import statement if some other module has already imported them, e.g. if futures are enabled. | ||
+ | </ | ||
+ | |||
+ | More information pertaining to the API of the leased references language module can be found in the appendix. | ||
===== Garbage collecting remote references ===== | ===== Garbage collecting remote references ===== | ||
+ | |||
+ | < | ||
+ | Under Construction: | ||
+ | Update this section to explain takeOffline in the contest of unitesting to unexport remotely accessible objects. | ||
+ | </ | ||
As explained in the previous section, AmbientTalk' | As explained in the previous section, AmbientTalk' | ||
Line 104: | Line 252: | ||
< | < | ||
- | As you may have noticed, the '' | + | As you may have noticed, the '' |
</ | </ | ||
- | On the client side, taking offline an object results in a permanent disconnection of the remote references pointing to it. In other words, despite having network connection, unexporting an object renders remote far references permanently disconnected. This implies that client have to deal explicitly with unexported objects. To this end, '' | + | On the client side, taking offline an object results in a permanent disconnection of the remote references pointing to it. In other words, despite having network connection, unexporting an object renders remote far references permanently disconnected. This implies that client have to deal explicitly with unexported objects. To this end, '' |
< | < | ||
when: messenger takenOffline: | when: messenger takenOffline: | ||
- | system.println(" | + | |
- | | + | //clean certain resources associated to the buddy |
}; | }; | ||
</ | </ | ||
- | Be aware that unexporting a object will not only trigger the takenOffline observers but also the disconnected observers since the taking offline event is also considered as a logical disconnection between two devices. Unlike | + | Be aware that unexporting a object will not only trigger the takenOffline observers but also the disconnected observers since the taking offline event is also considered as a logical disconnection between two devices. Unlike |
Note that disconnection, | Note that disconnection, | ||
< | < | ||
- | The complete implementation of the instant messenger application explained along this chapter can be found in the file at/ | + | The complete implementation of the instant messenger application explained along this chapter can be found in the file '' |
</ | </ |
at/tutorial/distribution.txt · Last modified: 2009/01/30 16:13 by tvcutsem