java.lang.isolate
Class IsolateMessageDispatcher

java.lang.Object
  |
  +--java.lang.isolate.IsolateMessageDispatcher
All Implemented Interfaces:
Runnable

public final class IsolateMessageDispatcher
extends Object
implements Runnable

Receives and dispatches messages to listeners.

IsolateMessageDispatcher is a utility class allowing IsolateMessages to be delivered to application code asynchronously via a listener interface as an alternative to being read directly from a Link. The dispatcher assumes ownership of the Link, until it is removed, closed, or the dispatcher is shut down.

Adding a Link to an IsolateMessageDispatcher does not change the rendezvous semantics of the link (the rendezvous occurs immediately prior to the message being dispatched to the listener).

The following is a simple usage scenario illustrating asynchronous delivery of IsolateEvents:

  class IsolateEventListener
    implements IsolateMessageDispatcher.Listener {
    public void messageReceived(IsolateMessageDispatcher d, Link l, IsolateMessage m) {
      IsolateEvent e = m.getEvent();
      System.err.println("State change: Isolate "+e.getIsolate()+" Type "+e.getType());
    }
    public void receiveFailed(Throwable thr, IsolateMessageDispatcher disp, Link l) {
      System.err.println("Link " +l+ " failed:");
      thr.printStackTrace(System.err);
    }
  }

  IsolateMessageDispatcher d = new IsolateMessageDispatcher();
  new Thread(d).start();
  d.add(someIsolate.newEventLink(), new IsolateEventListener());
 

Conceptually, a IsolateMessageDispatcher maintains an internal set of <LinkIsolateMessageDispatcher.Listener> pairs, and for each pair which is a member of that set, delivers messages received from the link element of that pair to the listener element. Consequently, it is possible to associate a given link with more than one listener, and conversely, to associate more than one link with a given listener. To illustrate the first case,

   d.add(link, firstListener);
   d.add(link, secondListener);
 

will cause messages received from link to be delivered to both firstListener and secondListener. To illustrate the second,

   d.add(firstLink, listener);
   d.add(secondLink, listener);
 

will cause messages from both firstLink and secondLink to be delivered to listener. In this case, the listener may use the Link argument of its messageReceived method to determine the source.

Additionally, it is permissible to add a Listener to more than one IsolateMessageDispatcher. However, if a single Link is added to more than one IsolateMessageDispatcher, any messages received on the Link will be delivered via exactly one Listener.

The add, remove and shutdown methods are all reentrant and may be invoked by a listener callback.

There are no guarantees of the order in which listeners will be invoked.

In more complex scenarios, it might be desirable for application code to establish thread-specific state for the listener methods, which will be invoked by the thread executing a dispatcher's receive/dispatch cycle. For example,

  class ThreadWithContext extends Thread {
    ThreadWithContext(Runnable r) {
      super(r);
    }

    public void start() {
      // Establish arbitrary thread-specific context for
      // listener callbacks from this dispatcher ...
      ClassLoader someClassLoader = ...;

      setContextClassLoader(someClassLoader);

      super.start();
    }
  }

  class ContextDependentListener
    implements IsolateMessageDispatcher.Listener {
    public void messageReceived(IsolateMessageDispatcher d, Link l, IsolateMessage m) {
      // This callback is invoked within the context established in
      // ThreadWithContext.start(), hence classes accessible via
      // someClassLoader are available here.
    }
    public void receiveFailed(Throwable thr, IsolateMessageDispatcher disp, Link l) {
    }
  }

  IsolateMessageDispatcher d = new IsolateMessageDispatcher()
  new ThreadWithContext(d).start();
  d.add(someLink, new ContextDependentListener());
 

Since:
1.5
See Also:
Link, IsolateMessage

Nested Class Summary
static interface IsolateMessageDispatcher.Listener
          A listener interface for receiving messages and exceptions from an IsolateMessageDispatcher's managed links.
 
Constructor Summary
IsolateMessageDispatcher()
          Creates a new IsolateMessageDispatcher.
 
Method Summary
 void add(java.lang.isolate.Link link, IsolateMessageDispatcher.Listener listener)
          Adds the supplied link to the set of links for which this dispatcher is dispatching messages and associates it with the supplied listener.
 void remove(java.lang.isolate.Link link)
          Removes the supplied link from the set of links for which this dispatcher dispatches messages.
 void run()
          Starts this dispatcher.
 void shutdown()
          Shuts down this dispatcher.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

IsolateMessageDispatcher

public IsolateMessageDispatcher()
Creates a new IsolateMessageDispatcher.

Method Detail

add

public void add(java.lang.isolate.Link link,
                IsolateMessageDispatcher.Listener listener)
Adds the supplied link to the set of links for which this dispatcher is dispatching messages and associates it with the supplied listener.

Messages received on the link will be delivered by invoking the listener's messageReceived method.

If an exception occurs when receiving messages from the link (e.g., due to the link having been closed, or a security exception), the Link will be implicitly removed from this dispatcher's set of managed links and then the receiveFailed method will be invoked for every previously registered listener. (The listener may add itself and the Link back to this dispatcher if the error condition was temporary.)

The link becomes the property of the IsolateMessageDispatcher and may not be used by application code after being passed to add except for a subsequent remove or to close the link. For example, implementations of IsolateMessageDispatcher may use a non-blocking LinkChannel associated with the link, and thus the send and receive methods may throw an IllegalBlockingModeException.

If a dispatcher has terminated (its run method has returned to the caller) this method is ignored and no exception is thrown. If a given Link and Listener pair has already been passed with this method the redundant invocation is also ignored.

If the current isolate is not a valid receiver for the given Link, an IllegalArgumentException will be thrown and the link will not be registered.

Parameters:
link - The Link to add
listener - The listener to which messages from the supplied Link will be delivered
Throws:
NullPointerException - if either parameter is null
IllegalArgumentException - if the current isolate cannot receive on link

remove

public void remove(java.lang.isolate.Link link)
Removes the supplied link from the set of links for which this dispatcher dispatches messages.

No further messages will be received by this dispatcher from the link, and no further messages will be delivered to any associated listener. If this method is invoked in the context of a Listener.messageReceived method invoked by this dispatcher, on the given link, the current message will be delivered to any other registered listeners, only future messages will not be received or dispatched.

No exception is thrown if the link is not in the set of managed links for this dispatcher. The link is reset to the blocking state it had when it was added to this dispatcher.

If a dispatcher has terminated (its run method has returned to the caller) this method is ignored and no exception is thrown.

Parameters:
link - The Link to remove
Throws:
NullPointerException - if link parameter is null

run

public void run()
Starts this dispatcher. This method may be invoked no more than once; subsequent invocations will cause an IllegalStateException to be thrown.

During the execution of this method, this dispatcher will receive messages from the links registered with it and dispatch them to their associated listeners.

This method will only return following an invocation of the shutdown method, or if a run-time exception is thrown by a listener. In both cases the managed links will be returned to their pre-add state (as if remove had been invoked on each one).

Specified by:
run in interface Runnable
Throws:
IllegalStateException - if a thread is already servicing this IsolateMessageDispatcher.

shutdown

public void shutdown()
Shuts down this dispatcher.

Following the invocation of this method, this dispatcher will cease receiving messages from the links registered with it and dispatching them to their associated listeners. The invocation of run which started this dispatcher will then return normally, typically leading to the termination of the thread in which run was invoked.

If invoked from a listener associated with this dispatcher, the dispatcher will cease as soon as the listener's messageReceived method returns, and no other listeners will be invoked for this or other messages. Any available messages which had not been passed to a listener will be available directly from the Link (i.e., no messages can be lost due to a shutdown invocation).