----- Original Message ----- 
From: "Remy Maucherat" <[EMAIL PROTECTED]>
To: "Tomcat Developers List" <[EMAIL PROTECTED]>
Sent: 2002. január 8. 16:35
Subject: Re: nbio connector


> > My primary goal for bringing the code in the public is that I want
> > to build a HTTP/1.1 connector for Tomcat 4.0 based on it
> 
> I don't think you can have a nbio connector with a compliant servlet
> container, because the J2EE spec mandates at the moment: 1 thread <-> 1
> request.

I don't think I conflict with this requirement. In fact, to execute a servlet's 
service() method still requires a separate thread. In my design, the connector first 
reads the request line and the headers in a non-blocking fashion, naturally 
multiplexing up to 63 requests on a single thread. I have a working HTTP processing 
state machine for that. (You simply HAVE to write state machines in nb world, since 
you can't encapsulate the algorithm in a single-thread linear flow of methods because 
of multiplexing). Then it buffers the whole request body using multiplexed 
non-blocking code. This buffering is done using a special non-blocking pipe (more on 
this below). After that, it constructs the request and response objects, and fires off 
container.invoke(req, resp) on a separate thread. The response object also has a 
non-blocking pipe that to the servlet masquerades as a ServletOutputStream.
All this is done with the goal of completely avoiding any thread running 
container.invoke(req, resp) to EVER block on a socket read or write.

A special non-blocking pipe is more-or-less an ordinary pipe: one input stream and one 
output stream, however it does not have a fixed-size buffer (because that would block 
when the buffer gets full), instead it manages a growing list of buffers and can hold 
any size of buffered bytes. It's used both for buffering request body, and for 
buffering the response. The response pipe is written to by the servlet and read from 
by the non-blocking code that transfers its data to the socket channel; so in the 
response phase the pipe buffers that part of the output that the servlet has already 
generated, but that still couldn't get pushed through the network interface. Thus, it 
eliminates I/O block in response.getOutputStream().write(...) calls. As an additional 
memory optimization, it starts buffering in memory, but if the buffered content gets 
large it switches to buffering in a memory-mapped file (also new in JDK 1.4).

> That requirements makes nbio much less interesting over the current since
> you would need a big thread pool.

With my design, you still need one thread/request but only for the time required to 
process container.invoke() (that is, while the filters and servlets run). Since the 
design also eliminates I/O blocking in those threads, they can complete as quickly as 
their code otherwise allows, so the overall requirement for threads is substantially 
lower than in a blocking implementation.

> 
> > , and could
> > use a helping hand here and there. In fact, I already have much of
> > the code for building the HttpServletRequest object, but to keep
> > it really elegant I'll need some help from the Tomcat community.
> > Most notably, much of the code duplications could go away if Catalina
> > code in  org.apache.catalina.connectors.http was more reusable
> > (some classes are package-private and some public classes take
> > package-private classes in a constructor argument etc.).
> > I'll return to these issues on this list after I've properly set
> > up the project on SourceForge.
> 
> Don't use that code, as it is not very efficient / memory intensive, etc.
> Something more useful would be to write a nbio selector for the HTTP/1.1
> connector I'm writing in j-t-c.
> For the connector, nbio is the last optimization which should be done. There
> are much bigger hotspots than the time spent in java.net in the connector
> which ships with 4.0.x ;-)
> 
> Also, why not contributing the thing to the core project (if it manages to
> get around the problem mentioned above, of course), instead of developing it
> separately ?

There are several reasons:

1. It needs JDK 1.4 to compile, and I believe Tomcat should not rely on the 
not-yet-final 1.4 JDK.
I know, this can be dealt with using conditional compilation in the build.xml file, as 
it does now with optional components.
2. My framework as it stands now is a generic framework for implementing arbitrary 
TCP/IP services in a non-blocking fashion. Having a Tomcat connector built upon it is 
only one possible application. SMTP, FTP, etc. servers can also be written upon this 
framework.
3. It would be tedious for me to send in CVS patches over long run. While I have no 
problem with this approach in general (I have already contributed to both Velocity and 
Ant by sending patches to committers), on SourceForge I have my own CVS I can commit 
to right now, and I need this level of control. I don't doubt, that the community 
would grant me committer status on Tomcat over time if I contribute regularly, however 
I plan to work intensively on this code and I fear the inability to have a CVS to 
which I can commit to right from the start would somewhat bog me down.

If the Tomcat HTTP connector comes to life as part of the nbserver project and works 
fine, I'll have no objections to migrating it into Tomcat source tree. In fact, since 
I'm publishing the code under Apache-style license, I *CAN NOT* have any objections if 
it ever gets transferred into Tomcat source tree - either with or without my 
assistance. :-)

Cheers,
  Attila.

> 
> Remy
> 
> 

Attachment: smime.p7s
Description: application/pkcs7-signature

Reply via email to