Application Techniques



Implementing Persistent Session-Level Failover

How to create an HTML application that maintains user state across server failures.

About this technique

Details

Category

HTML Client Techniques> Page flow and state management

Description

You'll learn about:

You can run this technique code from:

NOTE   First make sure that database is running on your localhost SilverStream Server

Related reading

See the chapter on administering a cluster in the Administrator's Guide

The term session-level failover refers to the ability of an HTML application to retain temporary user data (state) across server failures in a cluster. The data is stored in a persistent storage repository (such as a database or file system shared by the servers in the cluster) so that it can be recovered by any server in the cluster in the event of a server failure.

When a client makes an HTTP request against a SilverStream cluster, the Dispatcher redirects the request to an available server. After that initial connection to the Dispatcher, the user interacts directly with the server. In general, this provides better performance than having each user request go through the Dispatcher. However, because the user's browser connects directly to the server, the browser does not know what to do if the server fails.

Even if the application has maintained the user's state and it is available on another server, the browser does not know to connect to that server. If the user reconnects through the Dispatcher, an application with session-level failover will have the user's state and processing can proceed. In some cases, this level of failover is sufficient. In other cases, the application requires transparent failover. To support transparent failover, you need to use a third-party dispatcher that can automatically reroute a session to another server in the cluster.

    For more information about session-level failover, see the whitepaper entitled SilverStream Session-Level Failover, which is available at the SilverStream DevCenter.

Setting up the application   Top of page

To provide session-level failover support, an HTML application uses the following classes in the SilverStream API to manage the user's state:

To retain the user's state, an HTML page calls methods on the AgoPersistentStateManager object. This object in turn calls methods associated with a business object you define that extends the AgoPersistentStoreManager class. Your business object defines the actual storage mechanism used to maintain the user's state, specifying how and where the data is stored. In the live example provided in the Examples3_HTML database, the business object that stores the data is called invPersistentStoreManager. This object is located in the com.examples.persist package. The data is stored in a table called AgPersistentState in the Examples3_HTML database.

You specify the name of the business object that provides a storage implementation for your application in a file called PersistentSession.props, which is located in the Resources subdirectory of the SilverStream installation directory. The AgoPersistentStateManager object gets the name of the storage manager object for your application by reading this file.

NOTE   You do not need to define a cluster to test the live example. Simply run the pgSessionLevelFailover.html page and begin experimenting with the controls on the page. You can simulate a server failure by clicking the Simulate Server Failure button.

Using the persistent state manager on a page   Top of page

To retain the user's state, an HTML page calls methods on the AgoPersistentStateManager object.

Getting a reference to the object   Top of page

Before you can read or write state data by using the AgoPersistentStateManager class, you need to call a static factory method called getPersistentStateManager() to get a state manager object. The pgSessionLevelFailover.html page gets a state manager object in the pageRequestBegin event:

  m_mgr = AgoPersistentStateManager.getPersistentStateManager(req, res, "Examples3_HTML"); 

The final argument to getPersistentStateManager() specifies the name of the current application. This name is used to retrieve application-specific settings from the PersistentSession.props file, including the name of the store manager object, the cleanup age (the number of hours the state data should be retained), and the debug flag, which enables or disables debugging messages.

Reading and writing state data   Top of page

The AgoPersistentStateManager class has methods that let you read data from and write data to the persistent store. For example, to write the key and value data that the user enters on the page, the pgSessionLevelFailover.html page calls the put() method in the code for the Add button's pageActionPerformed event. The call to the commit() method tells the store manager to write the data to the persistent store:

  try 
  { 
     //Add the key (and its value) into the persistent state manager 
     m_mgr.put(fldKey.getText(), fldValue.getText()); 
   
     //If autocommit is turned off then commit changes manually 
     if (!chkAutoCommit.getState()) 
     { 
      //Commit the persistent data 
      m_mgr.commit(); 
     } 
   
     //Refresh the dataview 
     loadData(); 
  } 
  catch (Exception e) 
  { 
     lblErrorMsg.setText(e.toString()); 
  } 

Similarly, to read data from the store, the page calls the get() method in the code for the page's loadData() method:

  try 
  { 
     Vector vctState = new Vector(); 
     Hashtable state = m_mgr.getStateHashtable(); 
   
     //Get an enumeration of the hash table keys 
     Enumeration e = state.keys(); 
     while (e.hasMoreElements()) 
     { 
       Object[] obj = new Object[2]; 
       obj[0] = e.nextElement(); 
       obj[1] = m_mgr.get((Serializable)obj[0]); 
   
       //Add the object array to the state vector 
       vctState.addElement(obj); 
     } 
   
     //Set the result set for the row cursor 
     m_rowCursor.setResultSet(vctState); 
   
      //Tell the view where to get the data 
     View1.setDataProvider(m_rowCursor); 
      
     //Clear the data entry fields 
     fldKey.setText(""); 
     fldValue.setText(""); 
    } 
    catch (Exception e) 
    { 
     lblErrorMsg.setText(e.toString()); 
    } 

Implementing a store manager   Top of page

To add session-level failover support to an application, you need to create a business object that extends the AgoPersistentStoreManager class. Your business object defines the actual storage mechanism used to maintain the user's state.

Like an invoked business object, the AgoPersistentStoreManager class has an invoked() method that is executed when the object is invoked. In the invoked() method in your subclass, you need to call the invoked() method on the superclass:

  super.invoked(evt);	  

The invoked() method for AgoPersistentStoreManager calls the following methods:

These three methods are defined as abstract in the AgoPersistentStoreManager class; you need to implement them in your subclass. The invPersistentStoreManager business object in the Examples3_HTML database shows sample implementations for these methods.

Editing the PersistentSession.props file   Top of page

The PersistentSession.props file lets you specify both server-wide and application-specific property settings that apply to session-level failover. The AgoPersistentStateManager object reads this file. Here's what the file looks like:

  ############################################################################ 
  # Server-wide Persistent State Properties 
  ############################################################################ 
   
  CookieDomain=none 
  CookieName=PersistentSessionID 
   
  ############################################################################ 
  # Application specific PersistenceStoreManager Invoked Objects 
  ############################################################################ 
   
  SilverBooks.StoreManager=SilverBooks3:com.silverbooks.persist.invPersistentStoreManager 
  SilverBooks.CleanupAge=24 
  SilverBooks.Debug=false 
   
  Examples3_HTML.StoreManager=Examples3_HTML:com.examples.persist.invPersistentStoreManager 
  Examples3_HTML.CleanupAge=24 
  Examples3_HTML.Debug=false 
   
  PersistentSLFO.StoreManager=PersistentSLFO:com.examples.persist.invPersistentStoreManager 
  PersistentSLFO.CleanupAge=24 
  PersistentSLFO.Debug=false 

The property settings are described briefly below:

Property

Description

CookieDomain

The domain name for the cookie. The domain name determines the DNS zone in which the cookie is visible. By default, cookies are returned only to the server that originally sent them.

This property is used when you're running in a cluster. When you're testing on a single machine, the CookieDomain property should be set to None.

CookieName

The name of the cookie.

StoreManager

The name of the business object that acts as the store manager. This object must extend AgoPersistentStoreManager.

CleanupAge

The number of hours to retain the state data. In the live example, this value determines when the scheduled cleanup routine on the invPersistentStoreManager is triggered.

Debug

A switch that enables or disables debugging messages.

   





Copyright © 2000, SilverStream Software, Inc. All rights reserved.