dev@grizzly.java.net

Re: premature connection closure with ARP (was: grizzly + arp + jruby problem)

From: Igor Minar <iiminar_at_gmail.com>
Date: Tue, 19 Jan 2010 21:05:54 -0800

On Jan 19, 2010, at 1:47 AM, Oleksiy Stashok wrote:

>>>> I noticed that the connection is being closed by
>>>> TCPSelectorHander#postSelect calling
>>>> SelectorThreadKeyHandler#expire, which based on the value of
>>>> SelectionKey#attachment decides if the connection associated with
>>>> the SelectionKey should be expired (closed).
>>>>
>>>> When the requests are being made without ARP, the attachment is
>>>> usually KeepAliveThreadAttachment, which prevents the connection
>>>> to be closed prematurely. However, when ARP is used, the
>>>> attachment is a Long value, representing the timestamp of the
>>>> beginning of the request. Once the difference between the current
>>>> time and the timestamp is bigger than 30 seconds, the connection
>>>> is closed.
>>>>
>>>> Now my question is if this is the intended behavior or not.
>>> Well, for sure if connection is being actively used - it shouldn't
>>> get closed.
>>> But solution doesn't look trivial to me. When ARP is used - the
>>> HTTP request processing may be done in several steps on different
>>> threads, while Channel itself will be parked (registered on
>>> Selector will no SelectionKey.XXX interest), so basically
>>> processing will happen beyond Grizzly control, and if we will
>>> disable timeout - then we will 100% rely on custom application
>>> logic, that it will not forget to release the Channel correctly.
>>> As a possible solution we can introduce some kind of Async
>>> operation timeout, which will be different from regular Channel
>>> timeout (some bigger timeout value). IMO we can have something
>>> like that for 1.9.19.
>>>
>>> What do you think?
>>
>> I don't know. I'm not crazy about just increasing the timeout.
>>
>> How does comet get around this issue? Won't all the comet
>> connections get closed after 30 seconds?
> No, comet has own attachment type: CometTask.

I created this workaround that I use in my filter:

+ Object attachment = task.getSelectionKey().attachment();
+
              try {
+
+ if (attachment instanceof SelectionKeyAttachment) {
+ ((SelectionKeyAttachment)
attachment).setTimeout(SelectionKeyAttachment.UNLIMITED_TIMEOUT);
+ } else if (attachment instanceof Long) {
+
task.getSelectionKey().attach(SelectionKeyAttachment.UNLIMITED_TIMEOUT);
+ }
+
                  if (!asyncExecutor.execute())
                      return false;
              } catch (Exception e) {
                  throw new RuntimeException(e);
+ } finally {
+ if (attachment instanceof SelectionKeyAttachment) {
+ ((SelectionKeyAttachment)
attachment).setTimeout(System.currentTimeMillis());
+ } else if (attachment instanceof Long) {
+
task.getSelectionKey().attach(System.currentTimeMillis());
+ }


It's pretty ugly, but it gets me going for now. The thing is that if
there is more than one ARP filter, things get pretty ugly as they
start stepping on each other's toes.

It looks like it to me, that multi-filter ARP wasn't thought through
well enough. There are already some issues with AsyncExecutor and now
this. I'm starting to be more and more interested in getting off of
ARP and use some other integration point instead. I've already started
working on Adapter similar to StaticResourceAdapter, but that won't
help me to achieve the X-Sendfile functionality, which can be
implemented only via an around filter (just like AsyncFilter). Is
there something like that but not asynchronous? I don't need and
currently don't use the async functionality that ARP provides anyway.

thanks,
Igor