On 14 September 2011 02:51, Rajiv Mordani <rajiv.mordani_at_oracle.com> wrote:
>
>
> On 9/12/2011 10:44 PM, Greg Wilkins wrote:
>>
>> Rajiv,
>>
>> here is my first impression feedback.
>>
>> + Good call to hide the NIO APIs. The functionality you are targeting
>> looks pretty good. However I guess some might still want the
>> ability to do IO with Buffers and Channels?
>
> We talked about doing that - however if we end up exposing the Buffer /
> ByteBuffer then we need to worry about
> the ByteBuffer related APIs and also Channels etc become tricky with
> filtering. I am open to exposing it if we have
> a good way of doing so.
I'm conflicted about this. On the one hand it is good to avoid he complexity.
On the other, it would really good to be able to send a file mapped
Buffer in a single async operation.
>> + NIO is a really silly name. Can we try to avoid calling things
>> NIOXxx and instead use AsyncIOXxx. Specially as we are not actually
>> exposing any NIO classes and implementations might use NIO2 etc.
>
> Am not particularly good with naming ;).
Something you obviously share with the creators of NIO, NIO.2, NIO.2.NT...
AsyncIO is a pretty reasonably descriptive prefix.
>>
>> + Why create new methods ServletRequest.getNIOInputStream and
>> ServletResponse.getNIOOutputStream? The current getInputStream and
>> getOutputStream already return ServletInputStream and
>> ServletOutputStream abstract classes, so we could just add the methods
>> from the OutputSink and InputSource interfaces to those classes.
>> This would avoid adding methods to interfaces and breaking wrappers
>> and other extensions.
>
> So you are suggesting to move the InputSource and OutputSink methods to
> ServletInputStream and ServletOutputStream respectively? How would one
> distinguish between
> the traditional IO vs the non blocking API? I was trying to keep the two
> separate. One other thought
> was to have an overridden method for getInputStream that takes a boolean
> which says blocking
> or non-blocking. Keeping the two separate just seemed simpler at this time.
Keeping them separate can also mean a lot of duplication.
The InputSource and OutputSync methods are not actually asynchronous by nature.
dataAvailable and isReady are queries that can be answered for
blocking aswell as async IO.
isFinished() is useful to know rather than remembering previous -1
returns and can be calculated from content-length even for blocking
connections.
canWrite(size) can likewise be guessed for blocking connections by
using the available buffer space. For non-blocking connections, you
cannot actually answer that question because you don't know if you are
1 bytes away from filling up a network buffer - so the size will only
be compared against user space buffers anyway. isComplete can be
answered by looking at content-length or previous calls to close.
For any real modal behaviour for async IO, the container will know to
switch when either an async listener is added or if we add some async
read/write calls with Futures like NIO.2
> When I first wrote the sample - I had a startAsync but I think we should not
> enforce
> the users to have to startAsync. I was thinking that the listeners could be
> called
> asynchronously. Whether it is called immediately or not - my first reaction
> is to say yes
> it can be called immediately but I will need to think a little more about
> it.
I'd prefer to limit this to callbacks once the servlet dispatch has
returned. This way the container can never schedule more than 1
thread per request and make things a lot simpler. It would be
really good to avoid having a threads dispatched for the servlet, for
dataAvailable and for writePossible all at the same time.
cheers