users@grizzly.java.net

Re: Grizzly HTTP servlet: aggressive recycling revisited

From: Oleksiy Stashok <oleksiy.stashok_at_oracle.com>
Date: Tue, 09 Oct 2012 16:34:41 +0200

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
> <mailto: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
>> <mailto: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
>