java.lang.isolate
Class LinkMessageDispatcher

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

public final class LinkMessageDispatcher
extends Object
implements Runnable

Receives and dispatches messages to listeners.

LinkMessageDispatcher is a utility class allowing LinkMessages to be delivered to application code asynchronously via a listener interface as an alternative to being read directly from a Link.

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

  class IsolateEventListener
    implements LinkMessageDispatcher.Listener {
    public void messageReceived(Link l, LinkMessage m) {
      IsolateEvent e = m.getEvent();
      System.err.println("State change: Isolate "+e.getIsolate()+" Type "+e.getType());
    }
  }

  LinkMessageDispatcher d = new LinkMessageDispatcher();
  new Thread(d).start();

  d.add(someIsolate.newEventLink(Isolate.currentIsolate(), new IsolateEventListener());
 

Conceptually, a LinkMessageDispatcher maintains an internal set of <Link, LinkMessageDispatcher.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.

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 ...

      setContextClassLoader(someClassLoader);

      super.start();
    }
  }

  class ContextDependentListener
    implements LinkMessageListener {
    public void messageReceived(Link l, LinkMessage m) {
      // This callback is invoked within the context established in
      // ThreadWithContext.start(), hence classes accessible via
      // someClassLoader are available here.
    }
  }


  LinkMessageDispatcher d = new LinkMessageDispatcher();
  new ThreadWithContext(d).start();

  d.add(someLink, new ContextDependentListener());
 
If a single Link is added to more than one LinkMessageDispatcher, any messages received on the Link will be delivered to exactly one LinkMessageListener.

Since:
1.5
See Also:
Link, LinkMessage

Nested Class Summary
static interface LinkMessageDispatcher.Listener
          A listener interface for receiving messages on a Link.
 
Constructor Summary
LinkMessageDispatcher()
          Creates a new LinkMessageDispatcher.
 
Method Summary
 void add(java.lang.isolate.Link link, LinkMessageDispatcher.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 stop()
          Stops this dispatcher.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

LinkMessageDispatcher

public LinkMessageDispatcher()
Creates a new LinkMessageDispatcher.

Method Detail

add

public void add(java.lang.isolate.Link link,
                LinkMessageDispatcher.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 to the listener.

The link should be considered property of the LinkMessageReceiver and not used by application code after being passed to add (except to pass to remove). In particular, implementations of LinkMessageReceiver may use a non-blocking LinkChannel associated with the link, and thus the send and receive methods may throw an IllegalBlockingModeException.

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

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.

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.

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 stop() method.

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

stop

public void stop()
Stops 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.