The toolkit uses the com.ibm.dse.cs.servlet.CSInactivityClientEvent to notify an application of an application subsession timeout. This is the same event used to notify the application of a session timeout. To determine which type of session is timing out, the application must check the appSessionId attribute of the event. If the attribute is null, the session is timing out. If the attribute has a value, an application subsession is timing out and the value of the attribute identifies the application subsession. The sessionId attribute identifies the session to which the application subsession belongs.
You handle application subsession timeouts in the same way you handle session timeouts except that you pass the application session ID instead of the session ID. The following example demonstrates the handling of an application subsession timeout:
public void handleCSInactivityClientEvent(CSInactivityClientEvent event) { // Get the ID of the expired appSession encapsulated in the event. String sessionId = event.getSessionExpired(); String appSessionId = event.getAppSessionExpired(); try { // Get the table with the stored processors. java.util.Hashtable procTable = HtmlProcessorManager.getProcessorInfoTable(appSessionId); // Remove each entry from cache and from the table. java.util.Enumeration procKeyEnum = procTable.keys(); while (procKeyEnum.hasMoreElements()) { String processorId = (String) procKeyEnum.nextElement(); String procName = ((HtmlProcessorInfo) procTable.get(processorId)).getProcessorName(); // Remove the processor instance from the cache. ProcessorExternalizer.getFromCache(procName); // Remove the processor instance from the processors table and registry. HtmlProcessorManager.getUniqueHTMLInstance(). removeProcessor(sessionId, processorId); } // Get the application session context. Context ctx = Context.getCurrentContextForSessionOrApplication(appSessionId); // If the appSession context has a service, terminate it here. // Remove the application session from the session table. Context.removeSession(sessionId, appSessionId); // Unchain the session context from the context hierarchy. ctx.prune(); } catch (Exception e) { // Perform any exception handling } }
Note that this method is just performing internally required toolkit processes. The application can use this method to stop other processes (services or application-specific processes) that are running in the application session.
To clean up after an application, create a class that performs the housekeeping as shown in the following HTML Channel example:
public class AppSessionLogoff extends DSEServerOperation { public void execute() throws Exception { // Get the current sessionId and appSessionId String sessionId = (String) getValueAt(HtmlConstants.SESSIONID); String appSessionId = (String) getValueAt(HtmlConstants.APPLICATIONID); // Get the context from the application subsession Context appSessionCtx = Context.getCurrentContextForSession(sessionId, appSessionId); // Perform any clean up for the data or services in the context // such as terminating the services defined in the context // Unchain the context, that will free up the context and the data // stored there unless this data has links to other objects appSessionCtx.unchain(); // Remove the session entry for the application subsession. // Before this is performed, the application must free up any // resource allocated by the application in the session entry // (typically nothing will be there) Context.removeSession(sessionId, appSessionId); // The context must be updated to inform the toolkit that the // application is not wanted to run anymore under this application // session setValueAt(HtmlConstants.APPLICATIONID, HtmlConstants.IGNORE); } }
If the application has enabled the processors cache, the cleanup process must include cleaning the cache. See Managing HTML flow processor timeout in the HTML Channel documentation.