User Tools

Site Tools


Sidebar

Jump to
AmbientTalk
CRIME
iScheme

at:tutorial:distribution

This is an old revision of the document!


Distributed Programming

This section discusses how AmbientTalk virtual machines can discover and communicate with each other over the network. The integration of distribution was one of the main concerns in the design of AmbientTalk programming model. More specifically, as a distributed programming languages that adheres to the Ambient-Oriented Programming paradigm, AmbientTalk incorporates partial failures and discovery lookup facilities at the heart of its distributed programming model. Rather than creating stubs and skeletons to manage remote communications, AmbientTalk integrates them transparently to the developer thanks to its concurrency model based on actors and far references. Far references are in fact a vital feature of the distributed model of AmbientTalk that allows the language to be able to handle the so-called volatile connections featured in mobile ad hoc networks. This section mainly explains the language abstractions to export and discover other remote objects, and handle partial failures. But first, let us start simply by showing how to enable the network functionality.

Starting the Network..

AmbientTalk provides an unique native object, named network, that responds to two methods that control the network access to an AmbientTalk virtual machine. More specifically, network.online() and network.offline() make a virtual machine go online and offline, respectively.

When the virtual machine goes online, this allows the built-in discovery lookup mechanism to export the local objects and let local objects to find other remote objects. AmbientTalk's discovery support will be further explained in the following section. Taking offline a virtual machine breaks immediately the connections with other virtual machines and thus, all remote reference between them are disconnected. This is a deliberate design choice made to facilitate the simulation of transient disconnections.

Be aware that by default the network access is shut down.

Exporting and discovering objects

AmbientTalk provides language support to make some objects available to other objects residing in remote actors by means of the export:as: construct. The export:as: construct takes as argument an object that is made remotely accessible and a service type under which the object can be discovered. For example, one exports a printing service as follows:

defstripe Printer;
def service := object: { 
	def print(aDoc) {
		system.println("printing " +aDoc);
    }
};
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 stripe. 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 stripe, 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 stripe:

defstripe ColorPrinter <: Printer;

The export:as: construct returns a publication object that responds to a cancel method that can be used to cancel the publication, i.e, unexport the object.

Discovering objects

AmbientTalk has a built-in peer-to-peer discovery lookup mechanism based on a publish-subscribe scheme that was designed to be able to discover objects in mobile ad hoc network interactions where no centralized lookup infrastructure may be available.

As previously explained, objects broadcast to the network the service types they offer using the export statement. AmbientTalk also provides language constructs to install an observer whose block of code will be triggered when a remote object of a certain service type becomes available in the network. For example, one can discover a proximate buddy of an instant messenger application by means of the when:discovered: construct as follows:

when: InstantMessenger discovered: { |messenger|
     when: (messenger<-getName()) becomes: { |name|
	buddyList.put(name, messenger);
	system.println("Added buddy: " + name);			 
     };
};

The code block to execute when the service type becomes available is parameterized with the actual remote reference to the discovered service object. In the example above, messenger is a remote reference to the remote object exporting the InstantMessenger service type. Imagine the interaction between the instant messenger applications executing the above code of two persons, e.g. Bart and Lisa. When the instant messenger of Bart and the instant messenger of Lisa come into one another's communication range, Bart will discover Lisa and Lisa will discover Bart via the InstantMessenger service type. Then, both will interchange their names and store it in their buddyList.

We are using a future to get the return value of the getName asynchrnonus message invocation. For further details about futures and the when:becomes: language construct, we refer the reader to the previous chapter on the concurrency model of AmbientTalk.

The when:discovered: observers will be triggered only once when an InstantMessenger service type becomes available in the network. In order to be able to discover all other instant messenger buddies available in the network, the whenever:discovered: construct should be used. As when:discovered, whenever:discovered takes a service type and a block of code that will be triggered when a remote object of a certain type becomes available in the network. However, the block of code specified in whenever:discovered can be fired multiple times upon discovering several exported objects.

As export:as, both constructs returns a subscription object that responds to a cancel method that can be used to cancel the subscription so that the block of code is no longer invoked. Note that objects exported by an actor do not trigger the actor's own when:discovered: nor whenever:discovered: observers.

Partial Failure Handling

Let us consider again the example instant messenger application described in previous subsection to further explain the semantics of AmbientTalk's remote object references and how they deal with transient disconnections.

When an object discovers a service type, the when observers are triggered receiving as parameter a remote far reference to the remote object discovered. As explained in previous sections, far references operates asynchronously. When a client object sends a message via a remote reference, the message is buffered in the remote far reference and the client does not even wait for the message to be delivered. This is crucial in distributed computing in order to prevent race conditions. The parameter passing in the context of distribution works similar to the inter-actor message sending semantics:

  1. Objects are always passed by far reference, except for isolate objects which are passed by copy.
  2. 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, messages are accumulate in its inbox in order to be transmitted once the reference becomes reconnected at a later point in time once the network connection is restored.

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 the reference becomes disconnected or reconnected. For example, the instant messenger application can notify the user whenever a buddy moves in and out of the communication range as follows:

when: InstantMessenger discovered: { |messenger|
 ...
	when: messenger disconnected: {
     		system.println("Buddy offline: " + name);
	};
	when: messenger reconnected: {
     		system.println("Buddy online: " + name);
	};
};

Such observers can be also installed for the inter-actor far references. Such inter-actor far references are local to a virtual machines and as such, network failures cannot happen. In that case, the disconnection observer are triggered when the object pointed to by the far reference is taken offline. In other words, when the object is removed from the export table of an actor. However, note that the reconnected observers won't be never triggered since an object unexported is subject to be eventually reclaimed by the local garbage collector.

The complete implementation of the instant messenger application explained along this chapter can be found in the file at/demo/InstantMessenger.at.
at/tutorial/distribution.1177611191.txt.gz · Last modified: 2007/04/26 20:13 (external edit)