8.3. The Notification API

As we've already seen, several classes and interfaces play key roles in space-based distributed events, and we are going to examine the details of each in this section. Here is a brief overview:

  • JavaSpace. Objects can register to be notified of new entries appearing in a space by calling the JavaSpace interface's notify method and supplying a template. The space will generate an event whenever an entry is written that matches the template.

  • EventRegistration. When an object calls the JavaSpace interface's notify method, an EventRegistration object is returned. This object contains information about the registration, such as its lease time and a starting sequence number for events.

  • RemoteEventListener. Any object that wishes to receive remote events from a space must implement the RemoteEventListener interface. This interface consists of one method, notify, that a space calls to deliver remote events to the object.

  • RemoteEvent. A space passes a RemoteEvent object to the remote event listener's notify method when a space-based event occurs. This object contains details about the event, including its source and sequence number.

Now let's step through the details of each of these components.

8.3.1. The JavaSpace notify Method

The JavaSpace interface provides a notify method that is called to register interest in the arrival of entries into a space. Here is the method's signature from the JavaSpaces Specification:

EventRegistration notify(Entry tmpl,
               Transaction txn,
               RemoteEventListener listener,
               long lease,
               MarshalledObject handback)
  throws RemoteException, TransactionException;

The notify method takes five parameters and returns an EventRegistration object. The first parameter is an entry that acts as a template. As entries are added to the space, they are matched against this template (as well as all other registered templates), using the same matching rules as for read and take (see Section 2.4.3). If a match occurs, then a remote event is sent to the specified listener.

The second parameter to notify is a transaction. For now we will continue to supply a null transaction; we'll return to the topic of transactions in Chapter 9.

The third parameter is a listener that implements the RemoteEventListener interface. This is the object that receives remote events from the space. Since this object is a “remote” event listener it can be an object that exists locally or remotely on another JVM (even within a non-space-based program). We will describe the RemoteEventListener interface shortly (however, as we have seen, it contains only the notify method).

The next parameter is a lease time, which is a requested upper bound on the length of time the space should remember the registration. The syntax and semantics of leases are the same as those returned by the write method (as we saw in the last chapter). Lease times are requested in milliseconds and the space itself determines the actual length of the lease that it is willing to grant (as we will see, the lease object is returned as part of the EventRegistration). We can let the lease run its course, or we can use the lease object to cancel or renew the lease. Once the lease expires or is cancelled, the listener will no longer receive notifications.

The last parameter is a MarshalledObject called a “handback.” A handback is an object that the space will pass back to the remote event listener as part of an event notification; it is a wrapper around a serialized object. The space itself never instantiates the handback as an object; it simply keeps it around in serialized form and treats it as a byte array. When the remote event listener receives a handback as part of the event sent by the space, it can unpack the object and instantiate it.

Finally, the notify method can throw two exceptions: TransactionException and RemoteException. A TransactionException will be thrown when there is a problem with a non-null transaction parameter—for instance, if the transaction is unknown or has expired. As with other space-based operations, a RemoteException is thrown when communication problems occur between the object calling notify and the space, or when an exception occurs in the remote space in the process of registering the notify.

Now that we've taken a look at the notify call, let's look at the event registration object that is returned from this call.

8.3.2. The EventRegistration Class

When a notification is successfully registered with a space, the space returns an EventRegistration object that encapsulates information about the registration.

The EventRegistration provides the following set of public methods:

public class EventRegistration implements java.io.Serializable {
  public long getID();
  public Object getSource();
  public long getSequenceNumber();
  public Lease getLease();
}

The first two methods, getID and getSource, identify the event registration. The getID method returns an identifier assigned to a registration by the space (there is no standard convention for this identifier, and every space implementation is free to formulate its own identification scheme for the event registrations). The getSource method returns an object representing the event source (the space) with which interest in the event notification was registered. Together these two properties act to uniquely identify the event registration.

The getSequenceNumber method supplies an initial sequence number for events generated from a notify registration. Each successive event generated from the registration will contain a sequence number that is one greater than the previous sequence number. As we will see, the getSequenceNumber method gives the listener a way to deal with missing, out of order, and duplicate events generated from the registration.

Finally, the getLease method returns the lease granted to this event registration. If the client wishes to extend or cancel its registration, it can issue renew or cancel methods on the Lease object.

8.3.3. The RemoteEventListener Interface

In the context of JavaSpaces systems, remote event listeners are objects that receive remote events generated from the space. This object may reside in your space-based program or it can be an external third party object running remotely in another JVM. In order to act as a listener, an object must implement the RemoteEventListener interface:

public interface RemoteEventListener
  extends Remote, java.util.EventListener
{
  void notify(RemoteEvent theEvent)
    throws UnknownEventException, RemoteException;
}

The RemoteEventListener interface contains one method called notify, which is called whenever an entry is written into the space that matches the template supplied at event registration time. When the space calls a listener's notify method, it passes along a RemoteEvent object that provides specific information about the event. We will examine the RemoteEvent object in the next section.

The notify call is synchronous—when a space calls notify on a listener it waits until the call finishes. This is important: Since the space can't proceed until the call finishes, it is a good policy for the notify method to return as quickly as possible. In the case where you must do lengthy event processing, you should create a new thread for that purpose, and then return.

The notify method can throw two exceptions: RemoteException and UnknownEventException. The RemoteException occurs when there are communication problems between the space and the listener. The UnknownEventException can be thrown if the listener determines it has received an event it shouldn't have received, which allows the space the opportunity to cancel the particular notification.

8.3.4. The RemoteEvent Object

Each time a listener's notify method is called, a RemoteEvent object is passed to it. The RemoteEvent class is an extension of the java.util.EventObject, which is the event object used in Java's standard event model. The RemoteEvent class provides the following public methods, which you will find closely related to the EventRegistration class in Section 8.3.2:

public class RemoteEvent extends EventObject
{
  public long getID();
  public Object getSource();
  public long getSequenceNumber();
  public MarshalledObject getRegistrationObject();
}

Like the EventRegistration class, RemoteEvent provides getID and getSource methods, which uniquely identify the event as belonging to a particular event registration. When a listener receives an event notification, calling getSource and getID on the remote event will return the same values as calling getSource and getID on the EventRegistration object returned by the corresponding notify registration. If the listener is registered to receive multiple event registrations, it can use these values to identify the event as belonging to a particular registration.

Likewise, the RemoteEvent provides a getSequenceNumber method that returns the unique sequence number of this event, which can be used to compare this event against the beginning sequence number in the event registration and also the event numbers of other events from the same notification.

Unlike the EventRegistration class, the remote event contains a getRegistrationObject method that returns a MarshalledObject (a wrapper around a serialized object); this object is the “handback” that was passed as the final parameter to the space's notify method, and it gets handed back to a listener at notification time as part of the event object. We'll have more to say about the handback object, and what it is used for, in Section 8.5.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset