Managing server object application state


Summary A key aspect of designing your application is whether it is stateful or stateless. You can make either stateful or stateless use of a server object running on the geographic information system (GIS) server. Stateless refers to making read-only use of a server object, meaning your application does not make changes to the server object or any of its associated objects. Stateful refers to read-write use of a server object where your application does make changes to the server object or its related objects.

The question of state is important in server object use because it dictates whether server objects can be shared across application sessions. If you make stateless use of server objects, then they can be shared across application sessions; if you make stateful use of server objects, then they cannot be shared.

In this topic


GIS server state and object pooling

The aspect of stateful versus stateless use and server object sharing relates directly to the pooling model for the server object. The following programming rules apply to using server objects:
  • Client applications cannot change the properties of a pooled server object
  • Client applications can change the properties of a non-pooled server object
Pooled server objects are expected to be used in a stateless manner. As a developer, you are responsible for ensuring that the state of the server object, or its associated objects, has not changed when you return the object to the pool (by releasing its context via ReleaseServerContext). Each time a user or application session makes a request to create a pooled server object, it's indeterminate which running instance it will get out of the pool; therefore, all instances must have the same state or applications will experience inconsistent behavior.
A server object is a coarse-grained ArcObjects component that has other associated ArcObjects as illustrated in the following diagram.
 
Non-pooled server objects can be used in a stateful manner. Since non-pooled server objects and their contexts are destroyed when you release them, you need to hold on to them for as long as the state is important to you. When you call ReleaseServerContext, or you allow the server context to go out of scope, the server object and its context are destroyed, purging any state changes you made.

Stateful versus stateless use of server objects

Methods and properties that are exposed by server object interfaces, such as IMapServer and IGeocodeServer, and server object extension interfaces, such as INAServer, are by their nature stateless methods, such as IMapServer.ExportMapImage, IGeocodeServer.GeocodeAddress, and INASever.Solve . These methods do not change any of the properties of the server object when they are called and are safe to call on both pooled and non-pooled server objects. Changing the state of a server object typically involves making calls to get the finer-grained ArcObjects associated with a server object and making changes at that level.
Most GIS Web applications are not stateless. Typically, each user or session will have the following:
  • A current extent
  • A set of visible layers (that can be toggled on and off through the application)
  • Different graphics visible on the map as a result of query operations such as network tracing
It's possible to write a stateful Web application that makes stateless use of server objects in the GIS server by maintaining aspects of application state, such as the extent of the map, layer visibility, and application-added graphics, using the Web application server's session state management capabilities. Such applications are called "shallowly stateful".
The GIS server also supports "deeply stateful" applications that use the GIS server to maintain application state. Examples of deeply stateful Web applications include the following:
  • An application that starts a geodatabase edit session on behalf of a user and works with it across multiple requests in a session to support operations such as undo or redo
  • An application that allows a user to interactively compose a map across multiple requests within a session
Typically, if you're making state changes to server objects, you hold on to a reference context for the duration of your application session, then release the server context immediately after processing the request. You would not perform this type of operation with a pooled server object, as subsequent use of this instance of the MapServer object would reflect that the layer had been removed.
The state of a server object can be changed in a number of ways. The example above demonstrates making direct changes to the properties of a server object—for example, removing a layer from a map. You can also change the state of a server object indirectly through other objects in the server object's context. The following table summarizes the ways that you can change the state of a server object.

Using a method that is stateful on a server object

A stateful method is one that modifies or changes the instance of the server object. There are many examples of stateful methods; two common examples are methods that add or remove layers from a map server object and methods that change a layer's renderer. These methods should never be called on a pooled server object unless the client application can return the object to its original state before releasing it back to the server.

Using a method that is stateful on an environment

Server objects run in contexts that have a number of environment settings associated with them. Some of these environments can be modified by developers. For example, the geometry environment can be manipulated through the IGeometryEnvironment interface. While changes to the geometry environment do not directly affect a server object, those changes can affect other operations that a client application performs using a server object's context.
Changing the state of an environment is valid for both pooled and non-pooled server object use. To ensure that changes to environments do not negatively impact operations made by client applications, applications should not rely on the environment being in a particular state before performing that operation. When performing operations that rely on a particular state of the environment, applications should set the required environment state before performing that operation, especially when using pooled server objects.

Working with cursors

Some objects that are created in a server context can lock or use resources that the object frees only in its destructor. For example, a geodatabase cursor can acquire a shared schema lock on a file-based feature class or table on which it is based or can hold on to an ArcSDE stream.
While the shared schema lock is in place, other applications can continue to query or update the rows in the table; however, they cannot delete the feature class or modify its schema. In the case of file-based data sources, such as shapefiles, update cursors acquire an exclusive write lock on the file, which prevents other applications from accessing the file for read or write purposes. The effect of these locks is that the data may be unavailable to other applications until all of the references on the cursor object are released.
In the case of ArcSDE data sources, the cursor holds on to an ArcSDE stream, and if the application has multiple clients, each can get and hold on to an ArcSDE stream, eventually exhausting the maximum allowable streams. The effect of the number of ArcSDE streams exceeding the maximum is that other clients will fail to open their own cursors to query the database.
It's important to ensure that your reference to any cursor your application opens is released in a timely manner. When developing your application, your reference on the cursor will not be released until garbage collection occurs. In a Web application or Web service that services multiple concurrent sessions and requests, relying on garbage collection to release references on objects results in cursors and their resources not being released in a timely manner.
Garbage collection is the process by which memory is reclaimed from objects that are created by applications. Garbage collection occurs based on memory allocations. Garbage collection occurs when objects that are not referenced are actually cleaned up, which may be some time after they go out of the scope of your application.
When working with Web controls, the controls explicitly manage and release any objects you acquire from the server context. However, for applications that do not use the Web controls (for example an application Web service) to ensure an object is released when it goes out of scope, the ESRI.ArcGIS.ADF.AGS assembly contains a helper object called WebObject. Use the ManageLifetime method to add your object to the set of objects that will be explicitly released when the WebObject is disposed of. You must scope the use of WebObject within a using block. When you scope the use of WebObject within a using block, any object you have added to the WebObject using the ManageLifetime method (including your cursor) will be explicitly released at the end of the using block.

Shallowly stateful applications

As previously mentioned, it is possible to write a stateful Web application that makes stateless use of server objects in the GIS server by maintaining aspects of application state— such as the extent of the map, layer visibility, and application-added graphics—using the Web application server's session state management capabilities as illustrated in the following graphic.
The IServerContext interface has methods that allow you to save GIS objects in session state by exporting them to strings. The server context also has methods to rehydrate the objects from strings as you need them. Objects that support the IPersistStream interface can be exported and rehydrated in this manner.
One example of a shallowly stateful application is managing the user's or session's current extent as it pans and zooms around the map. To zoom in by a fixed amount, the steps are as follows:
  1. Load the serialized map description to get the current map description for the session.
  2. Shrink the extent for the map description.
  3. Draw the map using the modified map description.
  4. Export the modified map description to a string so that the session state is updated.
The objects and interfaces used for managing image display are located in the Carto object library.
The MapServer MapDecription is specifically designed to support programming patterns such as allowing state to be managed in a Web server and applied to the map in a stateless manner as part of the ExportMapImage method.

Deeply stateful applications

A shallowly stateful application means it is stateful, but its state is managed in the Web application server's session state. The GIS server also supports deeply stateful applications that use the GIS server to maintain application state. Supporting such an application requires a server object instance dedicated to each application session. You can configure this by making your server object non-pooled. The server objects necessary for such applications are non-pooled, which limits the number of concurrent sessions by the processing resources of the server.
When programming a deeply stateful Web application, you should use the same server context and server object throughout the session. You need to get a server context at the beginning of the session and hold on to it until the session has ended. The server context is held for the duration of the session and must be released at the end of the session.
The session ends based on a time-out that is set in the application. For example, if the session time-out is set to five minutes—meaning if the user does not interact with the running Web application session for five minutes—then the session will time out, and the server context will be released. In other words, once a user has ended the session by closing the Web browser, the server context won't be released for five minutes (until the session time-out is triggered).
If you are using the Web controls to build a Web application, the Web controls take care of many of these details, specifically, the Map control releases the server context and saves the MapDescription in session state. 

Application state and scalability

The question of stateful versus stateless use of the GIS server is central to the scalability of your application. An application is more scalable than another application if it can support a larger number of users with the same amount of computer resources. The keys to scalability are as follows:
  • Make stateless use of the GIS server
  • Use pooled server objects
  • Minimize the time your application holds on to a server object. Release server objects as soon as possible and do not rely on garbage collection to do it for you.
Using this criteria, it's clear that stateless or shallowly stateful applications can make use of object pooling and, therefore, are more scalable than deeply stateful applications. The question of stateful versus stateless use of the GIS server is critical in designing your application.
Additional information on performance tuning of ArcGIS Server applications can be found in the ArcGIS Server application performance tuning topic.


See Also:

Web controls and the server API