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 instead of NOTIFY/WRITE_COMPLETE. 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 inputstream.read() 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 CoyoteAdapter.read

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, CoyoteAdapter.read today, locks up in a blocking read, easy to reproduce, if a filter needs more data to do processing upon a READ event. 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 the CoyoteAdapter.read
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 ;)

Filip

Rémy

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to