Thanks for your excellent explanation!

This may stray off topic for tomcat, but I have been wondering how this (nio) would play out in XSL transformations in a servlet container.

Are you familiar with using custom URIResolvers [see below for an example scenario] in XSL transformations?

-- Briefly, you can assign a resolver to TransformerFactory which will resolve xsl:import/includes. Then you derive and cache a Templates object off of that, so nio might not give much advantage since building the Templates object grabs files once and it gets cached.

-- You can also set a resolver on the Transformer object (which is derived from the cached Templates object). The Transformer object is unique for each transformation and it resolves calls from the XSL document function.

We (an ASP content management system) use the Transformer resolver to gather (/aggregate/) content pieces and metadata files to be used in the transformation. In some case there can be large number of document() calls to gather XML files. I haven't had a chance to get into nio yet and was wondering if you (all) had opinions on this?

thanks,
-Rob

[example]

A source XML might look like:

<regions>
  <region nameref="wideMiddle">
    <content idref="piece1.xml"/>
    <content idref="piece2.xml"/>
  </region>
</regions>


An example XSL would look like:

<!-- page wrapper stuff -->
<xsl:apply-templates select="/regions/region/content"/>
<!-- page wrapper stuff -->

<xsl:template match="content" mode="aggregator">
  <xsl:apply-templates select="document(@idref)/*"/>
</xsl:template>


An example resolver might look like:

private static final String FNF = "<fnf/>";
private Project project;

public TemplatesResolver(Project proj) {
  this.project = proj;
}

public Source resolve(String href, String base)
    throws TransformerException {

  File file = this.project.getContentFile(href);

  if (file != null) {
    return new StreamSource(file);
  } else {
    return new StreamSource(new StringReader(FNF));
  }
}




Will Hartung wrote:

From: "Vy Ho" <[EMAIL PROTECTED]>
Sent: Tuesday, November 02, 2004 3:03 PM


I checked this document:

http://www-106.ibm.com/developerworks/library/j-nioserver/

and it talks about how wonderful new io could help server to serves
higher number of connections and less error/drop connections.

Is it true in practice?  Does Tomcat 5 uses new io of just io?  If not,
do they plan to move to this?


The dillema is that the Servlet Model as defined in the specification
doesn't work well in the kind of environment provided by NIO, so it's
difficult to say whether something that handled the semantics of a Servlet
written using NIO would actually be any faster at all.

Now, technically, if one were so inclined, you could implement that bits
that handle static content with Tomcat to, perhaps, use the nio model and
maybe get a bonus for a pure Tomcat, yet static heavy, site. But since most
folks simply Don't Do That (i.e. if they're distinguishing static content at
all, odds pretty good that they're fronting Tomcat with Apache anyway...),
there's little motivation to engineer Tomcat to support NIO for simply
static content.

Servlets are pretty much thread based, being as they can perform arbitrary
calculations. Also, Servlets can, technically, access the input and output
streams of the request directly. Many servlets don't need that kind of
direct access. For example, most simply use the request headers and
parameters rather than the input stream itself.

NIO based servers are essentially event driven, with the sockets and IO
channels being a dominant source of the events. The NIO server repeatedly
checks the two ends of a request (the source and the sink, for example, the
input stream and server logic). When the source has data ready to read and
the sink is ready to take data, the NIO server grabs a chunk from the source
and feeds it to the sink, and then moves on to the other sources/sinks
within its queue.

The main thread of an NIO server can NOT block waiting for something to come
ready, as it will stall the entire server (because none of the other
requests will get serviced). If you're simply moving data from disk to a
socket, this works fine because OS's offer asynchronous IO calls and make
available routines which an NIO server can use to see "who's waiting" and
needs servicing.

But exposing that "is it ready" interface to arbitrary logic like that
within a servlet is difficult. If the code is very short, it's no problem at
all. The code is "always" ready and essentially returns immediately. But if
it's doing anything more than that (say, contacting a database), then things
get more ugly very quickly. The IO drivers of the system are asynchronous
without directly using a user level mechanism like threads, so they're
asynchronous "for free". But if you want user written logic to have an
asynchronous behavior, we typically turn to threads to provide that for us.
But, the strength of the NIO model is that the requests it manages within
its internal queue have simple state than a thread, and therefore switch
from request to request is much cheaper (and therefor faster) than using the
JVMs thread scheduler to switch between threads.

But if the NIO server needs to spawn a thread to get asynchronous behaviour
from an arbitrary Servlet, then most of the benefit of the NIO architecture
is lost.

Servers can certainly be written this way. Servers can perform all of the
things that a Servlet can provide. But the fine grained event model is much
different than what the Servlet specification provides, and it would also
require that all calls be basically event based, particularly calls to
things like DBs.\

Regards,

Will Hartung
([EMAIL PROTECTED])


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to