users@grizzly.java.net

Re: Grizzly HTTP servlet: aggressive recycling revisited

From: Matthew Swift <matthew.swift_at_gmail.com>
Date: Tue, 9 Oct 2012 16:58:25 +0200

Hmm, I was hoping you'd be able to figure it out ;-) I ripped the sample
code from my Servlet (which I have got working ok now BTW but it's a bit of
a balancing act). It'll take a short while for me to create a unit test.
Give me a moment...

Matt


On 9 October 2012 16:34, Oleksiy Stashok <oleksiy.stashok_at_oracle.com> wrote:

> Hi Matt,
>
> from the code snippets you sent it's not clear to me why ISE is thrown...
> Can you pls. share the testcase, so I'll be sure I'm looking into the same
> issue?
>
> Thanks.
>
> WBR,
> alexey.
>
>
> On 10/09/2012 04:28 PM, Matthew Swift wrote:
>
> Hi Alexey,
>
> Don't worry about the slow response, I assumed that you were at Java One.
>
> Answers below:
>
> On 9 October 2012 08:38, Oleksiy Stashok <oleksiy.stashok_at_oracle.com>wrote:
>
>> Hi Matt,
>>
>> sorry for possible delays, the mailing list didn't work for the last
>> couple of days...
>>
>>
>> On 10/05/2012 07:26 PM, Matthew Swift wrote:
>>
>> I've been thinking about this some more... thoughts below:
>>
>> On 5 October 2012 18:19, Matthew Swift <matthew.swift_at_gmail.com> wrote:
>>
>>> [...]
>>>
>>> The call to resp.isCommitted() is the one triggering the exception,
>>> which seems a little harsh! How can it ever return true since, when a
>>> response is committed, I get an exception instead?
>>>
>>>
>> This has to be a bug, I'm pretty sure of that. There's no point in
>> having the method if it's going to never return true. Let me know if you
>> agree, and I'll raise an issue in JIRA for it.
>>
>> Is it easy to reproduce this issue?
>> Response.isCommited() has to return true, if response headers have been
>> sent to a client; or false otherwise.
>> The exception you reported might occur when you call isCommited after
>> response has been resumed, is it the case?
>>
>>
>
> Yes. Basically if I am doing Servlet 3 async processing using an
> AsyncContext then the following works:
>
> httpResponse.isCommitted();
> asyncContext.complete();
> httpResponse.isCommitted();
>
> But the following triggers an IllegalStateException during the second
> isCommitted():
>
> httpResponse.isCommitted();
> httpResponse.sendError(404, "Grrr");
> httpResponse.isCommitted(); // ISE
>
> To me at least httpResponse should always work regardless of whether or
> the internal state (Response) has been recycled or not. In other words I'd
> expect isCommitted to work like this:
>
> public boolean isCommitted() {
> final Response tmp = response;
> return tmp != null ? tmp.isCommitted() : true;
> }
>
> Note that the Javadoc for sendError states:
>
> *If the response has already been committed, this method throws an
>> IllegalStateException. After using this method, the response should be
>> considered to be committed and should not be written to.*
>
>
>
> While you cannot "write" to the response it says nothing about querying
> the response state. In addition the servlet spec section 3.11 states:
>
> *Containers commonly recycle request objects in order to avoid the
>> performance overhead of request object creation. The developer must be
>> aware that maintaining references to request objects for which startAsync
>> has not been called outside the scope described above is not recommended as
>> it may have indeterminate results.*
>
>
>
> It's only referring to the request object and says nothing about
> responses. I really think that Servlet implementations should be able to do
> conditional processing based on the isCommitted() state of a request. For
> example, during error handling - an error may be trapped after the response
> has been "committed" and error handling code should be able to check
> whether or not it is possible to send an error to a client.
>
>
> We can definitely implement a switch to allow/disallow Request/Response
>> recycling, it shouldn't be a problem at all... it may have some perf.
>> impact, cause Request/Response objects are relatively expensive, but we can
>> definitely try and double check that.
>>
>>
> No please don't :-) Since the Servlet specification permits recycling
> I'd prefer if my Servlet implementation was tolerant to this behavior for
> interoperability with other containers.
>
> Thanks again,
>
> Matt
>
>
>