dev@grizzly.java.net

Re: [Community Feedback] Grizzly 2.0

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Wed, 18 Jun 2008 13:46:57 +0200

Hi,

thank you for feedback! see my comments inlined :)

>>
>>
>> Main target for Grizzly 2.0 is improving Grizzly low level API,
>> mostly it's grizzly-framework module.
>> Grizzly 1.5+ was our first attempt to move HTTP oriented Grizzly
>> framework, which was embedded to GlassFishV2, to separate project,
>> remove HTTP dependancy, implement client side support and finally
>> have good performed, extensible NIO framework. IMHO we did good
>> work, which is confirmed by number of projects Grizzly is used in.
>> However quite often we got feedback, that our API is not clear,
>> difficult to use (because of following backwards compatibility with
>> existing HTTP API, our mistakes... etc), especially for smaller
>> projects, where people don't want to spend much time on performance
>> optimization etc, but mostly interested in getting nice, simple
>> high level API, which will hide all the NIO complexity.
>>
>> So with Grizzly 2.0, we want provide new framework API, which will
>> count with Grizzly 1.5+ experience we got, plus we will not be
>> limited with backwards compatibility anymore.
>>
>> Here is high level class diagram of Grizzly 2.0 [1] , which I
>> propose, but for sure all of you are more than welcome to propose
>> changes, improvements, etc.
>>
>> For those, who used Grizzly 1.5+ API, this first Grizzly 2.0
>> propose looks similar, however there are several changes:
>>
>> 1) No Controller, Transport comes
>> From Grizzly 1.5+ API I came to opinion, that attempts to unify
>> protocol logic (for ex. TCP & UDP) didn't simplify things, but made
>> them more difficult and less effective.
>> Controller was the part of that unification, but in practice,
>> Controller mostly was used just to start/stop Grizzly, other
>> Controller's API become redundant.
>> So instead of Controller API, which tried to unify transport logic,
>> I propose Transport API, which is implementation of one single
>> transport like TCP, UDP; and will have logic just for one specific
>> transport.
> I specifically tend to give very meaningful & intuitive names for
> any new classes or interfaces. I agree with you on the existing
> controller and it's removal. The new "Transport" seems a good
> candidate. But, could the name be 'GrizzlyTransportManager' ? A
> typical transport is just a vehicle to provide a mode of
> transportation (of bits). So, the abstraction 'Transport' here with
> start, stop, pause does not really click with other developers when
> they encounter this class or it's api.
>
> I think, you meant, an UDPTransport, HTTPTransport, TCPTransport
> etc... based on the protocol. If thats the case, we need
> reconsider the name of the transport class here.
Right, for example currently I'm working on TCPNIOTransport. As for
your concern about the Transport name as it is - not sure, for me
GrizzlyTransportManager sounds like common manager for all transports
(similar to Controller, which we had), for example name
TCPGrizzlyTransportManager sounds strange for me ;)


> I know about the SelectorHanlderRunner in Grizzly currently. I
> think this is the class that should have start, stop, pause ..calls
> basically to control the listening / selection activity on a per
> thread basis.
Correct, and in Grizzly 2.0 it has those methods.


> I also think that, the proposed transport needs a split with a
> another level of abstraction for Socket side settings/operations
> like host, port and bind etc. Basically, the proposed transport (to
> me) looks like... a configurator, context holder, socket binder.
Context holder?
Otherwise I agree. Bind related stuff probably should be moved to the
different abstraction like Acceptor, NIOAcceptor. Because currently
common Transport with: int port and SocketAddress looks strange.


> Question: What's the relation b/w this transport to SelectorHandler
> (nio.Selector) Who creates it and who owns it.
Transport<-1:1->SelectorHandler. Selector instance is created inside
SelectorHandler implementation. Then each created Selector is getting
associated with the SelectorHandlerRunner, which is responsible for
running Selector handling loop.


>> For Grizzly 2.0 I propose to move "multiple read threads" logic
>> under transport, to let them implement their own logic, how they
>> can distribute processing Channels among several Selectors
>> (Threads) (see NIOConnectionDistributor, SelectorHandlerRunner).
> What does a NIOConnectionDistributor do ? The name tells me that,
> it would help in registering and deregistering a channel with a
> given selector. But, then it's relation should be with a Selector/
> SelectorRunner than with the transport here. Basically, I think, I'm
> missing some relationships in the class diagram here.
NIOConnectionDistrubuter distrubutes accepted/connected channels among
SelectorHandlerRunner threads. Currently there is RoundRobin
distributor implementation.


>> 4) Improve SelectionKey events processing
> We need to discuss this (=how we process events) at length; since we
> are starting afresh, in this area for Grizzly 2.0
Agree.


>> In Grizzly 2.0 each transport will have EventProcessorSelector,
>> which will be able to add/modify EventProcessor(s) chain, which
>> will process event occurred on a channel.
>> For example EventProcessorSelector could decide to let FilterChain
>> to process all incoming SelectionKey events, regardless of channel
>> type: client or server.
>> Currently in Grizzly 2.0 there are 2 EventProcessor
>> implementations: FilterChain, CallbackHandler.
> The challenge to me was, the way controller was executing the filter
> chain in the current Grizzly. The new proposal looks good to me.
> (lines: regardless of channel type: client or server). Does that
> mean, say if my app. is interested in a particular event, and uses a
> callbackhandler; can it still executes filters too? Is the otherway
> possible too?
> Can we also unify the callbackHandler mechanism that is used now
> only on the client-side. ?
Exactly! What EventProcessorSelector does - it's each time, when event
occurs on some channel (no matter it's client or server) -
EventProcessorSelector chooses the corresponding EventProcessor, which
will process occurred IO event. In Grizzly 2.0 CallbackHandler and
ProtocolChain implement EventProcessor API, which means any of them
could be selected to process occurred IO event.
So implementing own EventProcessorSelector logic and assigning it
either to the Transport or specific connection unit - we can change
how IO events will be processed.


> I note the exceptionHandlers in the transport. Looks like a very
> good idea. But, they should be in the SelectorHandler / or in the
> Context itself. Isn't it?
SelectorHandler errors will be caught in the SelectorHandlerRunner
loop and passed to the Transport. As for Context - will see, currently
it's difficult to say :)

Thank you!

WBR,
Alexey.

>
>
> that's all I've for now.
>
> thanks,
> Harsha
>
>
>>
>>
>> These are original 2.0 changes I can propose.
>> Will appreciate your feedback and contributions!
>>
>> Thanks.
>>
>> WBR,
>> Alexey.
>>
>> [1] https://grizzly.dev.java.net/source/browse/grizzly/trunk/www/images/diagrams/GrizzlyV2-HL-class-diagram.png?view=auto&rev=1177
>