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 Wed, 09 May 2007 01:33:20 GMT
Remy Maucherat wrote:
> Filip Hanik - Dev Lists wrote:
>> Here are some changes.
>> 1. The background thread should not have to call notifyWrite, since 
>> we provide READ event, we can also provide
>>   an automatic event is thrown when a write completes 
>> EventType=NOTIFY EventSubType=WRITE_COMPLETE, as soon as the write 
>> does complete
>>   One exception, if the write completes on the first write attempt, 
>> canWrite returns true immediately after outputstream/writer.write(...)
>>   It is easier to implement, as we don't have to keep track of if 
>> they want to be notified or not.
>>   So basically, outputstream.write() -> canWrite==true -> we finished 
>> writing everything
>>   and in the same fashion, outputstream.write() -> canWrite==false -> 
>> we can expect a NOTIFY event
>>   canWrite should measure the length of bbuf, that's the easiest way 
>> to know if we can write or not
> I agree, but I don't understand how you can know if you can write 
> without a write polling. If there are no events on read, I have the 
> impression writing could be suspended for an indefinite amount of 
> time. So if it works, I am fine with this process.
In NIO, you basically can call SocketChannel.write anytime you want, it 
will return 0 if you can't. At the time of returning 0, you simply 
register it with the poller so that the poller notifies you when a 
SocketChannel.write actually will succeed. ie, you don't need a poller, 
you could do a spinning SocketChannel.write until it succeeds, of course 
this will suck up your CPU. Does that make sense?
>> 3. Since a write can timeout, and event ERROR/TIMEOUT might happen 
>>   This is one case where ERROR/TIMEOUT should close the socket, and 
>> that is why I think it should always do it
>>   regardless of have we do it now. Keeping a connection open after a 
>> TIMEOUT is not good, cause it makes it so much harder to clean up
>>   In a write timeout, we have data left in a buffer
> I don't want to do any special funky tracking of writes in the APR 
> connector, so I disagree with this (feel free to keep it in the NIO 
> connector if you want to, I'm fine with that). It's also a gratuitous 
> action which does not provide a real benefit.
funky tracking? ie, as keeping track of timeouts? Not sure how you are 
gonna implement "per-connection" timeouts without it?
Definitely a write should not be indefinite, it should timeout, just 
like a servlet write does today for servlets.

>> 4. Implementation detail, in TC 6 the buffers are sent in a separate 
>> flush to the socket
>>   Can we just merge this with the first servlet flush or automatic flush
>>   This will simply send the response headers with the first data for 
>> the response, hence be included in the
>>   "non block" write logic without further workarounds for that.
> I believe the number of writes should be kept as low as possible.
Exactly, today you are doing two when it can be done using one write.
>> 5. non block read
>>   After thinking about it, and since we send "events" when data is 
>> available on the socket
>>   I don't think we should enable them.
>>   The only time a non block read, would be in Comet connections that 
>> are in:
>>   a) the connection is non block mode &&
>>   b) the connection is not registered for a OP_READ with the Poller
>>   Because of the concurrency problems that can arise from non-block 
>> read and the connection being registered for READ with the poller,
>>   this feature is actually better if it is left implemented as it is 
>> today.
>> 6. READ event
>>   However, there is a need to modify the read, currently the 
>> CoyoteAdapter will end up in a blocking read if not enough data
>>   has been fetched that is needed for the filter.
>>   The filter should be able to back out, so that the connection gets 
>> returned to the poller to retrieve more data
>>   Bottom line is that Comet threads should never call 
>> unless it is a READ event
>>   If we feel there is a need, we can make non block read available to 
>> the servlet, although I see that lower priority than the write
>>   stuff and the blocking
> I don't think you can have non blocking writes and blocking reads (at 
> least I don't know how to do it with APR). I wanted to point out that 
> non blocking reads and blocking reads were almost equivalent.
NIO you can, but I'd like for the connectors to be consistent. blocking 
and non blocking reads are very different.
For example, today, locks up in a blocking read, easy 
to reproduce, if a filter needs more data to do processing upon a READ 
You can easily lock up a whole server, making it a subject to a denial 
of service.

What I am saying is that we shouldn't allow the servlet to do a 
event.getHttpServletRequest().getInputStream().read() if the socket is
registed for a READ event. non blocking mode is fine, as you can 
instantly return a 0 if that is the case. Blocking mode, when the poller 
wakes up,
the async thread will most likely get the data, then the READ event will 
proceed into the CoyoteAdapter on the worker thread, and get blocked in 
and voila, you are screwed.

see the problem I am trying to describe. I'm all for non blocking read, 
for the servlet programmer I find it useless, but for the rest of tomcat 
it is necessary in order for comet to work well.
>> 1 background thread
> Ah, the "feel good" factor ;)
you can't do anything without it ;)

> Rémy
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

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

View raw message