Friday, June 29, 2012

Immediate Effect for ADF Table Content Delivery

During stress load, we noticed complex ADF pages on load may produce more than one ADF passivation/activation events. This may decrease performance, because passivation/activation involves additional database calls plus ADF framework rendering functionality gets slower. We managed to debug one of such complex pages - this page was rendering many small tables in the same single page. During page load, it stress load environment, it was producing multiple activation/passivation events.

The trick was in Content Delivery setting for ADF Table component. By default this setting is set with whenAvailable value. While it works correctly, in some cases it may bring side effects for performance.  If you notice slow performance for ADF table rendering - double check Content Delivery property for ADF table. We would recommend to set it to immediate.

This is not only ADF table performance rendering, there might be additional huge side effect for system performance based on ADF table configuration. Imagine - ADF table rendering is triggering multiple activation/passivation events. In turn this triggers multiple prepareSession() method invocations. Very often we call DB PL/SQL initialization logic from prepareSession() method. If invoked PL/SQL logic is complex, it will be invoked multiple times with table rendering and this will make your system slow.

Download sample application - MultiTaskFlowApp_v2.zip.

Sample application is set with disabled AM pooling, to spot how it will be have in stress load environment:


prepareSession() is overriden in AM implementation class to track how many times AM is initialized (during activation/passivation events):


Sample application contain standard JSF page with out-of-the box readonly table component (all property settings are default):


Run sample application, it will load and invoke prepareSession() two times:


Set table ContentDelivery to Immediate - it will invoke prepareSession() only once on stress load and complete only one activation/passivation event:


1 comment:

Riccardo Frezza said...

Hi Andrejus.

I am facing the problem you talk about here and I found your article interesting.

In my application I have a page in which I put an af:table component.

I must premise that I am not using Datacontrols, but the table is bound to a List reference contained in a custom session bean, as shown below:





...

The bean code:

...
private List listOfDataFromDB;
...
public List getListOfDataFromDB() {
listOfDataFromDB= facade.getValuesFromDB(filter1,filter2,filter3,filter4,firstRow,rowsPerPage);
System.out.println("getListOfDataFromDB");
return listOfDataFromDB;
}

...

As shown in the bean code, I changed the list getter method putting inside it the code to get the data from db.

Because the page load was very slow, I put a print line in the method, and I found out that the getter method, of the list which the table is bound to, is called many times (around 8 times) causing a massive performance reduction. This happens with all the lists declared into the page, even those whose the getter method in the bean does not make any db call.

And moreover, this thing happens independentely that the "contentDelivery" property value is set to "when available" or "Immediate".

Reasoning on it, I got to the conclusion that probably I am making some mistakes, and there must be another way to make the table be loaded the first time, from putting the db call into the getter method.

I would really appreciate a point of view from your side.

Thank you

R.F.