jsr369-experts@servlet-spec.java.net

[jsr369-experts] Calling onWritePossible "the first time"?

From: Greg Wilkins <gregw_at_webtide.com>
Date: Wed, 20 Jul 2016 11:41:20 +1000

In the javadoc for onWritePossible
<http://docs.oracle.com/javaee/7/api/javax/servlet/WriteListener.html#onWritePossible-->
it says:

this method will be invoked by the container the first time when it is
> possible to write data


However, it is nigh impossible to really implement this. We get a lot
of proxy style asynchronous applications that a frequently reading and
writing content from the same invocation of either onDataAvailable and/or
onWritePossible.

So if read and write listeners have both been set, a call to
onWritePossible will be scheduled (as without a pending write we simply do
not know if a write is really possible or not) and a call to
onDataAvailable will be scheduled if there is data available (often the
case).

Now the problem comes that we have to call one or the other of these
methods first because we can only call one at a time and Jetty calls
onDataAvailable first. So what happens if onDataAvailable does a write
that does not immediately complete and then returns?

Currently jetty just calls onWritePossible anyway and relies on the
implementation calling isReady() to find out that it is not in fact
actually ready. We could potentially delay that initial call until the
write from onDataAvailable completes, but that doesn't help generally as
any thread might do a write so we will always be in a race and
implementations need to check isReady before doing any writes.

Eitherway, a call to onWritePossible immediately or delayed does not match
the javadoc of 'the first time when it is possible to write data' as that
was before we called onDataAvailable.

We can't just call onWritePossible first, as then we get the same problem
with onDataAvailable's javadoc saying:

this method will be invoked by the container the first time when it is
> possible to read data.


So we cannot have both read and write being called "the first time",
because we can't do both. Also because other events can intervene, we
can't even guarantee that the state which scheduled a call still persists
when the call is actually made. Implementations must always use isReady
and if they use non container threads they must also use some mutual
exclusion to prevent events getting in between a call to isReady and a
subsequent operation.


I think we should change the javadoc to read:

onWritePossible:

> this method will be invoked by the container after it is possible to write
> data


onReadPossible:

> this method will be invoked by the container after it is possible to read
> data.



cheers








-- 
Greg Wilkins <gregw@webtide.com> CTO http://webtide.com