Using Sessions

OGSA-DAI sessions were introduced on the Sessions page of the Background Reading section, then were covered in more detail on the Perform Document page of the same section. To summarise, sessions are objects created and managed by a data service resource that allow state to be stored across multiple perform document requests. State is stored in session attributes which are identifiable by name. Sessions are also used to expose session streams which allow reading and writing of data using the OGSA-DAI data transport functionality. Every request processed by a data service resource is joined to a session and the activities within that request may interact with the session during processing. Only one request may join a particular session at a time, so if one request is processing, a client must wait for it to complete before sending another request to join the same session.

The code excerpts featured on this page are shown in full in the following example file: UsingSessionsExample.java

1. Joining an implicit session

All requests processed by a data service resource are joined to a session, so all the previous examples in this tutorail have been using sessions implicitly. At the client side, details of the implicit session can be retrieved from the response. The example below performs an empty request then displays the identity of the session that the empty request was joined to.

ActivityRequest request = new ActivityRequest();
Response response = service.perform(request);
Session session = response.getSession();
System.out.println(session.getSessionID());

An implicit session is of little practical use for storing session attributes because it is terminated automatically as soon as request processing completes. In order to make proper use of sessions, it is necessary to instruct the data service resource to create them explicitly by specifying the session requirements for a request.

2. Creating a new session

A data service resource can be instructed to create a new session by attaching session requirements to an activity request. There are various session requirment objects that can be passed to the setSessionRequirements method of the ActivityRequest. The example below demonstrates how a request can instruct a data service resource to create a new session with default timeout settings.

ActivityRequest request = new ActivityRequest();
SessionRequirements requirements = new JoinNewSession();
request.setSessionRequirements(requirements);
Response response = service.perform(request);
Session session = response.getSession();

A session with a specific timeout value in milliseconds can be specified using the overloaded constuctor on the JoinNewSession class, as shown below:

SessionRequirements requirements = new JoinNewSession(300000);

Note that activities could also have been included in the requests in the above examples. The data service resource would first create the new session, then join the request to it, then process the activities.

3. Joining an existing session

Once a session has been explicitly created, a subsequent perform document request may wish to join the same session. In this way the activities within the request can access and modify attributes and streams that already exist in the session. The example below shows how another session requirements class can be used to instruct a data service resource to join a request to a particular session. In this example two activities are also contained in the request.

ActivityRequest request = new ActivityRequest();
SessionRequirements requirements = new JoinExistingSession(session);
request.setSessionRequirements(requirements);

SQLQuery query =
    new SQLQuery("select * from littleblackbook where id<10");
WebRowSet webRowSet = new WebRowSet(query.getOutput());
request.add(query);
request.add(webRowSet);

service.perform(request);

If the client session object is not available it is still possible to join that session so long as the ID of the session is known. A session ID is auto-generated when a new session is created by a data service resource and returned in the response. The example below shows how an existing session can be joined if the session ID is known by constructing a SessionID object.

ActivityRequest request = new ActivityRequest();
SessionID id = new SessionID("some-session-ID");
SessionRequirements requirements = new JoinExistingSession(id);
request.setSessionRequirements(requirements);
service.perform(request);

Special care should be taken when joining an existing session because of the restriction that only one request can join a particular session at a time. If the request that is currently joined to a session is processing asynchronously, then it is easy to accidentally submit another request to try to join the same session. This will result in a RequestException. To help determine the processing status of an asynchronous request, the Session interface provides a getStatus method. This returns an object describing the processing status of the request that is currently joined to that session.

RequestStatus status = session.getStatus();

The DataService interface also provides various pole methods that can be used to wait until an asynchronous request has completed. The example below polls the data service resource every 100 milliseconds until the request completes.

service.pollUntilRequestCompleted(session.getSessionID(), 100);

4. Terminating a session

Sessions have a finite life-time after which they expire and can no longer be joined by requests. Since sessions consume memory at the data service resource it is good practice to terminate a session explicitly when it is no longer needed. This allows the memory used by the session to be garbage collected at the data service resource. The example below shows how this is achieved using the TerminateSession session requirements class.

ActivityRequest request = new ActivityRequest();
SessionRequirements requirements = new TerminateSession(session);
request.setSessionRequirements(requirements);
service.perform(request);

Session Exceptions

If there is a problem creating or accessing a particular session then a client toolkit uk.org.ogsadai.client.toolkit.exception.RequestException will be raised. The exception will contain a message string describing the cause of the problem. This would occur if an attempt was made to join a session that had already expired or was currently joined by another request.

Conclusion

This page provided a brief introduction to the session capabilities of the client toolkit. Sessions are used most commonly during data transport scenarios, where data from a session stream is transported between two data service resources. This scenario is covered in detail in the next section of the tutorial. However, the full potential of sessions extends beyond this to enable users to develop activities that store and access state across multiple requests. In the future, sessions may become a more prominent part of the OGSA-DAI architecture used for managing transactions and other multi-request operations.