« Return to Thread: [Community Feedback] Grizzly 2.0

Re: [Community Feedback] Grizzly 2.0

by Oleksiy Stashok :: Rate this Message:

Reply to Author | View in Thread

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.



 « Return to Thread: [Community Feedback] Grizzly 2.0