I think Costin has summed up the situation very well, in terms of the
control/data issue.  As the person who originally suggested thinking about a
separate data channel, I am now strongly leaning away from that.  The
various complicated threading/process issues are not worth the grief.  

The only thing we really lose is the ability for the servlet engine to send
a message to TC in between requests.  And the main messages, as I see it,
are:
 
   a) the entire engine is shutting down 

   b) certain contexts are shutting down 

   c) certain contexts are now live

Henri, you're trying to cover that via the AJP_STATUS cmd, which the engine
writes to the socket at the end of a request-handling cycle but which the
web server only reads when it next goes to send a request over.  Unless I
misunderstand, the main reason for that delay is so that if the engine shuts
down, and the socket dies, the web server will find out immediately (rather
than sending across a request and only finding out on the subsequent read). 
[Socket trivia -- will this written-but-unread data cause any trouble during
the TC shutdown process?]

That part makes sense.  However, you're also suggesting using that status
command to send over config information via AJP_CONTEXT_(DOWN|UP|OK).  I
*do* like the idea of the engine sending over some control information at
the end of every request-handling cycle, but I have two suggestions:

 1) Don't use APR or OS-specific functions to see if there is more data. 
Instead, make a normal ajp13-style packet with a type of ajp_status_cmd, a
length and a payload.  That way you can fit arbitrarily large data (large
numbers of changed contexts or config information, for example), and take
advantage of the current ajp13 packet-handling functions.  Conceivably, you
could even set it up so that mod_jk could accept those packets *during*
request handling, as well as at the end.  

BTW, currently, ajp13 sends over a single byte of status, which determines
whether or not the connection should be reused.  We'd basically just be
expanding that.  I like that idea a lot.

 2) Have the web server read that config data immediately, but always have
an extra dummy byte (or whatever) of padding at the end which the server can
hold off on reading until the next request.  That way, config information
will flow up into the web server as soon as possible, and the logic will be
much simpler (e.g. you won't get a situation where the server is about to
forward a request and only then reads the config info which tells it that it
can't forward that request).

Then we just have to set up the Java code so that the context change
information can get passed into an ajp13 thread which is servicing requests
(so that it can tack it onto the end of the request cycle).  Questions: what
if multiple instances of Apache are forwarding requests to a single TC
instance?  How can TC "know" that?  It has a single master socket, and then
it hands off live sockets to individual threads, which hang onto them over
many requests.  If some of those threads are serving Apache 1, and some are
serving Apache 2, then we have to make sure that the context change info
goes into one thread from each group.  And then on the Apache side, we have
to bubble that config information up so that all the separate child
processes change their config setup.  (Is this true?  Does Apache work
differently than this somehow?)

That sounds complicated.  How is this handled in mod_webapp?  Anyone?

-Dan

[EMAIL PROTECTED] wrote:
> 
> > Argh, all the subtility is here.
> > Basically even if ajp13 is a bidirectional protocol,
> > it's a request/reply protocol since it's how a web
> > server function :
> 
> > 1) FORWARD REQUEST FROM WEB-SERVER TO SERVLET ENGINE
> > 2) WAIT FOR RESPONSE
> > 3) GET RESPONSE AND FORWARD TO WEB-SERVER.
> 
> Well, I see it a bit different :-)
> 
> 1. Apache sends a message to tomcat with the original request
> ( or part of it ! - for example it can send only some headers that are
> commonly used ), then start waiting.
> 
> 2. Tomcat receives the message, start processing. When he needs something
> from apache ( like sendHead or get info or auth or admin commands ) it
> sends a message, then start waiting.
> 
> 3. That goes on, with a message acting as a token. At any time one side is
> listening, and the other ( who reveived the last message ) has the
> control.
> 
> In a way it's like a single "virtual" thread of execution, with the apache
> thread and tomcat thread passing control via messages.
> 
> Now, I know this sounds complicated - but it's a good solution with very
> little overhead. This is not a general RPC protocol, but something
> specialized for tomcat, and it works very well with single-threaded
> processes.
> 
> Even in Apache2.0 - creating threads for each tomcat callback and using
> additional sockets is significant overhead given the time constraints.
> 
> The problem is that the "admin" commands can be passed only on certain
> moments:
> - when apache connects for the first time ( the socket will be kept open )
> - when apache sends a request
> 
> I think that should be enough for what we need - if we make it more
> complex we may add too much overhead. ( and we may not be able to have
> good  support for Apache1.3 )
> 
> We allways have the choice of using a "real" ORB - so there is a limit in
> AJP's complexity ( when it starts having all the features of an ORB, we
> shoud just replace it with a real one :-)
> 
> Costin

-- 

Dan Milstein // [EMAIL PROTECTED]

Reply via email to