Adept Development System

Adept - Application Developer Enterprise to Personal Transition - A system to leverage corporate design (graphic, interface and code) and development skills to produce shrink-wrap software packages.

http://marringtons.com

Friday, April 01, 2005

Session and Conversation Data

This article is an extension of Data Lifetimes in my Software Development blog.

What is Session Data

Session data is data that lives as long as the session is active. A session is active from the moment the browser first connects or a user logs in until the session times out - typically 20 minutes of inactivity after the user leaves the site or closes the browser.

What is Conversation Data

Conversation data is much shorter lived. It can exist from the moment a browser makes a get or post request to the server and goes out of scope as soon as the browser receives a response from the server. Conversation data is mostly used to return information, validation and error messages to the browser for display.

How Session Data is kept in Adept

Class com.marringtons.util.Session contains a static private com.marringtons.util.Cache instance that will hold session data and release it if not used for a specific interval (defaulting to 20 minutes). If a browser has never connected before, create() is called to generate a unique key. This is saved in a permanent cookie on the browser called "AdeptSession". This key is used to retrieve a session or create a new one at the start of each conversation. With this method the same session will be used by all instances of the same browser for the user currently logged in at the OS level. Closing the browser and reopening (before the timeout) will continue to use the same session. Using the same browser after the session timeout will still retrieve persistent session data.

This all changes if the user logs into the Adept system. A session-only cookie of the same name ("AdeptSession") is created with the user's name. This is used to retrieve session information - and isn't a security risk since the user is authenticated against the session at the start of each conversation.

In either case, because the thread is named for the session, a static getInstance() without parameters can be used to retrieve the session data dictionary.

Session session = Session.getInstance();

 

How Conversation Data is kept in Adept

Conversation data is kept in a much simpler static private Map, with the conversation keyed on the thread name. Since a conversation is sequential, it will use the same thread from beginning to end.

Manipulating Session Data

Retrieving the object from the session depends on it's scope and type. An object can have a scope of:
  1. Class scope. Use classScope();
  2. Package scope. Use packageScope();
  3. Global scope. Use globalScope();

Use the above methods to create a static final field in the calling class and use that to access session level data.

Objects can be one of three types also:

  1. Transient entries: are lost when the session closes.
  2. Closeable entries: have a close method that is called when the session goes out of scope. Data class implements com.marringtons.util.Closeable.
  3. Persistent entries: are saved on disk and retrieved the next time the session is activated (a user logs in). Set by final parameter in scope creator method.
Because session data can have type, scope, persistence and closeability, a Session.Key is created to contain it. For efficiency, this should be a static final field in the class that's making use of it.

Manipulating Conversation Data

Because a conversation is relatively short-lived, the com.marringtons.util.ThreadData class is much simpler. There are getters that create a new instance if needed, those that provide a default and those that use the class name as key name (for local scope). There is also, of course, a matching setter - although it's rarely used since most instances are created automatically using a default constructor.

Session Data: A Real-World Example

private static final Session.Key recordingSessionKey
  = Session.classScope( Tape.class, "taping",
    null, Session.transientLifetime);

private static final Session.Key storageSessionKey
  = Session.classScope( Tape.class, "tape",
    null, Session.persistentLifetime);

public static Tape load( Session session)
  { return (Tape) session.get( recordingSessionKey); }

public static Tape create( Request request)
  {
    Tape tape = load( request);
    if (tape == null)
      tape = new Tape();
    else
      tape.commands.clear();
    tape.startPage
        = request.getParameter( "startPage");
    request.session.put( recordingSessionKey, tape);
    return tape;
  }

 

Conversation Data: A Real-World Example

/**
 * @return Messages associated with this thread.
 * Usually used as error messages to be displayed
 * in response to a browser request.
 */
static public Messages getThreadInstance()
  {
    return (Messages) ThreadData.get( className, 
        Messages.class);
  }

 

0 Comments:

Post a Comment

<< Home