Despite HTTP a stateless protocol, the statefulness is required to be achieved for any enterprise web application. The reason is we cannot meet real life business requirements in a single HTTP request. To simplify the task of data input and to be able to gather only required data from the end user, a business requirement is divided into smaller steps. Each of these smaller steps have well defined previous and next step expecting some sort of user interaction like data input or confirmation to proceed. As each step needs to return a response to the user so every step is technically equivalent to a request-response cycle. To be able to track the entire business process/flow the information need to be remembered in between the steps by achieving statefulness somehow. This task is often at the hands of application developers to support multi-step processes. However, Oracle Fusion Applications uses ADF has powerful state management architecture built into the ADFbc. Most of the work happens behind the scene without requiring any developer intervention.
In ADF, application module (AM) is the logical unit that holds the transactional state. Hence, state management feature is also implemented at the AM level. In ADF, AM automatically stores the current state into the database and the process is referred as ‘Passivation’. Passivation is mandatory to manage the system resource efficiently which is application module instances in this case. As soon as user login happens an AM instance is assigned to the user session. It is practically impossible to have as many AM instances available as number of users due to server memory limitations. An AM instance is not used for the 100% of the user session time and hence stays idle during that time. During this idle time, the AM instance is used by AM pool manager to serve other users thereby, making it possible to serve more users than the AM instances. However, AM instance need to remember the state of the user session it is associated with. So, to be able to reassign the AM instance to another user session it becomes mandatory to persist the data to the DB which is referred as Passivation.
The exact reverse process of restoring the state from the database is referred as ‘Activation’. The Fusion Apps Developer Guide
cover the details on it. To summarize the standard ADF behavior is as follows:
- HttpSession keeps an ADF binding context object in it for each user. This holds a light-weight data control object for AM pool management.
- At the very first user request to the server, data control looks for an unreferenced application module instance from the pool.
- At the end of each request cycle the application module instance is checked back to the pool and the data control just maintains a reference to it.
- For every subsequent request from the same user, data control tries to allocate the same application module instance used at the previous request from the AM pool.
- If the previously referenced AM instance cannot be allocated and there is no unreferenced AM instance available then the data control tries to save the state of one of available AM instance from the pool to the database(it will be referenced by some other user session but not in use at this moment). This process of saving is called ‘Passivation’. Once passivation is completed this instance is then made available to the new request.
- If an earlier referenced AM instance is not available to serve the current request then data control pick another AM instance from the pool and loads the application state to it before making it available to the request. This process is called ‘Activation’.
Oracle Fusion Applications take one step forward and force the data control to do passivation at the end of every request cycle and activation at the beginning of every request cycle by setting the jbo.dofailover flag to true in AM properties. This provides a very pessimistic protection against application server failures.
Testing Passivation in an ADF Application
A later post about passivation will explain about handling the custom business specific data while passivation-activation cycle to avoid undesirable results. So, it becomes important to test those scenarios during development. As mentioned earlier, the passivation is triggered by AM automatically when an AM is checked into the AM pool. In the development environments when a couple of developers are only involved, the testing of passivation-activation would be difficult as it is not controlled by the developer and happens only when the AM is checked into the AM pool. The AM is not checked into the AM pool unless it is destroyed explicitly or there is no free AM instance left in the pool to serve a new request (which will force the AM pool manager to allocate one of unused AM instance at that moment). So, to trigger the passivation there are following options:
- Limit the Pool size:
You can limit the number of AM instances to just 1. As a result, whenever you will login to the application from another session the passivation will occur. To do that go to the AM configuration → Pooling & Scalability and set the maximum pool size to 1.
2. Force frequent cycles:
You can force the passivation to occur at the end of every request like Fusion Applications does by setting the jbo.dofailover flag to true. This option is also accessible in the Pooling & Scalability section as mentioned in point 1.
3. Adjusting Timeouts:
Third way is to set the Idle instance timeout as well as the polling interval to a smaller number. By default it is 10 min. If you set it to something like 1 min then after 1 min of inactivity will cause the passivation to start. Please note that this won’t work if there are already other free AM instances available in the pool.
Below is a screenshot showing all the AM properties discussed above: