Hi Igor,
did you try:
selectorHandler.register(...)?
Alexey.
On Jan 18, 2010, at 21:34 , Igor Minar wrote:
> This has turned out to be a bit more complicated than we originally
> thought.
>
> This is what I tried:
>
> version 1) using SocketChannel#register directly in my own thread:
>
> channel.register(grizzlySelector, SelectionKey.OP_READ,
> System.currentTimeMillis());
>
>
> version 2) using SelectorHandler#addPendingIO:
>
> boolean origVal = ((TCPSelectorHandler)
> selectorHandler).isFinishIOUsingCurrentThread();
> ((TCPSelectorHandler)
> selectorHandler).setFinishIOUsingCurrentThread(false);
>
> selectorHandler.addPendingIO(
> new Runnable() {
>
> public void run() {
> try {
> channel.register(selectorHandler.getSelector(),
> SelectionKey.OP_READ,
> System.currentTimeMillis());
> } catch (ClosedChannelException ex) {
> //channel is already closed
> }
> }
> }
> );
>
> ((TCPSelectorHandler)
> selectorHandler).setFinishIOUsingCurrentThread(origVal);
>
>
> both work when there are no concurrent requests, but under load both
> of them result in:
>
> java.util.ConcurrentModificationException
> at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
> at java.util.HashMap$KeyIterator.next(HashMap.java:828)
> at java.util.Collections$UnmodifiableCollection
> $1.next(Collections.java:1010)
> at
> com
> .sun
> .grizzly
> .http.SelectorThreadKeyHandler.expire(SelectorThreadKeyHandler.java:
> 115)
> at
> com
> .sun.grizzly.TCPSelectorHandler.postSelect(TCPSelectorHandler.java:
> 556)
>
>
> This is because both versions register the channel with the selector
> in a thread that is not the SelectorThread, which is not thread safe.
>
> Unfortunately I don't see a way to register a channel with the
> selector in a thread safe manner without modifying
> TCPSelectorHandler and adding a concurrent queue to it for
> operations that will get executed by the thread handling
> Selector#select operations.
>
> Thoughts?
>
> /i
>
>
> On Jan 14, 2010, at 9:57 AM, Igor Minar wrote:
>
>> Hi Alexey,
>>
>> You are just proving that I'm not familiar with all the details of
>> the grizzly apis I'm using. I did not know that returning false
>> from the filter has this effect. I'll give it a shot tonight!
>>
>> thanks,
>> Igor
>>
>>
>> On Jan 14, 2010, at 9:48 AM, Oleksiy Stashok wrote:
>>
>>> Hi Igor,
>>>
>>> probably you've already tried that.... anyway
>>> IMO, when you decide to intercept connection to execute sendfile
>>> asynchronously, you can return false from AsyncFilter. This way
>>> you'll be able to keep ProcessorTask, so at time when sendfile
>>> will complete its task - you can register Channel back to the main
>>> SelectorThread and resume connection using saved ProcessorTask.
>>>
>>> Please correct me, if something is missed.
>>>
>>> Thanks.
>>>
>>> WBR,
>>> Alexey.
>>>
>>>> As I mentioned in my previous email, I expect that support for
>>>> http keep-alive (persistent connections) is another major feature
>>>> that could push the performance of grizzly-sendfile even further.
>>>> I believe that with the current grizzly (1.9) api, it is not
>>>> possible for me to get this done, but I might be wrong. In any
>>>> case, I'd appreciate help with either pointing me to the right
>>>> api or discussing changes to grizzly needed in order to make this
>>>> possible.
>>>>
>>>>
>>>> How grizzly-sendfile integrates with grizzly:
>>>>
>>>> grizzly-sendfile works as an async filter for grizzly, which
>>>> intercepts all the http requests and when it determines that it
>>>> is being requested to download a static file, it deregisters the
>>>> current socket channel from the grizzly's selector, returns from
>>>> the filter and asynchronously does its best to efficiently send
>>>> the requested file to the client and then closes the connection.
>>>>
>>>>
>>>> The problem:
>>>>
>>>> Ending the transmission like this results in non-persistent
>>>> connections (Connection: close), which come with a significant
>>>> performance penalty compared to keep-alive (persistent)
>>>> connections.
>>>>
>>>> I'd much rather return the connection back to grizzly and put it
>>>> in its keep alive queue or list, so that it could be reused for
>>>> future transmissions. However because of the async implementation
>>>> by the time when the download is finished, the ProcessorTask that
>>>> was provided to my filter is long gone (recycled, or possibly in
>>>> use by a different request), and the only thing I'm left with is
>>>> the actual socket channel.
>>>>
>>>>
>>>> The question:
>>>>
>>>> Is there a way for me to take a channel and make grizzly accept
>>>> it as a channel that should be monitored for further requests? Or
>>>> is there a better way to integrate with grizzly that would allow
>>>> me to achieve my keep-alive goal?
>>>>
>>>> To get an idea of what I'm doing without digging through all of
>>>> the grizzly-sendfile's code, I suggest that you have a look at my
>>>> async filter [1], which is the integration point between grizzly
>>>> and grizzly-sendfile. Just keep in mind that when a Download[2]
>>>> is prepared in the filter and registered with my selector thread,
>>>> the filter returns. The Download is then processed asynchronously
>>>> by grizzly-sendfile threads.
>>>>
>>>> thanks,
>>>> Igor
>>>>
>>>>
>>>> [1] https://hg.kenai.com/hg/grizzly-sendfile~main/file/
>>>> a68e8b200193/grizzly-sendfile-g19/src/main/java/com/igorminar/
>>>> grizzlysendfile/SendfileFilter.java#l1
>>>> [2] https://hg.kenai.com/hg/grizzly-sendfile~main/file/
>>>> a68e8b200193/sendfile-core/src/main/java/com/igorminar/
>>>> grizzlysendfile/Download.java#l1
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
>>>> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
>>> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>