Process Affinity and State-Aware Mode (Preserve Mode 1)
The architecture of the web is stateless. In order to get the best out of web architecture in terms of performance, maintainability and scalability, web applications should embrace the stateless paradigm.
By default, web applications operate in a stateless environment with respect to the hosting InterSystems IRIS® server. The Web Gateway maintains a pool of connections to InterSystems IRIS and distributes the workload amongst them and increases, within configured limits, (or decreases) the size of the connection pool. Each connection is associated with a single InterSystems IRIS process (as identified by the $Job variable).
For a normal web application operating in stateless mode, consider the choice of backend InterSystems IRIS process used to serve each request for a client session to be random. The Web Gateway chooses whichever connection/process happens to be free.
However, in the interests of efficiency, the Web Gateway does implement a form of InterSystems IRIS process affinity. In other words, it attempts, where possible, to route a request for a session to the same InterSystems IRIS process that was used to serve the previous request for that session.
In addition to a measure of process affinity based on session ID, the Web Gateway also attempts to implement process affinity based on namespace. The Web Gateway keeps track of the namespace to which each connection is pointing and delivers, where possible, requests to a connection that is already pointing at the namespace required to process the request. This helps in avoiding the overhead incurred in moving resources between different namespaces on receiving each web request.
In terms of precedence, session affinity always overrides all other considerations in the selection of a connection. If an incoming request cannot be assigned to the same connection previously used to serve the client session, namespace affinity is used instead to influence the final choice.
CSP includes a mode whereby the Web Gateway routes all requests for a session to a reserved (or private) InterSystems IRIS connection/process. This mode of operation provides a state-aware environment with respect to the relationship between web sessions and their corresponding InterSystems IRIS processes.
The original motivation for the provision of a state-aware mode of operation (preserve mode 1) was to make it relatively easy to migrate legacy application code from a fixed client-server environment (e.g. terminal applications) to the web. Support for transactions that spanned several HTTP requests was also a consideration in its introduction. However, the limitations outlined in the following paragraphs should be borne in mind when creating state-aware applications.
State-aware applications do not scale as well as their stateless counterparts and it is therefore recommended that new applications (and modifications to existing ones) be designed to be stateless as far as is practically possible. It is recommended that state-aware mode, if used at all, should be applied sparingly in predominantly stateless applications.
Writing complete applications to operate in state-aware mode is not recommended. Apart from the scalability issues that arise as a consequence of the need to reserve an InterSystems IRIS process for each and every session, state-aware applications are unable to take full advantage of modern load balancing and failover solutions because of the very specific requirements for routing requests. Also, state-aware applications are not as fault-tolerant as their stateless counterparts. For example, the recycling of a web server worker process can happen transparently beneath a stateless application but results in all associated state-aware sessions closing. Of course, you can avoid the latter restriction by using the Web Gateway’s NSD component to separate the management of the Web Gateway process pool from the hosting web server.
Creating a successful state-aware application (or state-aware sections within a predominantly stateless application) requires a certain amount of discipline.
Since all requests for a session must be processed by the same InterSystems IRIS process, a queue must be maintained to serialize access to the private InterSystems IRIS process for cases where the client simultaneously dispatches several requests. The original HTTP v1.1 standard mandated that a client should simultaneously open no more than 2 connections to each server (RFC2616). However, this limit is configurable and, indeed, the latest generation of web browsers support, by default, up to 8 connections to each server. Needless to say, an increase in the maximum number of connections to each server can have a profound effect on state-aware web applications: an application can expect up to 8 requests to be fired concurrently and subsequently held in the queue responsible for controlling access to the single private InterSystems IRIS process.
Another potential pitfall in state-aware mode is the effect of the Server Response Timeout operating between the Web Gateway and InterSystems IRIS. When the Web Gateway does not receive a response within the prescribed time limit imposed by the response timeout it has no option but to close the connection with the consequential loss of the state-aware session.
Finally, the effect of client interrupts can cause problems with applications operating in state-aware mode. When a client interrupts a request at (and beyond) the point at which InterSystems IRIS is generating a response, the Web Gateway attempts to absorb the (now unwanted) response payload in order to retain the connection. If it is unable to do this in a timely fashion it, again, has no option but to interrupt whatever the InterSystems IRIS process is doing by closing the connection and the session is lost. Bear in mind that while the Web Gateway is attempting to absorb the payload for an interrupted request, further requests for the same session may be arriving and placed in the queue.
In summary, follow the following design goals when creating state-aware applications.
As far as possible avoid (or use sparingly) client constructs that generate many simultaneous requests (for example: HTML Frameset documents).
Ensure that responses are generated quickly. This reduces the scope for issues related to timeout and/or client interrupt events. It also relieves pressure on the session queue. If a task in InterSystems IRIS potentially requires an extended time to complete, then consider performing it in another process so that the primary private process can quickly return a response to the Web Gateway (and client).
Launching State-Aware Mode
Mark a session as state-aware by setting the preserve mode as follows:
Set %session.Preserve = 1
It is recommended that a session be marked as state-aware in the form’s OnPreHTTP method:
<script language=objectscript method=OnPreHTTP arguments="" returntype=%Boolean> Set %session.Preserve = 1 Quit 1 </script>
Issuing the instruction here means that the CSP engine can mark the session cookie (or token) as state-aware before formulating and dispatching the HTTP response headers to the Web Gateway.
Sessions can be marked as state-aware after the OnPreHTTP method has fired but in this case the session cookie/token has already been formulated. The CSP engine passes the preserve=1 instruction to the Web Gateway in the response footers (dispatched after the response payload) and the Web Gateway marks the connection as private and caches the instruction against the session ID so that it can recognize the unmodified session token as state-aware when subsequent requests arrive.
If the session is marked as state-aware in the OnPreHTTP method, the Web Gateway has no need to cache the transition against the session since the information is carried in the session cookie/token which effectively resides on the client.
Maintaining State-Aware Mode and Responding to Errors
Once a session is marked as state-aware and the Web Gateway has acknowledged the state-transition and marked the connection as private, the session transparently operates in state-aware mode until one of the following events occurs:
The application transitions back to a stateless mode of operation.
The application programmatically ends the session or the session times out.
The private connection closes prematurely as a result of some error condition.
If the private connection hosting a state-aware application is prematurely closed (perhaps as a result of an error condition), the Web Gateway routes the request to a free stateless connection in the pool and InterSystems IRIS error number 5974 is returned:
CSP error occurred Error: The persistent session is no longer available because the server process does not exist ErrorNo: 5974 CSP Page: /csp/samples/loop.csp Namespace: %SYS Class: <Unknown>
At this point, the request is operating in stateless mode and it is the application’s responsibility to respond to this error: for example, by directing the user back to the login form for the application.
When operating in state-aware mode, the value of %session.NewSession should be checked in every page. Alternatively, the application should check the validity of user specific authentication data stored in %session.Data when the user was first authorized to access the application. These checks are important for security reasons and to ensure that the user session is still securely locked-in to a state-aware mode of operation. An error condition is not automatically raised under these circumstances because it is possible that the session had already (and legitimately) transitioned out of state-aware mode. For example, consider the situation where an incoming session token is still marked as state-aware but the application had already transitioned to stateless mode – this situation arising as a result of a session token being embedded in a form (as CSPCHD) that was served before the transition was made.
Finally bear in mind that when a session is terminated (for example, after it has timed out) the CSP engine deletes all operational data associated with the session, after which point any further incoming requests for that session are treated as though they are for a new session.
The embedded security mechanisms provided by InterSystems IRIS for web applications offer protection against the eventualities outlined above. Users are automatically directed to the login form in all cases where a loss of continuity within a state-aware application occurs (with respect to InterSystems IRIS process).
Terminating State-Aware Mode
An application can revert back to a stateless mode of operation by setting the preserve mode as follows:
Set %session.Preserve = 0
It is recommended that this code be executed in the form’s OnPreHTTP method:
<script language=objectscript method=OnPreHTTP arguments="" returntype=%Boolean> Set %session.Preserve = 0 Quit 1 </script>
Issuing the instruction here means that the CSP engine can mark the session cookie (or token) as stateless before formulating and dispatching the HTTP response headers to the Web Gateway.
A session can be immediately terminated as follows:
Set %session.EndSession = 1
When you set this property, the session terminates immediately after serving the current request.
You can set a session to timeout as follows:
Set %session.AppTimeout = 900
The session times out and terminates after the prescribed number of seconds of inactivity. The default is 900 seconds (15 minutes).