appendToResponse in a separate thread (outta context)
appendToResponse in a separate thread (outta context)
- Subject: appendToResponse in a separate thread (outta context)
- From: Ondra Cada <email@hidden>
- Date: Wed, 23 Jul 2008 15:02:58 +0200
Hello all,
I have to update an old WO application to be more responsive. I have
found that there are a lot of pages there whose appendToResponse is
just plain too slow. Since re-writing them all to be either snappier
or to use explicitly LongResponsePage would be quite a task I could
do without, I've considered the following pattern:
(a) giving all the slow components a common superclass, say,
OCSLongResponserBase
(b) exploit a similar technique LongResponsePage uses in this
superclass, but running the appendToResponse in the thread; thus,
making them all "long response" at once.
Essentially (without logs, error/exception checking, invokeAction,
etc.) the OCSLongResponserBase skeleton is pretty plain:
...
private Thread longResponseThread=null;
private boolean _threadIsDone=false;
public void run() {
super.appendToResponse(_cachedContext.response
(),_cachedContext);
_threadIsDone=true;
}
public void appendToResponse(WOResponse rr, WOContext ctxt) {
if (longResponseThread==null || Thread.currentThread()!
=longResponseThread) { // in the main worker thread
boolean haveOriginalResponse=false;
if (longResponseThread==null) { // first time here,
let's create the thread
// 1: cache original response/context/session so
that it works in the thread: that's the problem
haveOriginalResponse=true;
_threadIsDone=false;
(longResponseThread=new Thread(this)).start();
}
if (!_threadIsDone) { // first or any other time here
whilst thread runs
int refreshInterval=1;
if (haveOriginalResponse) refreshInterval=0; // not
to display partially filled original (cached) response
else rr.setContent("JUST WAITING..."); // not to
override contents of the original (cached) response
String url=ctxt.urlWithRequestHandlerKey
(WOApplication.application().componentRequestHandlerKey(),null,null);
String hdr=""+refreshInterval+";url="+url
+"/"+ctxt.session().sessionID()+"/"+ctxt.contextID()
+"."+WOMetaRefreshSenderId;
rr.setHeader(hdr,"refresh");
} else { // thread finished, last time here
// 2: copy original (cached) response content to rr
(and free cached objects)
longResponseThread=null;
}
} else // in the long response thread
super.appendToResponse(rr,ctxt);
}
The problem is context/response caching at //1 and //2: the idea was
to save the response at the beginning when the long response thread
is launched, make its (nested) appendToResponses to write there, and
at the end just to copy the complete result to the response in the
main thread. To do that, context/session need to ba cached, too (or
it seems).
What I cannot figure is _how_ to cache them so that this works: all
my attempts (lots and lots of different combinations of overridden
context() and/or session() in a shared superclass of all components,
so that whenever any component uses them in the long response thread,
it gets the cached context/session; overridden
createContextForRequest/createSessionForRequest in Application so
that in the long response thread they do not create anything but
return the cached objects, etc.) so far were in vain.
The threads run precisely as intended, but the response generation in
the long response thread does not work: seems the framework accesses
some extra context which I forget to (or don't know how) cache or to
"enforce" inside the long response thread. The actual result in the
cached response seems somewhat random, from a completely empty
response to a partially created page, I suppose depending on a timing
of the long response and main threads.
Has somebody already solved this (or similar) problem (or, at worst,
proved it unsolvable)?
Oh, a propos, WebObjects 5.3/Tiger, if that is important.
Thanks,
---
Ondra Čada
OCSoftware: email@hidden http://www.ocs.cz
private email@hidden http://www.ocs.cz/oc
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden