users@grizzly.java.net

Re: grizzly-sendfile (was Re: High latency of ARP calls in Glassfish v2)

From: Igor Minar <iiminar_at_gmail.com>
Date: Wed, 26 Nov 2008 16:06:08 -0800

On Nov 26, 2008, at 2:35 PM, Jeanfrancois Arcand wrote:

>
>
> Igor Minar wrote:
>> On Nov 26, 2008, at 2:07 PM, Jeanfrancois Arcand wrote:
>>>
>>>
>>> Igor Minar wrote:
>>>
>>> [cut]
>>>
>>>> I believe I have copy of the comet code from gfv2ur2 and in
>>>> CometTask I see:
>>>> } finally {
>>>> // Bug 6403933
>>>> if (connectionClosed){
>>>> cometSelector.cancelKey(cometKey);
>>>> }
>>>> And in CometSelector there is:
>>>> SelectorThread st = cometTask.getSelectorThread();
>>>> SelectionKey mainKey = cometTask.getSelectionKey();
>>>> if (cometTask.getCometContext() != null){
>>>> cometTask.getCometContext().interrupt(mainKey);
>>>> }
>>>> cometEngine.interrupt(key);
>>>> st.cancelKey(mainKey);
>>>
>>> ah you deep dive inside that code :-) I agree I think that will
>>> works. But I still need to invoke cancelKey(..) as the keep-alive
>>> subsystem needs to be advised a connection is getting closed. I
>>> guess I can get the KeepAlivePipeline and invoke it directly. I
>>> need to investigate...
>>>
>>> Let me look at your code now :-)
>> hahaha.. go for it and let me know if you see places that could be
>> improved. I'm sure that there are some. Especially the plugin
>> interface is super simple and should be improved.
>> One thing I'm not terribly happy about is the state of my test
>> suite. I basically have only a faban benchmark which does system/
>> acceptance testing and load testing/benchmarking. I have some unit
>> and functional tests written in RSpec that I invoke via JTestR, but
>> that stuff is not committed yet because it's not complete.
>
> I want to see how you automate faban here as I really want to
> automate it for the http modules.

You can see the code in the repo under test/faban, which tests an
example application (under etc/test-webapp).

I had to build some custom code in order to make faban suitable for my
"large" file downloads (see my custom class Md5Downloader).

The test suite is not perfect, but it's good enough at the moment for
catching concurrency issues, which could result in data
inconsistencies or aborted downloads. Overall I'm sleeping much better
now that I can reliably test the code even though it's only at this
high level.


>> In general I found it pretty difficult to test the code that
>> extends grizzly code. Maybe that has changed in later releases
>> (I've been primarily working with 1.0.x), but I'd really love to
>> see some helper/mock/stub classes in grizzly or more IoC/injection
>> that would aid in building a good test suite.
>
> Fully agree.
>
>> Do you have any pointers to your test suite or testing practices
>> that other grizzly developers could leverage?
>
> We have improved a lot since 1.0.x IMO. For the http module,
> embedding it could be as simple as:
>
> http://weblogs.java.net/blog/jfarcand/archive/2008/07/extending_the_g.html
>
> For the test case, take a look at:
>
> https://grizzly.dev.java.net/nonav/xref-test/index.html

Nice.

> Of course there are still places for improvement, but that was a
> gigantic step to move out of GF, then split the 1.0.x into 5 modules
> (framework, http, http-utils, comet, cometd) instead of a monolithic
> jar.

Very good. I need to catch up with grizzly 1.9 and 2.0.

> You feedback is welcome :-) :-)

I really like grizzly and I learned a lot by reading its code (I had
no NIO experience before). I think that more focus on testability and
better naming of classes and methods were the two main areas that I
had problems with.

For example, I found a few oddities that caused me to waste a lot of
time by debugging:

- org.apache.coyote.Response#reset doesn't reset the response body. I
spent quite some time debugging data corruption cased by my app
inserting a single space character into the response buffer and
response#reset not cleaning it out. Actually I'd prefer to have two
methods on the response class - resetHeaders and resetBody. In my
extension, I'm really interested only in resetting the body and
preserving the headers set by an application.

- org.apache.coyote.Response#sendHeader is misleading because it
doesn't send headers until #finish is called, again something that I
wasted a lot of time on

- org.apache.coyote.Response#remoteAddr returns null when I run
grizzly-sendfile on my mac as localhost, but it works fine on our
production servers (solaris)

oh.. and there was one more.. If a subclass of AsyncFilter throws an
exception from the static initializer or constructor, this exception
is swallowed without any error logs. (that resulted in: http://twitter.com/IgorMinar/status/1020362781
  :-D)


One thing that is on my wishlist, but that is probably more an RFE for
NIO than grizzly is that I'd like to be able to do "semi-blocking"
writes to a channel or writes with defined timeout. What I mean by
that is that I'd like to say, try to write this bytebuffer into this
channel but don't block for longer than x milliseconds. That would
allow me to take my code to a whole new level. Right now I workaround
this by doing non-blocking writes and repeating them with throttling
involved to avoid high cpu usage (see SendfileAlgorithm#throttle).

At the moment I focus mainly on what I call blocking algorithms
(algorithms that employ blocking writes) because they are easier to
implement, but IMO the future of grizzly-sendfile will be in non-
blocking algorithms, which as my preliminary benchmarks show, deliver
incomparable scalability, while retaining transfer performance (think
500 concurrent downloads served by only 50 or less worker threads).
There are many cool *and* useful things that can be done in the
grizzly-sendfile world when you start writing plugins and algorithms.

cheers,
Igor


>
>
> A+
>
> -- jeanfrancois
>
>
>
>
>
>> /i
>>>
>>>
>>> A+
>>>
>>> --Jeanfrancois
>>>
>>>
>>>
>>>> /i
>>>>>
>>>>>
>>>>>
>>>>> This would allow me to
>>>>>> avoid having to retain a reference to the main selector and its
>>>>>> selectionkey resulting in less clutter.
>>>>>
>>>>> I agree.
>>>>>
>>>>> A+
>>>>>
>>>>> -- Jeanfrancois
>>>>>
>>>>>
>>>>>> /i
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>