Remy Maucherat wrote:
Hi,
To summarize, I propose the following additions in the Comet
functionality for the next Tomcat 6.0 release (the various names are
proposals, I am not very good at names):
- per event timeout becomes mandatory
per event or per connection?
- small refactoring of the timeout callback using an action code
rather than a request attribute (the reason for using request
attributes for sendfile is because I needed it in the Servlet layer,
which doesn't have access to the action callback)
+1
this would be perfect, cause it would mean I can change the timeout
anytime (even async), currently you can only do it during an event from
a worker thread.
- refactor a bit the poller for the APR endpoint and add per
connection timeout support; I also don't like the multiple poller
threads design anymore - it is only useful on Windows, and would be
replaced by using a single thread with multiple pollers and a shorter
pollTime
+1, the easier the better
- notify method on the event (wakes a connection from the endpoint,
and invoke a NOTIFY event)
- add NOTIFY as a new CometEvent.EventType
+1
Excellent.
- add a CometEvent.disableReadPolling() method which will signal that
the connection should not be put in the poller, but should still be
checked for timeout
ok, when would it be legal to call this method? can you call it async?
or only during an "event"
calling it async, with NIO it still has to "register" a runnable and the
poller thread has to do it, which could cause some funky concurrency
behavior.
To work around this, one could call event.notify(), and when the NOTIFY
event arrives, one could call disableReadPolling().
Would this be acceptable?
- EOF as a new ComentEvent.EventSubType, subtype of
CometEvent.EventType .END (will be called when the endpoint signals a
read); after getting this event, the CometAdapter could automagically
call CometEvent.disableReadPolling() to avoid problems if the client
somehow sends additional bytes (they don't belong to this request)
how could the client send "additional bytes" when an EOF happens. EOF
would only happen if the client disconnected, ie read() returns -1 on
the socket.
- possible improvements for available() to be proposed by Filip
ok, here we go, I have thought about this and have two different proposals.
1. Add non blocking support to Coyote(In|Out)putStream
The servlet can cast request.getInputStream() to a CoyoteInputStream
Example:
//perform a non blocking read.
int read = ((CoyoteInputStream)request.getInputStream()).nbRead(buf);
if ( read > 0 ) //we have data
else if ( read == -1 ) //eof, in NIO it actually throws EOFException
else // move on, read returned 0
Same support for writing.
Basically, the CoyoteInputStream.read would return the actual number of
bytes available to the servlet. not the number of bytes by the socket.
So the read would have to filter through the chain, and the entire
buffer chain would have to support this, I think this is all doable.
2. Alternative - expose nbRead through available() method
If we don't want to expose nbRead or nbWrite by casting to an interface,
we could always make
available() as a non blocking read. available() would return the actual
number of bytes for the servlet.
should available() return >0, then request.getInputStream().read()
should return the same number of bytes the return value for available().
Basically, available() invokes a non blocking read from the socket. then
the bytes get passed through the buffers.
If some buffer requires additional data, it will not invoke a blocking
read, instead available() will return 0.
request.getInputStream().read() - if the top most buffer has data, it
will return it immediately, and not invoke the chain down.
If there is no data, this becomes a regular read.
This solution lets us do a non blocking read using the existing API, but
has no solution for a non blocking write.
I'd be happy to take a stab at this, and if we don't like it, we can
throw it away. I think it is easier for me to show it through code, than
through an essay in an email.
Just give me a feel for option 1 or 2, and I will take one of them, and
do it this week, by the end of week I can have one option completed for
testing.
These should be relatively easy to implement, and should allow
supporting additional use cases.
ok, as I see your checkin's I can make the adjustments for NIO. Poller
behavior is different there, we only use one poller, and one poller thread.
I will not propose any non blocking IO changes at this time, as I
don't have a solution where the complexity would not increase quite a
bit for both Tomcat and the "Servlet" code. So since it is blocking
IO, certain uses will still need to make use of more than one thread
for output (to compensate for the risk of blocking).
I can work on this in parallel.
Comments ?
thanks for putting this together. I'm on GMT+1 time for the next 5 weeks.
Filip
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]