This package implements remote event passing (REP).


Class Summary
AnnounceEvent Implementation of an announce event.
BenchmarkREP This class performs remote event passing benchmarks.
BenchmarkREPEcho Implements the echo server required for a latency benchmark for remote event passing.
BenchmarkREPLatency Performs the latency benchmark for remote event passing.
BenchmarkREPReceiver Performs the receiver side of a throughput benchmark for remote event passing.
BenchmarkREPSender Performs the sender side of a throughput benchmark for the REP component.
DiscoveredResource Implementation of a discovered resource.
DiscoveryClient A client for service discovery.
DiscoveryServer A service discovery server.
ElectionEvent An event to perform
ElectionManager A component to perform discovery server elections.
LocalizedResource A localized resource is a resource that is associated with a particular host and port number.
NamedResource Implementation of a name for a remote event handler.
RemoteDescriptor Implementation of a remote export descriptor.
RemoteEvent Implements a remote event, an event which is to be delivered to a remote host.
RemoteManager A manager for remote event passing.
RemoteReference Implementation of a reference to a remote event handler.
ResolutionRequest A request to resolve a SymbolicHandler.
ResolutionResponse Implements the result of a resolution.
TestREP Regression tests for RemoteManager.

Exception Summary
AlreadyBoundException Implementation of a already bound exception.
ConnectionFailedException Implementation of a connection failed exception.

Package Description

This package implements remote event passing (REP). REP allows events to be sent to event handlers on remote hosts. To become remotely accessible, an event handler must handle remote events and remotely export itself via a binding request. Event handlers must also be exported if they wish to send remote events and receive responses.

Two kinds of remote resources are used to refer to event handlers on remote hosts: DiscoveredResource and LocalizedResource. Both descend from SymbolicHandler and do not directly handle events. Discovered resources are named by some query describing the desired attributes of the resource, and are located by the discovery service if one is available. Localized resources are located with a RemoteManager running on a particular machine and a particular port. LocalizedResource is an abstract class with two subclasses: NamedResource and RemoteReference. The actual event handler which is bound to a named resource may change over time, but remote references always refer uniquely to a single event handler.

The following three event types are handled by the request handler of an Environment or RemoteManager.

  1. BindingRequests are used to export event handlers. The descriptor for the binding request should be an RemoteDescriptor. If the operation is successful, the resulting BindingResponse will contain a RemoteReference that refers uniquely to the newly exported event handler. The operation may fail with a AlreadyBoundException.

  2. RemoteEvents are used to send events to a remote event handler. A failure may be indicated with an UnknownResourceException or a ConnectionFailedException.

  3. ResolutionRequests are used to resolve remote resources to specific remote references. If resolution is successful, the response will be a ResolutionResponse. Otherwise, the result will be an UnknownResourceException or a ConnectionFailedException.

    Because resolution may require communication with a remote host, the source of a ResolutionRequest must be a RemoteReference in order to receive a result. An InvalidTupleException will be returned if this is not the case.

AbstractHandler and IOUtilities provide several utility methods that are useful in exporting event handlers and sending remote events.


In these examples, handler is an EventHandler and requestHandler is the Environment's request handler.

Exporting an event handler:

// Construct an export descriptor with a name as the 
// event handler descriptor.
RemoteDescriptor descriptor = new RemoteDescriptor(handler, "name");

// Construct the binding request.
Event request =
    new BindingRequest(null, null, descriptor, 60*1000);

// Use synchronous invokation to send the request.
Event response = Synchronous.invoke(requestHandler, request);

if (response instanceof BindingResponse) {
  // The event handler was successfully exported.  
  // Extract the lease and the remote reference.
  BindingResponse br = (BindingResponse)response;
  EventHandler lease =;
  RemoteReference handlerReference = (RemoteReference)br.resource;

} else if (response instanceof ExceptionalEvent) {
  if (((ExceptionalEvent)response).x instanceof AlreadyBoundException) {
    // The desired name is already in use by someone else.

} else {
  // The event handler was not successfully exported.

After exporting the event handler, it can be refered to with the descriptor NamedDescriptor("hostname", Constants.REP_PORT, "name") as well as with the RemoteReference returned in the binding response.

Sending a remote event:

// A remote reference to the sending event handler should be stored here
// after exporting the event handler.
RemoteReference myReference = ...;

// Construct a remote resource for the destination.
NamedResource destination = 
    new NamedResource("hostname", Constants.REP_PORT, "name");

// Construct the event we wish to send.  The source of the event (and all
// other event handlers in the event) must be remote resources.
Event nestedEvent = 
    new DynamicTuple(myReference, "Hello world!");

// Construct the remote event.
RemoteEvent remoteEvent =
    new RemoteEvent(this, null, destination, nestedEvent);

// Invoke the environment's request handler on the event.

Handling a remote event:

class MyHandler extends AbstractHandler {
   * A remote reference to this event handler, obtained by exporting it.
  RemoteReference myReference;


  protected boolean handle1(Event e) {
    if (e instanceof RemoteEvent) {

      // Extract the nested event.
      Event nestedEvent = ((RemoteEvent)e).event;

      // Extract the nested event source.
      SymbolicHandler source = (SymbolicHandler)nestedEvent.source;
      // Generate a response to the nested event.
      Event response = ...;

      // Send the response to the nested event, via the environment's
      // request handler.
          new RemoteEvent(this, null, source, response)):

      return true;
    return false;

See RemoteReceiver and RemoteSender for a simple example application.


(C) Copyright 2001 UW CSE