Re: Optimising #include creation of FastWriter

Endre Stølsvik <[email protected]> Mon, 20 Mar 2006 14:47:31 +0100 (CET)
Newsgroups gmane.comp.java.webmacro.user
Message-ID <[email protected]>
  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--0-1619244491-1142862451=:2389
Content-Type: TEXT/PLAIN; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable

On Fri, 17 Mar 2006, Alex Twisleton-Wykeham-Fiennes wrote:

| On Fri 17 March 2006 11:23, Endre St=F8lsvik wrote:
| > On Mon, 13 Mar 2006, Alex Twisleton-Wykeham-Fiennes wrote:
| > | > I do it using _a new_ FastWriter with a temporary backing, then i=
f
| > | > everything went right, I put the result to the FastWriter.
| > |
| > | Do you use a seperate Context for each portlet as well?
| >
| > Yes.
| > But assuming that the Portlets aren't _pure_ evil, this would have be=
en a
| > big thing: I could just have recreated the initial state before each
| > rendering, by using a "weird-long-named" context-var for "my state",
| > hoping that the corelet wouldn't intentially mess things up.
| >
| > But I do make a new Context, due to this concern.
| >
| > | > This temporary backing paradigm obviously isn't the best, and a
| > | > mark/reset/flush paradigm would be much better for my part.
| > |
| > | I can see where you are coming from on this, but it is very hard to=
 state
| > | what the side effects of flushing the FastWriter early and / or rol=
ling
| > | it back to an earlier state.
| >
| > Why is that? This seems completely illogical to me, I can't see at al=
l
| > where you're coming from.
| >
| > If I still make new Contexts, and you understand that each portlet is=
 "on
| > its own" (with a logical separate context too), and if I don't commit
| > bytes to the browser-stream before flush, then "rolling back" is _exa=
ctly_
| > the same as ditching the buffer, _as I do now_.
|=20
| I understand exactly what you have at the moment, and I understand what=
 is=20
| being suggested, but let me just recap for a moment:-
|=20
| - you have a series of portlets.  Currently you are rendering these by=20
| creating a new Context and a new FastWriter, doing all the work and the=
n=20
| dropping the contents of the FastWriter (which will either contain your=
=20
| portlet or your error report) into the master FastWriter.

No, it doesn't contain the error-report. If it fails, I drop the=20
fastwriter, and then actually make another one, which I run the=20
error-template in, and use that (but I could have just dropped it, and=20
rendered the error-template "directly").

|=20
| - you are proposing to save the creation time of a new FastWriter by us=
ing the=20
| master FastWriter for the global template page and resetting it as nece=
ssary=20
| to handle the consequences (I think the use of flush in your mark/reset=
/flush=20
| is maybe what is confusing because flushing by definition drops the con=
tents=20
| of the FastWriter out to the output stream which is probably not what y=
ou=20
| mean).

Flush if it went Okay (as stated repeatedly, I believe?). That way, the=20
user would get the portlets rendered in their browser as they were=20
finished, giving an impression of something happening, even if some stupi=
d=20
portlet later in the line use too much time.

Rollback ("reset") if it didn't, and then render the error-template, and=20
then flush.

|=20
| Now, just for a moment in order to play devils advocate:  supposing tha=
t we do=20
| have this #flush command that Keats mentioned, and suppose one of your=20
| portlet implementors executes #flush inside one of your portlet and the=
 bytes=20
| (both before and after your mark) are flushed out to the output stream.=
  You=20
| then try and do a reset, but the reset point along with all the data be=
fore=20
| and after it has already been sent down-stream.

Why whould i let the user do #flush?

FastWriter.flush() would be good enough for me - I'M THE PORTAL!

The _working_ trio mark(), reset() and flush() is what I'm requesting.

In _production_ environments, where one is very sure about the quality of=
=20
portlets, one could potentially let the #flush actually map to the=20
.flush(), instead of just noop'ing.

|=20
| Personally, I think that you already have a nicely encapsulated safe st=
ructure=20
| for your portlets with a dedicated Context and a dedicated FastWriter f=
or=20
| each portlet.

Me too thinks so! But there is way to much byte-arrays around, and if=20
things goes OK (no errors to wrap), then there is _lots_ of byte-copying=20
that is totally utterly useless. Do you see this point?

I'm not quite sure how the byte-arrays work now, after your fixups (whose=
=20
bugs seem _amazing_ that have been around so long!) - are they still=20
recycled?

See, object creation is rather cheap these days, but it is still faster t=
o=20
_not_ create objects.

And byte-array copies do take _some_ time, most probably unnecessary.

|  Error failure is encapsulated and you don't drop the result of your=20
| parsing / error catching out to your master FastWriter until it is=20
| completed.  If you are concerned about the overhead of generating lots=20
| (1 per portlet) of new FastWriter instances, then I would use just one=20
| FastWriter that is shared between all of your Portlets, and your=20
| sequence would be:-
|=20
| - create Portlet FastWriter
| - foreach portlet in portlets
|   - create new Portlet Context
|   - reset Portlet FastWriter
|   try {
|     - render portlet with Portlet Context to Portlet FastWriter
|   } catch (exception) {
|     - reset FastWriter
|     - render error with Portlet Context to Portlet FastWriter
|   }
|   - write Portlet FastWriter to Servlet FastWriter
| }
| - write Servlet FastWriter to OutputStream

Actually that's what I _believed_ that it did already, due to the=20
pooling/recycling. I still use WM 1.1, so I guess that still holds true?

But btw, isn't the FastWriter thing holding some interal state?

|=20
| Now, you still have all of your encapsulation, your rollbacks work, you=
 are=20
| creating at most one FastWriter beyond where you are, and it really doe=
sn't=20
| matter what happens inside the rendering loop and you don't need to mak=
e any=20
| functional changes to how the FastWriter works.  Or am I missing someth=
ing?

You're missing copying of bytes.

|=20
| (you should also look at the overhead of Context initialisation - HashM=
ap and=20
| ConcurrentHashMap usage are by far the greatest CPU hogs in my tree at=20
| present)

I have my own special Context that have a "lookaside hashmap" that holds=20
the "portal context" (as opposed to "portlet context"), so that the=20
creation of context shouldn't be very heavy.

Thanks for hanging in on this discussion!

Regards,
Endre.
--0-1619244491-1142862451=:2389--


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642