Hi Gurus,
Have an interesting scenario. To cut the long story short, in our scenario, the browser requests are routed to our server through Akamai, which is a 3rd party array of servers that are spread over geographies and cache static content, in order to ensure the request is routed through the nearest Akamai server to our WLS server. Akamai timeout threshold is maxed at 15 minutes. One of our transactions are time intensive and runs between 20-25 minutes. As you would have guessed, the connection is idle until process completes, akamai timeout is kicking in and closing the connection. Hence browser throws a javascript alert saying 'A connection to the server has failed'.
Q) So, the direct question is, is there a mechanism in ADF to send heartbeat or ping signal to the browser periodically so that the connection will be kept open.
We built a simple POC and beat Akamai timeout, by spawning a thread on server side that keeps writing a heartbeat signal something like "<!-- heartbeat -->" into ServletOutputStream periodically, just before invoking the long-running-proces. We could successfully beat Akamai timeout, but the problem is finally when the long-running-process completes and ready to proceed with rest of lifecycle, it fails with the popular exception "Response that is already committed". Though the error can be prevented by ctx.responseComplete(), it throws a blank page.
Couple of things puzzling us:
1) Why not simple ADF continue with rest of lifecycle phases and write to the same outputstream , in which case "response already committed" exception will not happen
2) Is ADF internally doing any redirect ? Because it is a command button (Non-PPR) that initiates the entire call.
3) Any other suggestions or best approaches or tweaks are appreciated
JDEV Version: 11.1.1.3
Code snippet is as follows:
FacesContext ctx = FacesContext.getCurrentInstance();
HttpServletResponse resp = (HttpServletResponse)ctx.getExternalContext().getResponse();
HttpServletRequest req = (HttpServletRequest)ctx.getExternalContext().getRequest();
ServletOutputStream out;
hbThread = new HeartBeatThread();
Object result = null;
try {
out = resp.getOutputStream();
hbThread.setOut(out);
OperationBinding binding = ADFUtils.getOperationBinding("copyQuoteStub");
// -- heartbeat thread started
hbThread.start();
// -- Long running process invoked
result = binding.execute();
// -- Long running process ended
// -- heartbeat thread stopped
hbThread.stop();
ctx.responseComplete();
Heartbeat thread code:
public void run() {
while(sendHeartbeat) {
try {
System.out.println("...............BKB::Heartbeat Thread heartbeat " + new Date());
out.write(heartbeatSignal.getBytes());
out.flush();
Thread.currentThread().sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
Thanks a ton
Srini
Edited by: sangara on Mar 21, 2013 8:45 PM