EV.2. The Basic Interfaces

The basic interfaces you are about to see define a protocol that can be used by one object to register interest in a kind of state change in another object, and to receive a notification of an occurrence of that kind of state change, either directly or through some third-party, that is specified by the object at the time of registration. The protocol is meant to be as simple as possible. No attempt is made to indicate the reliability or the timeliness of the notifications; such guarantees are not part of the protocol but instead are part of the implementation of the various objects involved.

In particular, the purpose of these interfaces is:

  • To show the information needed in any method that allows registration of interest in the occurrence of a kind of event in an object

  • To provide an example of an interface that allows the registration of interest in such events

  • To specify an interface that can be used to send a notification of the occurrence of the event

Implicit in the event registration and notification is the idea that events can be classified into kinds. Registration of interest indicates the kind of event that is of interest, while a notification indicates that an instance of that kind of event has occurred.

EV.2.1. Entities Involved

An event is something that happens in an object, corresponding to some change in the abstract state of the object. Events are abstract occurrences that are not directly observed outside of an object, and might not correspond to a change in the actual state of the object that advertises the ability to register interest in the event. However, an object may choose to export an identification of a kind of event and allow other objects to indicate interest in the occurrence of events of that kind; this indi cates that the abstract state of the object includes the notion of this state changing. The information concerning what kinds of events occur within an object can be exported in a number of ways, including identifiers for the various events or methods allowing registration of interest in that kind of event.

An object is responsible for identifying the kinds of events that can occur within that object, allowing other objects to register interest in the occurrence of such events, and generating RemoteEvent objects that are sent as notifications to the objects that have registered interest when such events occur.

Registration of interest is not temporally open ended but is limited to a given duration using the notion of a lease. Full specification of the way in which leasing is used is contained in Section LE “Distributed Leasing”.

The basic, concrete objects involved in a distributed event system are:

  • The object that registers interest in an event

  • The object in which an event occurs (referred to as the event generator)

  • The recipient of event notifications (referred to as a remote event listener)

An event generator is an object that has some kinds of abstract state changes that might be of interest to other objects and allows other objects to register interest in those events. This is the object that will generate notifications when events of this kind occur, sending those notifications to the event listeners that were indicated as targets in the calls that registered interest in that kind of event.

A remote event listener is an object that is interested in the occurrence of some kinds of events in some other object. The major function of a remote event listener is to receive notifications of the occurrence of an event in some other object (or set of objects).

A remote event is an object that is passed from an event generator to a remote event listener to indicate that an event of a particular kind has occurred. At a minimum, a remote event contains information about the kind of event that has occurred, a reference to the object in which the event occurred, and a sequence number allowing identification of the particular instance of the event. A notifica tion will also include an object that was supplied by the object that registered interest in the kind of event as part of the registration call.

EV.2.2. Overview of the Interfaces and Classes

The event and notification interfaces introduced here define a single basic type of entity, a set of requirements on the information that needs to be handed to that entity, and some supporting interfaces and classes. All of the classes and interfaces defined in this specification are in the net.jini.core.event package.

The basic type is defined by the interface RemoteEventListener. This interface requires certain information to be passed in during the registration of interest in the kind of event that the notification is indicating. There is no single interface that defines how to register interest in such events, but the ways in which such information could be communicated will be discussed.

The supporting interfaces and classes define a RemoteEvent object, an EventRegistration object used as an identifier for registration, and a set of exceptions that can be generated.

The RemoteEventListener is the receiver of RemoteEvents, which signals that a particular kind of event has occurred. A RemoteEventListener is defined by an interface that contains a single method, notify, which informs interested listeners that an event has occurred. This method returns no value, and has parameters that contain enough information to allow the method call to be idempotent. In addition, this method will return information that was passed in during the registration of interest in the event, allowing the registrant, the object that registered interest with the event generator, to associate arbitrary information or actions with the notification.

The RemoteEventListener interface extends from the Remote interface, so the methods defined in RemoteEventListener are remote methods and objects supporting these interfaces will be passed by RMI, by reference. Other objects defined by the system will be local objects, passed by value in the remote calls.

The first of these supporting classes is RemoteEvent, which is sent to indicate that an event of interest has occurred in the event generator. The basic form of a RemoteEvent contains:

  • An identifier for the kind of event in which interest has been registered

  • A reference to the object in which the event occurred

  • A sequence number identifying the instance of the event type

  • An object that was passed in, as part of the registration of interest in the event by the registrant

These RemoteEvent notification objects are passed to a RemoteEventListener as a parameter to the RemoteEventListener notify method.

The EventRegistration class defines an object that returns the information needed by the registrant and is intended to be the return value of remote event registration calls. Instances of the EventRegistration class contain an identifier for the kind of event, the current sequence number of the kind of event, and a Lease object for the registration of interest.

Although there is no single interface that allows for the registration of event notifications, there are a number of requirements that would be put on any such interface if it wished to conform with the remote event registration model. In particular, any such interface should reflect:

  • Event registrations are bounded in time in a way that allows those registrations to be renewed when necessary. This can easily be reflected by returning, as part of an event registration, a lease for that registration.

  • Notifications need not be delivered to the entity that originally registered interest in the event. The ability to have third-party filters greatly enhances the functionality of the system. The easiest way to allow such functionality is to allow the specification of the RemoteEventListener to receive the notification as part of the original registration call.

  • Notifications can contain a MarshalledObject supplied by the original registrant, allowing the passing of arbitrary information (including a closure that is to be run on notification) as part of the event notification, so the registration call should include a MarshalledObject that is to be passed as part of the RemoteEvent.

EV.2.3. Details of the Interfaces and Classes

EV.2.3.1. The RemoteEventListener Interface

The RemoteEventListener interface needs to be implemented by any object that wants to receive a notification of a RemoteEvent from some other object. The object supporting the RemoteEventListener interface does not have to be the object that originally registered interest in the occurrence of an event. To allow the notification of an event’s occurrence to be sent to an entity other than the one that registered with the event generator, the registration call needs to accept a destination parameter that indicates the object to which the notification should be sent. This destination must be an object that implements the RemoteEventListener interface.

The RemoteEventListener interface extends the Remote interface (indicating that it is an interface to a Remote object) and the java.util.EventListener interface. This latter interface is used in the Java Abstract Window Toolkit (AWT) and JavaBeans components to indicate that an interface is the recipient of event notifications. The RemoteEventListener interface consists of a single method, notify:

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

The notify method has a single parameter of type RemoteEvent that encapsulates the information passed as part of a notification. The RemoteEvent base class extends the class java.util.EventObject that is used in both JavaBeans components and AWT components to propagate event information. The notify method returns nothing but can throw exceptions.

EV.2.3.2. The RemoteEvent Class

The public part of the RemoteEvent class is defined as:

public class RemoteEvent extends java.util.EventObject {
    public RemoteEvent(Object source, long eventID, 
                       long seqNum, MarshalledObject handback) 
    public Object getSource () {...} 
    public long getID() {...} 
    public long getSequenceNumber() {...} 
    public MarshalledObject getRegistrationObject() {...} 
} 

The abstract state contained in a RemoteEvent object includes: a reference to the object in which the event occurred, a long that identifies the kind of event relative to the object in which the event occurred, a long that indicates the sequence number of this instance of the event kind, and a MarshalledObject that is to be handed back when the notification occurs.

The combination of the event identifier and the object reference of the event generator obtained from the RemoteEvent object should uniquely identify the event type. If this type is not one in which the RemoteEventListener has registered interest (or in which someone else has registered interest on behalf of the RemoteEventListener object), an UnknownEventException may be generated as a return from the remote event listener’s notify method. [1]

[1] There are cases in which the UnknownEventException may not be appropriate, even when the noti-fication is for a combination of an event and a source that is not expected by the recipient. Objects that act as event mailboxes for other objects, for example, may be willing to accept any sort of notification from a particular source until explicitly told otherwise.

On receipt of an UnknownEventException, the caller of the notify method is allowed to cancel the lease for the combination of the RemoteEventListener instance and the kind of event that was contained in the notify call.

The sequence number obtained from the RemoteEvent object is an increasing value that can act as a hint to the number of occurrences of this event relative to some earlier sequence number. Any object that generates a RemoteEvent is required to ensure that for any two RemoteEvent objects with the same event identifier, the sequence number of those events differ if and only if the RemoteEvent objects are a response to different events. This guarantee is required to allow notification calls to be idempotent. A further guarantee is that if two RemoteEvents, x and y, come from the same source and have the same event identifier, then x occurred before y if and only if the sequence number of x is lower than the sequence number of y.

A stronger guarantee is possible for those generators of RemoteEvents that choose to support it. This guarantee states that not only do sequence numbers increase, but they are not skipped. In such a case, if RemoteEventx and y have the same source and the same event identifier, and x has sequence number m and y has sequence number n, then if m < n there were exactly n–m–1 events of the same event type between the event that triggered x and the event that triggered y. Such sequence numbers are said to be “fully ordered.”

There are interactions between the generation of sequence numbers for a RemoteEvent object and the ability to see events that occur within the scope of a transaction. Those interactions are discussed in Section LEEV.2.4 “Sequence Numbers”.

The common intent of a call to the notify method is to allow the recipient to find out that an occurrence of a kind of event has taken place. The call to the notify method is synchronous to allow the party making the call to know whether the call succeeded. However, it is not part of the semantics of the call that the notification return can be delayed while the recipient of the call reacts to the occurrence of the event. Simply put, the best strategy on the part of the recipient is to note the occurrence in some way and then return from the notify method as quickly as possible.

EV.2.3.3. The UnknownEventException

The UnknownEventException is thrown when the recipient of a RemoteEvent does not recognize the combination of the event identified and the source of the event as something in which it is interested. Throwing this exception has the effect of asking the sender to not send further notifications of this kind of event from this source in the future. This exception is defined as:

public class UnknownEventException extends Exception {
    public UnknownEventException() {
        super(); 
    } 
    public UnknownEventException(String reason){
        super(reason); 
    } 
} 

EV.2.3.4. An Example EventGenerator Interface

Registering interest in an event can take place in a number of ways, depending on how the event generator identifies its internal events. There is no single way of identifying the events that are reasonable for all objects and all kinds of events, and so there is no single way of registering interest in events. Because of this, there is no single interface for registration of interest.

However, the interaction between the event generator and the remote event listener does require that some initial information be passed from the registrant to the object that will make the call to its notify method.

The EventGenerator interface is an example of the kind of interface that could be used for registration of interest in events that can (logically) occur within an object. This is a remote interface that contains one method:

public interface EventGenerator extends Remote {
    public EventRegistration register(long evId, 
                    MarshalledObject handback, 
                    RemoteEventListener toInform, 
                    long leaseLength) 
        throws UnknownEventException, RemoteException; 
} 

The one method, register, allows registration of interest in the occurrence of an event inside the object. The method takes an evID that is used to identify the class of events, an object that is handed back as part of the notification, a reference to an RemoteEventListener object, and a long integer indicating the leasing period for the interest registration.

The evID is a long that is obtained by a means that is not specified here. It may be returned by other interfaces or methods, or be defined by constants associated with the class or some interface implemented by the class. If an evID is supplied to this call that is not recognized by the EventGenerator object, an UnknownEventException is thrown. The use of a long to identify kinds of events is used only for illustrative purposes—objects may identify events by any number of mechanisms, including identifiers, using separate methods to allow registration in different events, or allowing various sorts of pattern matching to determine what events are of interest.

The second argument of the register method is a MarshalledObject that is to be handed back as part of the notification generated when an event of the appropriate type occurs. This object is known to the remote event listener and should contain any information that is needed by the listener to identify the event and to react to the occurrence of that event. This object will be passed back as part of the event object that is passed as an argument to the notify method. By passing a MarshalledObject into the register method, the re-creation of the object is postponed until the object is needed.

The ability to pass a MarshalledObject as part of the event registration should be common to all event registration methods. While there is no single method for identifying events in an object, the use of the pattern in which the remote event listener passes in an object that is passed back as part of the notification is central to the model of remote events presented here.

The third argument of the EventGenerator interface’s register method is a RemoteEventListener implementation that is to receive event notifications. The listener may be the object that is registering interest, or it may be some other RemoteEventListener, such as a third-party event handler or notification “mailbox.” The ability to specify some third-party object to handle the notification is also central to this model of event notification, and the capability of specifying the recipient of the notification is also common to all event registration interfaces.

The final argument to the register method is a long indicating the requested duration of the registration. This period is a request, and the period of interest actually granted by the event generator may be different. The actual duration of the registration lease is returned as part of the Lease object included in the EventRegistration object.

The register method returns an EventRegistration object. This object contains a long identifying the kind of event in which interest was registered (relative to the object granting the registration), a reference to the object granting the registration, and a Lease object.

EV.2.3.5. The EventRegistration Class

Objects of the class EventRegistration are meant to encapsulate the information the client needs to identify a notification as a response to a registration request and to maintain that registration request. It is not necessary for a method that allows event interest registration to return an EventRegistration object. However, the class does show the kind of information that needs to be returned in the event model.

The public parts of this class look like

public class EventRegistration implements java.io.Serializable 
{
    public EventRegistration(long eventID, 
                             Object eventSource, 
                             Lease eventLease, 
                             long seqNum) {...} 
    public long getID() {...} 
    public Object getSource() {...} 
    public Lease getLease() {...} 
    public long getSequenceNumber() {...} 
} 

The getID method returns the identifier of the event in which interest was registered. This, combined with the return value returned by getSource, will uniquely identify the kind of event. This information is needed to hand off to third-party repositories to allow them to recognize the event and route it correctly if they are to receive notifications of those events.

The result of the EventRegistration.getID method should be the same as the result of the RemoteEvent.getID method, and the result of the EventRegistration.getSource method should be the same as the RemoteEvent.getSource method.

The getSource method returns a reference to the event generator, which is used in combination with the result of the getID method to uniquely identify an event.

The getLease returns the Lease object for this registration. It is used in lease maintenance.

The getSequenceNumber method returns the value of the sequence number on the event kind that was current when the registration was granted, allowing comparison with the sequence number in any subsequent notifications.

EV.2.4. Sequence Numbers, Leasing and Transactions

There are cases in which event registrations are allowed within the scope of a transaction, in such a way that the notifications of these events can occur within the scope of the transaction. This means that other participants in the transaction may see some events whose visibility is hidden by the transaction from entities outside of the transaction. This has an effect on the generation of sequence numbers and the duration of an event registration lease.

An event registration that occurs within a transaction is considered to be scoped by that transaction. This means that any occurrence of the kind of event of interest that happens as part of the transaction will cause a notification to be sent to the recipients indicated by the registration that occurred in the transaction. Such events must have a separate event identification number (the long returned in the RemoteEvent getID method) to allow third-party store-and-forward entities to distinguish between an event that happens within a transaction and those that happen outside of the transaction. Notifications of these events will not be sent to entities that registered interest in this kind of event outside the scope of the transaction until and unless the transaction is committed.

Because of this isolation requirement of transactions, notifications sent from inside a transaction will have a different sequence number than the notifications of the same events would have outside of the transaction. Within a transaction, all RemoteEvent objects for a given kind of event are given a sequence number relative to the transaction, even if the event that triggered the RemoteEvent occurs outside of the scope of the transaction (but is visible within the transaction). One counter-intuitive effect of this is that an object could register for notification of some event E both outside a transaction and within a transaction, and receive two distinct RemoteEvent objects with different sequence numbers for the same event. One of the RemoteEvent objects would contain the event with a sequence number relative to the transaction, while the other would contain the event with a sequence number relative to the source object.

The other effect of transactions on event registrations is to limit the duration of a lease. A registration of interest in some kind of event that occurs within the scope of a transaction should be leased in the same way as other event interest registrations. However, the duration of the registration is the minimum of the length of the lease and the duration of the transaction. Simply put, when the transaction ends (either because of a commit or a rollback), the interest registration also ends. This is true even if the lease for the event registration has not expired and no call has been made to cancel the lease.

It is still reasonable to lease event interest registrations, even in the scope of a transaction, because the requested lease may be shorter than the transaction in question. However, no such interest registration will survive the transaction in which it occurs.

EV.2.5. Serialized Forms

Class serialVersionUID Serialized Fields
RemoteEvent 1777278867291906446L Object source

long eventID

long seqNum

MarshalledObject handback
UnknownEventException 5563758083292687048L none
EventRegistration 4055207527458053347L Object source

long eventID

Lease lease

long seqNum

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

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