java.lang.isolate
Class Link

java.lang.Object
  |
  +--java.lang.isolate.Link

public abstract class Link
extends Object

A Link supports communication between isolates. Different implementations of Link may differ in both topology and in underlying IO mechanics. However, all kinds of link objects support at least one sender and at least one receiver and the rendezvous point between the sender and receiver constitutes the unique identity of a link within an isolate aggregate. Each construction of a link defines a distinct rendezvous point. When a link is copied the rendezvous points of the original and copied link objects are the same.

By convention, capitalization is used to distinguish a Link class or class instance from a reference to the link abstraction.

Only point to point links between pairs of isolates are supported. Two types of Link are defined, application links and event links, instances of which are obtained by invoking the appropriate static factory method of this class.

Application Links

Application links represent a unidirectional application-level communication channel between a pair of isolates. Instances of this type of Link are obtained via invocations of the newLink static factory method.

All application link communication is synchronous and unbuffered and requires sender and receiver to rendezvous before either the send or receive methods will complete. As such, successful communication provides a form of inter-isolate synchronization. The LinkChannel class provides nonblocking behavior for either sender or receiver.

A new application Link instance cannot be used immediately after construction. It must first be passed to the involved isolates by wrapping it in an IsolateMessage and either sending it across an existing link using send, or passing it to Isolate.start. If the link creation is performed by one of the involved isolates, then the link is implicitly passed to the creator.

The following example demonstrates how a worker isolate might receive "work" from a manager isolate. This code assumes the isolate is started with a Link instance for receiving commands from its manager. Commands consist of a String followed by a Socket if the command is "do work." (The manager isolate code is not shown.)

 public void doNextCommand() throws IOException {
   IsolateMessage[] isolateMessages = Isolate.currentIsolateStartMessages();
   // isolateMessages[0] is the command channel
   Link cmdlink = isolateMessages[0].getLink();
   String cmd = cmdlink.receive().getString();
   if (cmd.equals("do work")) {
     workOnSocket(cmdlink.receive().getSocket());
   } else if (cmd.equals("flush")) {
     flush();
   } else if (cmd.equals("quit")) {
     cleanup();
     System.exit(11);
   }
 }
 private void flush() { ... }
 private void cleanup() { ... }
 private void workOnSocket(Socket socket) { ... }
 

A link may be established between a pair of isolates which have already been started by creating a new Link and passing it to the involved isolates over a pre-existing link. The following example illustrates a manager isolate creating a new link between two started isolates,

 Link worker1To2 = Link.newLink(worker1, worker2);
 IsolateMessage linkMessage = IsolateMessage.newLinkMessage(newLink);

 // pass the new link to worker1 over an existing link
 managerToWorker1.send(linkMessage);

 // pass the new link to worker2 over an existing link
 managerToWorker2.send(linkMessage);
 

Communication across the new link can proceed once both worker isolates have received the new link from their pre-existing link with the manager. For example, in the first worker isolate,

 Link worker1To2 = managerToWorker1.receive().getLink();
 worker1To2.send(IsolateMessage.newStringMessage("HELLO"));
 

and in the second,

 Link worker1To2 = managerToWorker2.receive().getLink();
 String fromWorker1 = worker1To2.receive().getString();
 

Bidirectional communication can be achieved by using a pair of unidirectional links with the endpoint Isolate reversed. To avoid the establishment of such pairs requiring two rendezvous with each participating isolate, the two links may be wrapped in a composite message and passed with a single send,

 Link worker1to2 = Link.newLink(worker1, worker2);
 Link worker2to1 = Link.newLink(worker2, worker1);
 IsolateMessage linkPairMessage =
   IsolateMessage.newCompositeMessage(
     IsolateMessage.newLinkMessage(worker1to2),
     IsolateMessage.newLinkMessage(worker2to1));

 // pass the new links to worker1 over an existing link
 managerToWorker1.send(linkPairMessage);

 // pass the new links to worker2 over an existing link
 managerToWorker2.send(linkPairMessage);
 

which corresponds to the following in the first worker isolate,

 IsolateMessage[] messages = managerToWorker1.receive().getComposite();
 Link worker1To2 = messages[0].getLink();
 Link worker2To1 = messages[1].getLink();

 worker1To2.send(IsolateMessage.newStringMessage("HELLO"));
 String fromWorker2 = worker2To1.receive().getString();
 

and the following in the second worker isolate,

 IsolateMessage[] messages = managerToWorker2.receive().getComposite();
 Link worker1To2 = messages[0].getLink();
 Link worker2To1 = messages[1].getLink();

 String fromWorker1 = worker1To2.receive().getString();
 worker2To1.send(IsolateMessage.newStringMessage("ACK"));
 

Application links may be closed explicitly by their endpoints. They might also be closed implicitly under the following circumstances,

Once closed, no further communication across the link is possible, and any attempts to invoke send or receive will result in a ClosedLinkException being thrown.

Applications which wish to allow an isolate to signal to its peer that it has no further messages to send across a given link and intends to close that link should arrange for the sending isolate to send a message indicating that intent, and for the receiving isolate to react appropriately. For example, a sender could indicate impending closure as follows,

 link.send(NoMoreMessages.getInstance());  // NoMoreMessages is a serializable singleton
 link.close();
 

which would correspond to the following receiver behavior,

 Object o = link.receive().getSerializable();
 if(o != NoMoreMessages.getInstance())
   // handle ordinary message
 else
   // sender has closed the link
 

Event Links

Event links are for receiving system-provided IsolateEvent instances from a particular isolate by a particular isolate. As events occur in the target isolate, a corresponding IsolateEvent object will be created and be receivable on every event link associated with that isolate. Invocations of send will throw an UnsupportedOperationException. The only objects received on an event link will be instances of IsolateEvent.

Event links are created either by invoking the newEventLink static factory method or by invoking Isolate.newEventLink on the source Isolate. An event link is implicitly connected to the target isolate, and does not need to be sent to become active. Additionally, while regular links are implicitly closed as soon as the remote end dies, an event link will remain open until the IsolateEvent.Type.TERMINATED event is received, at which point the event link will implicitly close.

Unlike non-event links, the sending isolate will not block until rendezvous with a thread in receive. IsolateEvent instances will be buffered in the event link until received, with the restriction that events will always be received in the order they arrived, regardless of buffering. (Note that there are only three possible events, IsolateEvent.Type.STARTING, IsolateEvent.Type.EXITING, and IsolateEvent.Type.TERMINATED, and that they can only occur exactly once and in strict order. Note also that the exactly once semantic is independent of the number of threads within an isolate attempting to receive an event.)

When an event link is sent through another link, any events that may have been sent and implicitly buffered in the event link will not be copied along with the event Link instance. To avoid race conditions on receiving events, an event Link instance should be delivered to all interested isolates before the source isolate is started.

Since:
1.5

Method Summary
abstract  void close()
          Closes this link, disabling both sending and receiving on this Link.
 boolean equals(Object obj)
          Tests this Link for equality with the given object.
abstract  LinkChannel getChannel()
           Returns the unique LinkChannel associated with this Link.
abstract  boolean isOpen()
          Tests to see if this Link is open.
abstract  boolean isReceiver(java.lang.isolate.Isolate i)
          Returns true if the given Isolate is structurally allowed to receive on this Link.
abstract  boolean isSender(java.lang.isolate.Isolate i)
          Returns true if the given Isolate is structurally allowed to send on this Link.
static java.lang.isolate.Link newEventLink(java.lang.isolate.Isolate sender, java.lang.isolate.Isolate receiver)
          Create a new event link associated with the given Isolate, from which the given receiver Isolate can receive events.
static java.lang.isolate.Link newLink(java.lang.isolate.Isolate sender, java.lang.isolate.Isolate receiver)
          Creates a new application link between the given pair of Isolate instances.
abstract  java.lang.isolate.IsolateMessage receive()
          Receives a message from this link.
abstract  void send(java.lang.isolate.IsolateMessage m)
          Sends the given message on this link.
 
Methods inherited from class java.lang.Object
getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

newLink

public static java.lang.isolate.Link newLink(java.lang.isolate.Isolate sender,
                                             java.lang.isolate.Isolate receiver)
                                      throws ClosedLinkException
Creates a new application link between the given pair of Isolate instances.

Parameters:
sender - The isolate that will send
receiver - The isolate that will receive
Returns:
A new Link instance
Throws:
NullPointerException - if either argument is null
IsolateResourceError - if insufficient resources are available to allocate the link
ClosedLinkException - if either isolate is in the terminated state

newEventLink

public static java.lang.isolate.Link newEventLink(java.lang.isolate.Isolate sender,
                                                  java.lang.isolate.Isolate receiver)
                                           throws ClosedLinkException
Create a new event link associated with the given Isolate, from which the given receiver Isolate can receive events.

If invoked before Isolate.start on the source Isolate, the event link is guaranteed to receive all events on that isolate. If the associated isolate eventually terminates it is guaranteed that a TERMINATED event will be delivered on the returned Link.

Parameters:
sender - The isolate that will send events
receiver - The isolate that will receive events
Returns:
a new Link associated with the sender isolate
Throws:
NullPointerException - if either argument is null
IsolateResourceError - if there are insufficient resources to allocate the link
ClosedLinkException - if either isolate is in the terminated state

isSender

public abstract boolean isSender(java.lang.isolate.Isolate i)
Returns true if the given Isolate is structurally allowed to send on this Link. A return value of false means that attempts by that isolate to send on this Link will always fail (by throwing an UnsupportedOperationException). A return value of true is an indication that an attempt by that isolate to send may succeed. However, such attempts may still fail due to other failures or concurrent interference.

A return value of false indicates that the isOpen and close methods on this Link will also fail with an UnsupportedOperationException if invoked in the given isolate. This method will always return false for a link created via newEventLink.

Parameters:
i - The isolate to test to see if it can send on this Link
Returns:
true if the given isolate can structurally send on this Link
Throws:
NullPointerException - if i is null

isReceiver

public abstract boolean isReceiver(java.lang.isolate.Isolate i)
Returns true if the given Isolate is structurally allowed to receive on this Link. A return value of false means that attempts by that isolate to receive on this Link will fail (by throwing UnsupportedOperationException). A return value of true is an indication that an attempt by that isolate to receive may succeed. However, such attempts may still fail due to other failures or concurrent interference.

Parameters:
i - The isolate to test to see if it can receive on this Link
Returns:
true if the given isolate can potentially receive on this Link
Throws:
NullPointerException - if i is null

send

public abstract void send(java.lang.isolate.IsolateMessage m)
                   throws IOException
Sends the given message on this link.

The current thread will block in this method until a receiver reaches the rendezvous point. When the sender and receiver rendezvous, the message will be transferred. A normal return indicates that the message was sent but is not an absolute guarantee that the corresponding receive returned normally. If a receive terminates early due to an UnsupportedOperationException or IllegalBlockingModeException there is no effect on a send in progress on the same link as the receiver never reached the rendezvous point.

This method is threadsafe. If multiple threads invoke this method on the same object concurrently their access to the rendezvous point will be arbitrarily serialized by the implementation. Consequently each successful sender-side rendezvous and message transfer corresponds to exactly one successful receive.

If this link is closed, implicitly or explicitly, either before or during an invocation of send then the invocation will terminate by throwing a ClosedLinkException.

If close is invoked on this Link object while another thread in the same isolate is blocked in send the invocation will terminate by throwing a ClosedLinkException. On platforms which support java.nio this exception will have an AsynchronousCloseException as its cause. Similarly, if Thread.interrupt is invoked on a thread that is blocked in send a ClosedLinkException will also be thrown, and on platforms which support java.nio have a ClosedByInterruptException as its cause. Finer-grained control of blocking behavior may be obtained by using a LinkChannel in preference to a Link.

If the given IsolateMessage contains a serializable object then serialization of that object will occur during the invocation of this method. If any errors occur during serialization a LinkSerializationException will be thrown and rendezvous will not occur. Note that if the given message is a composite message and it contains one or more serializable message components then any serialization error occurring during the sending of one of those components will cause the send of the entire composite to fail with a LinkSerializationException. In this case rendezvous will not occur, however if the composite message contained more than one serializable message the visible side-effects of the serialization of one or more of them might have occurred.

If a SecurityManager is present it will be consulted to see if the appropriate send permission is granted (see IsolatePermission for a list of permissions), unless the message is a composite message in which case each component of the composite will be checked.

If the current isolate is not a sender on this Link, an UnsupportedOperationException will be thrown and rendezvous will not occur. As send operations with event links are done by the implementation an attempt to use this method with a link created by newEventLink will also result in an UnsupportedOperationException.

Although the m parameter is a reference to an IsolateMessage, copy semantics are provided with the send and its corresponding receive, even when the Link source and destination are the same isolate.

Parameters:
m - the message to send on this Link
Throws:
ClosedLinkException - if the link is closed explicitly or implicitly, either before or during this method invocation.
UnsupportedOperationException - if current isolate is not a sender for this Link.
NullPointerException - if the message is null
IsolateResourceError - if a resource failure occurs while preparing the message for transfer.
LinkSerializationException - if the message contains a serializable object, and an error occurs during serialization.
IllegalBlockingModeException - if send is invoked when the associated LinkChannel for this Link has been placed in non-blocking mode.
SecurityException - if a SecurityManager is present and it denies IsolatePermission("send.{mtype}"), where "{mtype}" is the type of message being sent.
IOException

receive

public abstract java.lang.isolate.IsolateMessage receive()
                                                  throws IOException
Receives a message from this link.

The current thread will block in this method until a sender reaches the rendezvous point. When the receiver and sender rendezvous, a message will be transferred. A normal return indicates that the message was received but is not an absolute guarantee that the corresponding send returned normally. If a send terminates early due to a SecurityException, UnsupportedOperationException or IllegalBlockingModeException the sender will not have been considered to have reached the rendezvous point, and the receiver will continue to block waiting for a subsequent successful send.

This method is threadsafe. If multiple threads invoke this method on the same object concurrently their access to the rendezvous point will be arbitrarily serialized by the implementation. Consequently each successful receiver-side rendezvous and message transfer corresponds to exactly one successful send.

If this link is closed, implicitly or explicitly, either before or during an invocation of receive then the invocation will terminate by throwing a ClosedLinkException.

If close is invoked on this Link object while another thread in the same isolate is blocked in receive the invocation will terminate by throwing a ClosedLinkException. On platforms which support java.nio this exception will have an AsynchronousCloseException as its cause. Similarly, if Thread.interrupt is invoked on a thread that is blocked in send a ClosedLinkException will also be thrown, and on platforms which support java.nio have a ClosedByInterruptException as its cause. Finer-grained control of blocking behavior may be obtained by using a LinkChannel in preference to a Link.

If a SecurityManager is present it will be consulted to see if the appropriate receive permission is granted (see IsolatePermission for a list of permissions), unless the message is a composite message in which case each component of the composite will be checked.

If the current isolate is not a receiver on this Link an UnsupportedOperationException will be thrown and rendezvous will not occur.

This method never returns null.

Returns:
An IsolateMessage containing the message from the sender
Throws:
ClosedLinkException - if the link is closed explicitly or implicitly, either before or during this method invocation.
UnsupportedOperationException - if the current isolate is not a receiver for this Link
IsolateResourceError - if a resource failure occurs while receiving a message.
IllegalBlockingModeException - if receive is invoked when the associated LinkChannel for this Link has been placed in non-blocking mode
SecurityException - if a SecurityManager is present and it denies IsolatePermission("receive.{type}"), where "{type}" is the type of message being received
IOException

isOpen

public abstract boolean isOpen()
Tests to see if this Link is open.

For application links, a Link is open from the point of its creation until the earliest of at least one of its associated isolates closing it, or at least one of its associated Isolates terminating.

An event link is open from the point of its creation until the earliest of its receiving isolate closing it, its receiving isolate terminating, or the receipt of the TERMINATED event.

This method throws an UnsupportedOperationException if the invoking isolate is neither a sender nor a receiver on this link.

Returns:
true if the openness conditions are satisfied, false otherwise
Throws:
UnsupportedOperationException - if the current isolate is neither a sender nor a receiver for this Link

close

public abstract void close()
Closes this link, disabling both sending and receiving on this Link. Invocations of send or receive on a closed Link will result in a ClosedLinkException. For any send or receive methods that are active in other threads when close is invoked, those methods will either complete successfully or see a ClosedLinkException.

If the invoking isolate is neither a sender nor a receiver on this Link, an UnsupportedOperationException will be thrown, and the link will not be closed.

If this link is already closed or is in the process of closing, invoking this method will have no effect.

Throws:
UnsupportedOperationException - if the current isolate is neither a sender nor a receiver for this Link

getChannel

public abstract LinkChannel getChannel()
Returns the unique LinkChannel associated with this Link.

Sending or receiving on the returned LinkChannel is indistinguishable on the remote side from sending or receiving on this Link. The only differences are the local-side blocking and selection semantics.

Closing the LinkChannel will close the Link, and vice-versa.

Returns:
the associated LinkChannel
Throws:
ClosedChannelException - if the LinkChannel's channel is closed
This API element may not be present in some J2ME profiles.

equals

public boolean equals(Object obj)
Tests this Link for equality with the given object. Returns true if and only if obj is not null and denotes the same link as this, with respect to the rendezvous point.

Overrides:
equals in class Object
Parameters:
obj - The object to be compared
Returns:
true if the objects are the same; false otherwise