tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Filip Hanik - Dev Lists <>
Subject Re: Comet changes
Date Mon, 07 May 2007 15:40:33 GMT
Remy Maucherat wrote:
> Filip Hanik - Dev Lists wrote:
>> 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 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.
> This is interesting, and it's giving me some (basic) ideas. I think it 
> (at least part 2) is too much about reading, where non blocking and 
> blocking are functionally equivalent due to the events which allow 
> knowing when read will not block.
> In theory, 1 is more interesting, but not with the casting and API 
> hacking. It is perfectly legitimate to use Reader/Writer, so adding 
> calls which bypass the standard does not seem like a good idea. Maybe 
> it could work with an IO control feature on the event (a canWrite 
> method or something; the low level would use non blocking writes, 
> buffer a little bit, and expect the user to use canWrite to check the 
> result of the last real write to the socket; if the user keeps on 
> writing without checking canWrite, throw an exception), to go along 
> write events (which is a problem: I don't know how to request to be 
> placed in a poller, although maybe another method on the event could 
> work), and maybe it would be enough.
To get it to the poller one could do
event.notify(OP_WRITE) -> notify me when I can do a write. this would 
result in an event with EventType=NOTIFY EventSubType=WRITE
same to get notified of a READ event in the case of not being registered 
with the poller.

I thought about the canWrite idea earlier, and there is a difficult 
problem to get around. the steps are
1. canWrite - returns true
2. response.getOutputStream().write(8k byte array)
3. only 2k gets written during the non blocking write

so what does one do? does it issue a blocking write for the remainder? 
it gets quite tricky.
that is why the cast/API hack (which can be done for both reader/writer 
as well as input/output streams) is a clearer way.

so non blocking read, is pretty easy to accomplish, but non blocking 
write is very difficult using the regular API as you may write partial 
data, regardless of what method we use to do this.

any thoughts on this.

> > got it, the extra bytes, if that is a new request, ie "GET /
> > HTTP/1.1..." will that work?
> Yes, that's pipelining. The extra bytes are supposed to be a new request.
> Rémy
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message