tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Remy Maucherat <>
Subject Re: Comet changes
Date Tue, 08 May 2007 18:10:13 GMT
(repost, trouble with smtp)

Filip Hanik - Dev Lists wrote:
> Remy Maucherat wrote:
>> Filip Hanik - Dev Lists wrote:
>> That doesn't look like much of a problem to me. The user in that case 
>> would be writing in a situation where canWrite is false (since the 
>> data hasn't been written yet), which is an error. To resume writing 
>> stuff after canWrite becomes false, the servlet would have to wait 
>> until it gets the write event.
> and that's my issue, no we are adding a "new hidden API", ie, we are 
> changing the behavior of the old blocking API.
> I like that even less than doing a cast to invoke nbWrite on 
> writer/outputstream.

We have a disagreement then ;)

> outputstream.write should always do a blocking write and return only 
> when all data is written, not be transformed by the canWrite behavior.

I thought we were talking about non blocking IO. If we're talking about 
that, then the rules are slightly adjusted when the connection are 
placed in non blocking mode (the main difference is that reads and 
writes on the socket are allowed to return 0, which means that no bytes 
were written or read; the idea is then to hide this as much as possible 
behind all the usual structures of the servlet API to be able to 
continue using its services, including buffering and i18n).

> if you dont like casting, then simply adding nbRead/nbWrite to the 
> CometEvent interface solves all problems.
> no need for canWrite, as in the scenario where canWrite returns false, 
> nbWrite returns 0. same behavior. just simpler and more consistent with 
> Java and it's non blocking features.

I don't think you talked about nbWrite before, so I don't really know 
what nbWrite is.

The process I am talking about works like this:
- the servlet has to place the connection in non blocking mode using a 
method of the event (by default it uses blocking IO)
- the servlet writes its data as if it was blocking IO (there's really 
no way around this), but checks after each write if it is allowed to 
continue writing using a method which will return some flag; the value 
of this flag will indicate that it is not allowed to continue writing if 
the last write on the socket returned 0
- the leftover data is kept in the socket buffer - in APR, it is the 
bbuf field of the InternalAprOutputBuffer class
- if the flag was set and another write is attempted, throw an exception
- the background thread which had his write interrupted and had to stop 
then calls a "notifyWrite" callback which will add the socket in a write 
- when the poller signals the socket, and the event method of the 
processor is called, the leftover data in the buffer is written, and the 
flag indicating that it's allowed to write is set to allow it if all 
bytes were written (if not -> goes back to the poller)
- the processor invokes the adpater which invokes the servlet with a 
write event
- the servlet should then notify its background thread that it may 
resume writing on that socket (obviously, if a connection goes to the 
poller too often, it could decide to give up)
- reads become non blocking, and will cause an error if a read returned 
0 (basically, the servlet should never attempt to read in that case); 
there's no real difference with blocking IO

So it does non blocking reads and writes, but it remains very similar 
from the Servlet perspective.

All in all, NB IO is cute, but I'd like to know which use case it 
addresses in Servlet land. Hopefully it's not to be able to implement a 
stream server ;)


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

View raw message