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]
