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.

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

Only point to point links between pairs of distinct isolates are supported. Three types of Link are defined, instances of which are obtained by invoking the appropriate static factory method of this class:

With the exception of event links, all 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 (but not both).

With the exception of event links, a new Link instance cannot be used immediately after construction. It must first be passed to the other involved isolate(s). There are two mechanisms for passing Link objects to other isolates: first by encapsulation in a LinkMessage followed by transmission across an existing link using send, and second, as a member of the array of Link objects supplied to the Isolate.start method for starting a new isolate.

Unidirectional Links

The simplest type of link is a unidirectional connection from one isolate to another. Link instances of this type are obtained via invocations of the newLink static factory method.

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 {
   Link[] links = Isolate.getLinks();
   // links[0] is the command channel
   Link cmdlink = links[0];
   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) { ... }
 

Bidirectional Links

A bidirectional link can be obtained via an invocation of the newBidirectionalLink static factory method. Link instances obtained in this way support full duplex sending and receiving by both associated isolates. Semantically bidirectional links are equivalent to a pair of unidirectional links.

The following example builds on the previous one by demonstrating how a worker isolate might also return a result to its manager. This time, the worker isolate is started with a bidirectional Link instance for communication with its manager.

 public void doNextCommand() throws IOException {
   Link[] links = Isolate.getLinks();
   // links[0] is the bidirectional command/result channel
   Link cmdreslink = links[0];
   String cmd = cmdreslink.receive().getString();
   if (cmd.equals("do work")) {
     int rc  = workOnSocket(cmdreslink.receive().getSocket());
     cmdreslink.send(LinkMessage.newSerializableMessage(new Integer(rc)));
   } else if (cmd.equals("flush")) {
     flush();
   } else if (cmd.equals("quit")) {
     cleanup();
     System.exit(11);
   }
 }
 private void flush() { ... }
 private void cleanup() { ... }
 private int workOnSocket(Socket socket) { ... }
 

Event Links

Event links are for receiving IsolateEvent instances from a particular isolate by a particular isolate. As events occur in the target isolate, the appropriate 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. Instances of event Link are created either by invoking the newEventLink static factory method or by invoking Isolate.newEventLink on the source Isolate. An event link does not need to be sent to the target isolate to become active; it is active as soon as it is in the context of the receiver isolate. Additionally, while regular links are implicitly closed as soon as the remote end dies, an event link will remain open until the IsolateEvent.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.STARTING, IsolateEvent.STOPPING, and IsolateEvent.TERMINATED, and that they can only occur exactly once and in strict order.)

When an event Link instance 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.
abstract  boolean equals(Object other)
          Returns true if and only if the given Link object refers to the same link as this Link 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 able to invoke receive on this Link.
abstract  boolean isSender(java.lang.isolate.Isolate i)
          Returns true if the given Isolate is structurally able to send on this Link.
static java.lang.isolate.Link newBidirectionalLink(java.lang.isolate.Isolate left, java.lang.isolate.Isolate right)
          Creates a new two-way link between the isolates represented by the given pair of Isolate instances.
static java.lang.isolate.Link newEventLink(java.lang.isolate.Isolate sender, java.lang.isolate.Isolate receiver)
          Gets a new Link associated with an 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 one-way link between the given pair of Isolate instances.
abstract  java.lang.isolate.LinkMessage receive()
          Receives a copy of a message sent on this Link.
abstract  void send(java.lang.isolate.LinkMessage 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 one-way link between the given pair of Isolate instances. The sender and the receiver must not be equal.

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

newBidirectionalLink

public static java.lang.isolate.Link newBidirectionalLink(java.lang.isolate.Isolate left,
                                                          java.lang.isolate.Isolate right)
                                                   throws ClosedLinkException
Creates a new two-way link between the isolates represented by the given pair of Isolate instances. The sender and the receiver must not be equal.

Parameters:
left - One isolate that can communicate on this Link
right - The other isolate that can communicate on this Link
Returns:
A new Link
Throws:
IllegalArgumentException - if sender and receiver are equal
NullPointerException - if either argument is null
ResourceException - if their are insufficient resources 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
Gets a new Link associated with an Isolate, from which the given receiver Isolate can receive events. The sender and the receiver must not be equal.

If invoked before Isolate.start on the source Isolate, the event link is guaranteed to receive all events on this isolate. At a minimum, the TERMINATED event is guaranteed to be delivered on the returned Link.

A ClosedLinkException is thrown if this isolate or the receiver isolate is in the terminated state.

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:
IllegalArgumentException - if sender and receiver are equal
ResourceException - 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 able 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 IllegalStateException). 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 IllegalStateException if invoked in the given isolate.

Parameters:
i - The isolate to test to see if it can send on this Link
Returns:
true if the given isolate can potentially 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 able to invoke receive on this Link. A return value of false means that attempts by that isolate to receive on this Link will fail (by throwing IllegalStateException). 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.LinkMessage m)
                   throws ClosedLinkException,
                          LinkSerializationException
Sends the given message on this Link.

The current thread will block in this method until a receiver is available. When the sender and receiver rendezvous, the message will then be transferred. A normal return indicates that the message was transferred. If an exception occurs on the sender side, no rendezvous will occur and no object will be transferred. Even if an exception occurs on the recieve, the sender will see a successful transfer.

If the receiving isolate becomes terminated after this method is invoked but before it returns, the link will be closed, a ClosedLinkException will be thrown, any subsequent attempts to use send will result in a ClosedLinkException, and any Isolate objects corresponding to the receive side of the link will reflect a terminated state.

If invoked on a closed link, this method will throw a ClosedLinkException.

If close() is invoked on this Link while a thread is blocked in send, send will throw a ClosedLinkException. No message will have been transferred in that case.

If Thread.interrupt() is invoked on a thread that is waiting in send, the thread will not throw an InterruptedException, but the Thread.interrupted() method will return true when the thread returns from send. The message being sent will have been sent in that case. The only way to get a thread out of a blocking send is to close the link or use a non-blocking LinkChannel.

If a resource failure occurs during the transfer a ResourceException may be thrown in the sender and the object will not be sent. A transfer may succeed from the sender's point of view, but cause an independent ResourceException in the reciever. For example, if a message containing a large buffer is sent and the receiver has insufficient heap memory for the buffer or if construction of a link in the receiver isolate fails a ResourceException will be thrown in the receiver after the transfer completes.

A ClosedLinkException will be thrown if the given LinkMessage contains a closed Link, Socket, ServerSocket, Pipe.SinkChannel or Pipe.SourceChannel. No object will be transferred in this case.

A SecurityException will be thrown if the sender does not have permission to send the given type of LinkMessage. No object will be transferred in this case.

If the current isolate is not a sender on this Link, an UnsupportedOperationException will be thrown. No object will be sent in this case.

If the given LinkMessage contains a serializable object, then send may throw a LinkSerializationException if any serialization errors occur during the send. No object will be sent in this case.

Both of the checked exceptions thrown by send are subclasses of java.io.IOException.

Parameters:
m - the message to send on this Link
Throws:
ClosedLinkException - if the link is closed before or during this method invocation or if the receiving isolate is terminated
UnsupportedOperationException - if current isolate is not a sender for this Link.
NullPointerException - if m is null
ResourceException - if a resource failure occurs while transferring m to the receiver.
LinkSerializationException - if the message being sent contains a serializable object, and there is an exception during the serialization of that object.
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.{type}"), where "{type}" is the type of message being sent.

receive

public abstract java.lang.isolate.LinkMessage receive()
                                               throws ClosedLinkException
Receives a copy of a message sent on this Link.

The current thread will block in this method until a sender is available. When the sender and receiver rendezvous, the message will then be transferred. A normal return indicates that the message was received successfully. If an exception occured on the sender side, no rendezvous will occur, and no object will be transferred, the receiver will wait for the next successful send. If an exception occurs on the recieve, the sender will see a successful transfer.

This method never returns null.

If the sending isolate becomes terminated after this method is invoked but before it returns, the link will be closed, a ClosedLinkException will be thrown, any subsequent attempts to use receive will result in a ClosedLinkException, and any Isolate objects corresponding to the receive side of the link will reflect a terminated state.

If invoked on a closed Link, this method will throw a ClosedLinkException.

If close() is invoked on the link while a thread is blocked in receive, receive will throw a ClosedLinkException. No message will have been transferred in that case.

If Thread.interrupt() is invoked on a thread that is waiting in receive, the thread will not throw an InterruptedException, but the Thread.interrupted() method will return true when the thread gets a message and returns from the receive. The only way to get a thread out of a blocking receive without waiting to complete a receive is to close the link or use a non-blocking LinkChannel.

If a resource failure occurs due to the object being transferred between isolates a ResourceException may be thrown in the receiver. For example, if a message containing a large buffer is sent and the receiver has insufficient heap memory for the buffer or if construction of a link in the receiver isolate fails a ResourceException will be thrown. The sender will see a successful transfer in these cases.

A SecurityException will be thrown if the receiver does not have permission to receive the received type of LinkMessage. The sender will see a successful transfer in this case.

If the current isolate is not a receiver on this Link an UnsupportedOperationException will be thrown. The receiver will not rendezvous with a sender in this case.

Returns:
A LinkMessage containing the message from the sender
Throws:
ClosedLinkException - if the sending isolate becomes terminated or the link is closed
UnsupportedOperationException - if the current isolate is not allowed to receive on this Link
ResourceException - if a resource failure occurs while transferring o to the receiver
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

isOpen

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

For non-event 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 Links is open from the point of its creation until the earliest of its receiving isolate closing it, or its receiving isolate terminating, or the receipt of the IsolateEvent.TERMINATED event.

Throws UnsupportedOperationException if the invoking isolate is neither a sender nor a receiver.

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 on both sides, or both sides will 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 the link. The only differences are the local-side blocking and selection semantics.

Returns:
the associated LinkChannel
Throws:
IllegalStateException - if the link is closed

equals

public abstract boolean equals(Object other)
Returns true if and only if the given Link object refers to the same link as this Link object.

Parameters:
other - Link to compare this with
Returns:
true if this Link is the same as the other Link