Access Keys:
Skip to content (Access Key - 0)









How do I Use the Event Context in SLEE 1.1

Print this page

Introduction

This document provides an overview of the Event Context introduced in Rhino 2.0, how it can be used, and why you might want to do so.

Event Context Overview

Every event fired in a JAIN SLEE 1.1 SLEE has an Event Context associated with it. The Event Context encapsulates the information related to the event, such as the event object, the activity context the event was fired on, the service the event was fired to, and the address the event was fired with. The Event Context allows an SBB to suspend and resume delivery of the event associated with the Event Context. When the event delivery is suspended the event will not be delivered to other eligible SBBs until its delivery has been resumed. The suspend/resume model supports modelling of synchronous behaviour in the SLEE asynchronous environment. For example an SBB can suspend event delivery of an event before asynchrously querying an external system and then resuming event delivery in a subsequent transaction.

Event Contexts may only be used by SBBs written to the SLEE 1.1 specification. They are not available to SLEE 1.0 SBBs.

What Use is Event Delivery Suspension?

Consider an example where an SBB is triggered at the beginning of a call and needs to query an external billing system to reserve credit for the call. If the resource adaptor providing access to the billing system defines an asynchronous API then the SBB would typically initiate a billing request then return from its event handler method. However the default SLEE event routing algorithm means that the event will then be delivered to the next eligible SBB, even though a response to the billing request is still outstanding. If, based on the billing response, the first SBB changes the progress of the call, updates shared activity context state, etc, then undesirable interactions can occur between services as concurrent operations on the same call execute.

In SLEE 1.0 the only way to deal with this effectively is to use a synchronous billing API so that the event delivery thread is blocked while the charging request is in progress, thus preventing further SBBs from being invoked by the SLEE event router for the same event. However synchronous downcall APIs that may block for an indeterminate period of time are generally a bad idea as they do not scale to high-volume event processing rates. A SLEE typically only has a limited number of threads available with which is uses for event delivery. If all these threads get blocked performing synchronous downcalls then a bottleneck is created, event queues quickly back up, and performance plateaus at a rate relative to the number of available threads and the speed the synchronous resource can service requests. Adding more threads to the problem is not the answer as each new thread consumes more system resources, ultimately placing a limit on the total number of threads that could possibly be created without crippling the machine.

Asynchronous APIs do not suffer these limitations, but have not been a generally workable solution in SLEE 1.0 in scenarios where multiple services could be triggered for the same event. Thankfully the ability to suspend further delivery of an event in SLEE 1.1 opens up the possibilites of using asynchronous APIs effectively. By suspending delivery of an event an SBB can initiate an asynchronous request and release control of the event delivery thread without fear that SBB logic in other services will corrupt the state of the activity the suspended event was fired on. Since these SBBs do not hold event delivery threads blocked, the SLEE is able to continue delivery of other events while the asynchronous request proceeds concurrently. The nett result for the SLEE is much higher throughput capabilities than could be achieved using a synchronous API.

EventContext Interface

An Event Context is represented by the javax.slee.EventContext interface. This interface is shown below:

package javax.slee;

public interface EventContext {
    // event properties
    public Object getEvent();
    public ActivityContextInterface getActivityContextInterface();
    public Address getAddress();
    public ServiceID getService();

    // event delivery manipulation
    public void suspendDelivery()
        throws IllegalStateException, TransactionRequiredLocalException,
               SLEEException;
    public void suspendDelivery(int timeout)
        throws IllegalArgumentException, IllegalStateException,
               TransactionRequiredLocalException, SLEEException;
    public void resumeDelivery()
        throws IllegalStateException, TransactionRequiredLocalException,
               SLEEException;
    public boolean isSuspended()
        throws TransactionRequiredLocalException, SLEEException;
}

Getting a Reference to an Event Context

A SLEE 1.1 SBB initially obtains a reference to an Event Context object via an event-handler method invocation. The SLEE 1.1 specification provides a variation of the SBB event-handler method signature which adds a third argument of type javax.slee.EventContext, as shown in the example below:

import javax.slee.ActivityContextInterface;
import javax.slee.EventContext;
import javax.slee.Sbb;

public abstract class MySbb implements Sbb {
    ...
    public void onEvent1(ExampleEvent event, ActivityContextInterface aci, EventContext context) {
        ...
    }
}

An Event Context object may also be stored in an SBB CMP field and retrieved again in a later transaction. The Java type of a CMP field that stores an Event Context must be javax.slee.EventContext. For example, if the CMP field name was "exampleEventContext", then the CMP field accessor methods would look like this:

public abstract void setExampleEventContext(EventContext context);
public abstract EventContext getExampleEventContext();

Other than declaring the CMP field in the deployment descriptor, no special declaration needs to be made for the CMP field. The SLEE infers from the CMP field type that it will be used to store EventContext objects and will handle persistence of these objects in its own way.

Note that if an Event Context becomes invalid due to the SLEE completing event delivery processing for the event then the Event Context can no longer be retrieved from an SBB CMP field in subsequent transactions. An SBB CMP field getter method returns null in this case.

Suspending Event Delivery

The following example illustrates a practical case where suspending event delivery is desirable. In this example the SBB receives an event indicating a new call is starting. The SBB stores the Event Context in a CMP field, suspends further delivery of the event, then invokes a external billing system, for example to reserve some credit for the call. The external billing system uses an asynchronous API and notifies the SBB of the outcome of the charging request when it becomes available by firing an event to the SBB. Upon receipt of the billing system callback, the SBB processes the result, then retrieves the Event Context previously stored in CMP and resumes delivery of the original call event.

import javax.slee.ActivityContextInterface;
import javax.slee.EventContext;
import javax.slee.Sbb;

public abstract class MySbb implements Sbb {
    public void onCallStartEvent(CallEvent event, ActivityContextInterface aci, EventContext context) {
        // store the context in a CMP field
        setEventContext(context);

        // suspend event delivery
        context.suspendDelivery();

        // send request to asynchronous external billing system to do some account processing
        ...
    }

    public void onBillingSystemCallBack(BillingCallbackEvent event, ActivityContextInterface aci) {
        // process billing system response
        ...

        // retrieve original event context of onCallStartEvent() event handler
        EventContext context = getEventContext();

        // resume delivery of call event now that the billing subsystem has done its work
        context.resumeDelivery();
    }

    ...

    public abstract EventContext getEventContext();
    public abstract void setEventContext(EventContext value);
}

Resuming Event Delivery

Delivery of a suspended event typically resumes when a transaction in which the resumeDelivery() method is invoked on the event's Event Context commits. However event delivery may be automatically resumed by the SLEE in either of the the following situations:

  • the event was suspended using the suspendDelivery(int timeout) method and the timeout period has expired;
  • the event was suspended using the suspendDelivery() method and a SLEE-implementation-specific (possibly configurable) timeout period has expired.
Adaptavist Theme Builder Powered by Atlassian Confluence