jsr369-experts@servlet-spec.java.net

[jsr369-experts] Re: [servlet-spec users] Re: Re: Re: Re: Re: Calling complete with write pending

From: Greg Wilkins <gregw_at_webtide.com>
Date: Wed, 2 Dec 2015 20:17:36 +1100

On 27 November 2015 at 17:18, Stuart Douglas <sdouglas_at_redhat.com> wrote:

>
>
> +1
>
> I think it makes sense to handle it this way. It will result in a broken
> connection in most cases but I think that is an acceptable tradeoff, as
> this is not something that should happen in normal usage.
>
>
I've changed the jetty dev branch to have this behaviour and it has not
impacted anything, but then our examples/users have all been trained to
check isReady()==true before doing a complete or close.



> I wonder if the same behavior should also apply to
> ServletOutputStream.close() if it is called when isReady()==false?
>

Note that this behaviour should apply to isReady()==false and ALSO TO if
isReady() has not been called, but would return false if called. These are
two different states because calling isReady() has a scheduling side effect.

I've currently implemented close to have the same behaviour. I think this
kind of makes sense because anybody that write code like

  if(out.isReady())
  {
    out.write(content);
    out.close();
  }

Is mixing async and blocking styles. However, looking at this now... I
can also see the argument that the call to close should throw an exception,
no matter if isReady is true or false. Otherwise you get modal behaviour
where the code works on fast networks, but on slow networks (or small
buffers) it will fail - either with a WritePending (jetty's old behaviour)
or now with just a truncated response. This could allow unreliable code
to be released.

Perhaps it is better to fail fast. Ie if isReady() has not been called,
then an ISE should be thrown, not matter if the isReady() is true or false?

So I'm in two minds again....



> I think we also need to cover how flush() behaves when using non blocking
> IO. I think it should have the same semantics as write(), i.e.:
> - You can only call it when isReady()==true
> - After it has been called you need to check the ready state again
>

I think we can be more flexible with flush. If a write is pending, then
the flush has already happened, so we can ignore the flush. If a write is
not pending, we can do the flush!

cheers


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