Ok, started digging into this, and noticed that non blocking will ever only
be available when using intput/output streams, and not when using
readers/writers.
From my perspective I see that the 3.1 is too limiting. Do you see any
reasons why we shouldn't implement non blocking behavior for
Readers/Writers?
I do believe that we should take the opportunity to enhance our container
beyond the specification if there is an opportunity for it.
The servlet spec has opened up an opportunity for doing non blocking reads
in two different ways
1. Polling based by calling ServletInputStream.dataAvailable() or
ServletInputStream.isReady()
2. Event based by implementing javax.servlet.ReadListener
My guess is that their intention, albeit not clearly specified, is that
isReady() would always return false and dataAvailable() would always return
0 unless ServletInputStream.setReadListener(..) has been called. The spec
indicates that once this method has been called, then the event based
notifications will start.
This has now become a pretty bad API. Since non blocking should only come in
event based form, that would mean that ServletInputStream.dataAvailable as
well as ServletInputStream.isReady should only be called from within
ReadListener.onDataAvailable(...)
So a much cleaner API would have been
ReadListener.onDataAvailable(ByteBuffer data) and let the user get access to
the bytes right away.
However, given that there is a polling API, should it be implemented?
Meaning, should I be able to do
while (req.getInputStream().dataAvailable() > 0 ) {
req.getInputStream().read();
}
Without ever setting a listener? According to the spec, no, but why prevent
us from doing such?
In a similar fashion, the exact same could be accomplished with
while (req.getReader().ready()) {
req.getReader().read();
}
The exact same limitations exist for writing.
WriteListener.onWritePossible() doesn't tell you anything about how much
data you can write. In a pretty lame fashion you have to do single byte
writes unless you knew something about the buffering of the underlying
container
while (resp.getOutputStream().canWrite()) {
//write only *single byte* here
//you can't write more as there is no guarantee that you wouldn't
fill/overflow a buffer
}
Why is the API not WriteListener.onWritePossible(ByteBuffer buf) - this
would tell me exactly how many bytes I could write as I would simply
So, as a conclusion,
1. why has the servlet expert group introduced both polling and event based
when it could have been strictly event based. Or should polling work even
when event based has not been initiated? (ie setReadListener or
setWriteListener called)
2. all API's are not really usable unless Async servlets are used. The
current API allows me to end the request while still have registered for
reads.
So, it is only meaningful if async is used, so why not add the API to the
async APIs. We already have a listener there.
Does the expert group believe that this is the best API to move forward
with?
Filip
> -----Original Message-----
> From: Filip Hanik (mailing lists) [mailto:devlists_at_hanik.com]
> Sent: Thursday, June 28, 2012 2:38 PM
> To: users_at_servlet-spec.java.net
> Subject: [servlet-spec users] Clarification on non blocking reads
>
> ServletInputStream.dataAvailable() - returns the number of bytes that
> that
> can be read without blocking
>
> Question:
>
> Does this imply that non blocking reads are not supposed to be available
> for
> Readers?
>
> Take a 2 byte character set, like UTF-16, and the client sends the first
> byte only.
> In this case, the, onDataAvailable() would trigger, dataAvailable()
> would
> return 1, but ServletRequest.getReader().read() would not have any data
> to
> return
> It can't return -1 as the stream hasn't ended. How are we supposed to
> handle
> this case?
>
> It seems here that the method ServletInputStream.dataAvailable() could
> be
> replaced by
> ServletInputStream.available() - return the number of bytes that can be
> read without blocking
> Reader.ready() - return true if read() is guaranteed to not block
>
>
>
>
>
>