User Tools

Site Tools


at:byexample

Key Expressions

This page lists some of AmbientTalk's most characteristic expressions, showing how the language aids the programmer in writing applications for distributed computing.

Remote Communication

Here is how to send a message to a remote object, receive a reply, and deal with the exception that the reply was not received in time:

import /.at.lang.futures;
 
when: lightbulb<-toggleLight()@Due(seconds(10)) becomes: { |reply|
  // code to execute when the message has been
  // succesfully processed.
  // reply refers to the return value of the
  // toggleLight method.
} catch: TimeoutException using: { |e|
  // code to execute when the light bulb did not
  // respond before 10 seconds
  // note: this block may be executed either because
  // the message toggleLight could not be sent or was
  // not succesfully acknowledged, or because the message
  // carrying the reply was not received, or has not yet
  // been received (missed the deadline)
}

The expression obj←msg() denotes an asynchronous message send. The @Due annotation puts a timeout on this asynchronous send.

Discovery

To make an object available to other actors in the ad hoc network, execute:

def pub := export: obj as: Type;

where obj is the object to be exported, and Type refers to a type tag by means of which the object can be discovered. To unexport the object, execute pub.cancel(). Here's how to discover the object:

def sub := when: Type discovered: { |obj|
  // code to execute upon discovery
}

Here, obj is either a far reference to the object (i.e. a remote object reference) if obj is pass-by-reference, or a copy of the object, if obj is pass-by-copy. sub refers to a subscription object. To stop looking for a Type object in the ad hoc network, invoke sub.cancel().

The above block is triggered upon discovering one object of the appropriate (sub)type. If one wants to trigger a block every time an object of the appropriate type is discovered, execute:

whenever: Type discovered: { |obj|
  // code to execute upon every discovery
}

Failure Detection

Given a far reference ref to a remote object, here's how to use AmbientTalk's built in failure detector to react to the object going offline:

def sub := when: ref disconnected: {
  // code to execute upon disconnection
}

And here is how to react to the object becoming available again:

def sub := when: ref reconnected: {
  // code to execute upon reconnection
}

In both cases, sub refers to a subscription object. Invoking sub.cancel() cancels the subscription of the block with the far reference, after which it will not be invoked anymore until the block is explicitly re-registered.

In both of the above cases, the block is fired only once. If the block must be fired every time a disconnection/reconnection occurs, use the whenever:disconnected: and whenever:reconnected: variants.

Leasing

Here's how to create a lease for an object:

import /.at.lang.leasedrefs;
 
def l := lease: minutes(10) for: obj;

Here, l is a leased reference: a proxy to obj which remains valid for at least 10 minutes. Every time a message is sent via the lease to the object, the lease gets transparently renewed. When a lease has expired, it no longer acts as a proxy for obj, allowing obj to be eventually reclaimed if no other objects refer to it. One can react to the expiration of a lease as follows:

when: l expired: {
  // code to execute upon lease expiration
}

Timing

Here's how to postpone the execution of a block of code until a certain period of time has elapsed:

import /.at.support.timer;
 
def sub := when: seconds(10) elapsed: {
  // code to execute after 10 seconds
}

Here, sub refers to a subscription object. Invoking sub.cancel() unregisters the block with the timer, such that it will not be executed in the future. If you want to repeatedly execute a block of code, write:

whenever: minutes(1) elapsed: {
  // code to execute every minute
}
at/byexample.txt · Last modified: 2009/10/08 14:11 by tvcutsem