Some testing related to “RenderHint=background” and “contentDelivery=lazy”

In JDev v12.2.1, I create a simple testing jsf page which contains one af:table and some dummy af:output components, I change af:table’s “contentDelivery” to “lazy” and change table iterator’s “RenderHint” to “background”:
RenderHint=background
Run the page and inspect it in browser:
requests
As shown in the above picture, the browser will issue two requests, the 1st request’s response will render the non-lazy components first, the browser will issue another HTTP request to fetch the data of the table. If there are multiple such af:table, the second request will include all the table’s id in the URL. This means, for example, if there are three such af:table, the browser will still issue two HTTP request in total (excluding those resource request like image, css, js etc). The server will response the 2nd request using HTTP streaming technique, this conforms to the ADF documentation below:
renderhint_doc
(URL:doc url)
I noticed that above behavior will not occur if the af:table has “scrollPolicy=page”. Moreover, above documentation seems giving an impression that we could run queries in parallel, so I did some experiments. Firstly, I created two VO “EmployeeVO” and “DepartmentVO” with two slow query (let’s assume the SQLs are not using any parallel SQL hint):
departmentVO
employeeVO
Where “make_me_slow” function is:

CREATE OR REPLACE FUNCTION make_me_slow( p_seconds in number )
	RETURN number
	IS
	BEGIN
	dbms_lock.sleep( p_seconds );
	RETURN p_seconds;
END;

This will make the sql take 5 seconds to return. (I also tried slow sql without DBMS_LOCK.sleep function, the result is same.)
Then, I overwrite the VO’s “executeQueryForCollection” method:
vo_method
I put the two VO in two different AM (MyAM1 and MyAM2, so two DB connections are expected to be used for each test) and tried following different combinations:
1. drag drop two table into same page, mark both table as “contentDelivery=lazy” and iterator “RenderHint=background”
2. drag drop two table into same page, mark one of the two tables as “contentDelivery=lazy” and iterator “RenderHint=background”
3. create two regions, each region contain one table, mark both table as “contentDelivery=lazy” and iterator “RenderHint=background” (The region’s task flow is “Always begin new Tx” and data control “Isolate”)
4. create two regions, each region contain one table, mark one of the two tables as “contentDelivery=lazy” and iterator “RenderHint=background” (The region’s task flow is “Always begin new Tx” and data control “Isolate”)
For all above tests, I changed iterator’s “RowCountThreadhold” to “-1” since I don’t want the count query to disturb the test. The output from “executeQueryForCollection” for all above combinations is always:
log
That means the VO’s query is always executed sequentially by same thread, even for different data control frame and different root AM, each query take 5 seconds to finish. I am not sure why it’s always the same thread, is it because thread-session affinity, or is it because HTTP keep-alive so same TCP connection is reused and thus the same thread is reused. It always requires 10 seconds to finish rendering the page. I also observe that in some of the combination, the behavior is the page will be rendered entirely firstly, then the browser starts fetch table data, it takes 5 second to fetch first table’s data and another 5 seconds to fetch 2nd table’s data. This is indeed already very good, it’s the best result we could get. Since the queries are executed sequentially, we don’t need two root AM and regions to achieve this, we just need one AM. Maybe, the result could be improved if one of the data control is non-SQL based data control, like web service data control etc.

The next test is a standalone test (not weblogic related). I open one single connection using JDBC thin driver and share it among two threads, 1st thread will run the slow department SQL, 2nd thread will run the slow employee SQL:
junit
The result is always either:
result1
or
result2
I.e. shortest time to finish both SQL is 10 seconds, it can never be 5 seconds to finish both SQL, this is even worse than executing them sequentially since both SQL could possibly take 10 seconds.

The last test is an attempt to run the 2nd SQL asynchronously myself to reduce the entire page rendering time to 5 seconds, the pseudo code is like:

  //in somewhere do following:
  HttpServletRequest req = ...
  AsyncContext ctx = req.startAsync(); //This line causes issue as JSF v2.2 doesn't support this
  ctx.start( new Runnable(){
       //do 2nd SQL via MyAM2 with JDBC connection 2
  }
  //do 1st SQL in MyAM1 with JDBC connection 1
  if(both finish) ctx.complete();
  ...

JDev v12.2.1 is based on JSF v2.2 spec which doesn’t support async request, so the clause “req.startAsync()” will cause an fatal application error.

PS: I personally don’t prefer using “RenderHint=background” and I only use af:region when it’s really necessary. I am a fan of SQL optimization. Optimized SQL could run very fast even on tables with multi-million records, “contentDelivery=immediate” could work very well.