Hi Alexey,
On Jan 20, 2010, at 2:14 AM, Oleksiy Stashok wrote:
> Hi Igor,
>
>>>>>> 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.
> Not exactly, you can decide to not give a control to other filters,
> once you'll figure out, that this is sendfile related request.
The issue is that I will find that out only after
asyncExecutor.execute(), based on the headers in the response. In the
meantime the connection might time out, e.g. due to a file upload, or
other legitimately long-lasting operation.
> The problem with workaround I see - connection will *never* timeout,
> which may create a lot of idle connections registered on a Selector.
> I think here we should implement the similar solution as Comet, in
> other words create specific ARPAttachment, which will not let
> framework to close connection after 30 seconds (by default), but use
> another ARP timeout, which would be used until HTTP request is being
> processed, once processing is done - we switch back to 30 seconds
> idle timeout.
But what should the timeout be? And how will you coordinate between
commet timeout, the default ARPAttachment timeout, and a timeout of
another filter if they all try to attach their attachment to the key?
> Igor, can I ask you to create an issue for that?
I will.
>
>>
>> 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.
> Can you pls. elaborate what other issues did you find?
The problem is with dispatching the request into the adapter and the
order of filter execution. Please see my comment from Fri Sep 4
20:25:40 at
https://grizzly.dev.java.net/issues/show_bug.cgi?id=643
>
>> 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.
> Adapter may work in async way - you can postpone/resume HTTP request
> processing. The issue with adapter and sendfile I see - is that HTTP
> framework choses appropriate Adapter basing on request URI.
correct, the adapter can be used only for serving static files as if
it was a regular webserver.
> In your case, you'd probably want to intercept *all* requests, not
> just those, which are targeted to the specific URI?
yes, that's what I need in order to be able to handle to X-Sendfile
responses.
> For now, IMO, AsyncFilter is the best approach here, so let's fix
> the issues you have :)
:) One more question. I had a look at the ProtocolFilter, but I
believe that is not an around filter. Is that right?
thanks,
Igor