On Nov 27, 2009, at 8:23 PM, Ashish wrote:
In the second approach, won't we end up with the same problems as
Mina 2.0,
"From the debugging PoV, it's a nightmare, as you have to step
through many
intermediate calls (in fact, an other call for each filter). The
StackTrace
is heavy. The next filter is not known when you are in a Filter,
as it's
computed outside of the current method"?
No : the next is computed inside the method :
...
nextFilter = computeNext( params );
nextFilter.<action>( params );
...
so you can immediately know which is the next filter (as it's stored
in the nextFilter variable) and you don't have one more call in the
stack, as once you get the nextFilter, you are done. This was not the
case in MINA 2.0, because the computation was delegated to an
intermediate object.
To make things clear in my mind, where would we need such a feature?
If you get a message that can be decoded in many different ways, for
instance, depending on the first byte (just an exemple). The
computeNext method can take some parameter, and returns the next
filter, depending on the context. Ok, at the end of the day, it's a
state machine :)
Couldn't we just load all the filters in the chain and they
decide whether
or not to do anything?
Yes, of course, and we should probably implement most of the
protocols
this way. The idea is to keep the full stuff simple, but allow a user
to go a bit further if needed. At this point, we may want to offer
differnt kind of Chain implementation ...
I am still kinda not very comfortable with the computation part. The
only reason why I need the next filter to be got dynamically is to
handle dynamic chain.
Wearing a User's hat :-)
Acceptor --> IoFilter1--> IoFilter2 --> IoFilter3 -->IoFilter4 -->
IoHandler
If I see from POV, this is what I need in my implementation. To add to
this, I may choose to modify the chain at runtime, say disable/remove
IoFilter3, giving me this new chain
Acceptor --> IoFilter1--> IoFilter2 --> IoFilter4 --> IoHandler
or adding a new Filter between 3 and 4
Acceptor --> IoFilter1--> IoFilter2 --> IoFilter3 -->IoFilter5
-->IoFilter4 --> IoHandler
So, compute function shall always return me the next filter in chain
from somewhere (based on our implementation)
This is pretty much that I need from the chain.
Now lets see if based on identifier we choose that we need to decide
which is the next filter, then we get something like this
X - means skipped (Artwork inspired by Emm's Art work :-) )
/ IoFilter1--> IoFilter2 --> IoFilter3 -->IoFilter5
-->IoFilter4 --> IoHandler
Acceptor --> IoFilter1--> X --> IoFilter3 -->IoFilter5
-->IoFilter4 --> IoHandler
\ IoFilter1--> IoFilter2 --> IoFilter3 --> X
-->IoFilter4 --> IoHandler
so how it could be a possibility that we allow to override the
computeFilter() to get the desired functionality. We provide default
functionality to support static and dynamic chains For any custom
functionality we leave scope improvement. If this is what everyone is
thinking my doubt on computeFilter() is a little clear :-)
Well, choosing a suitable Data Structure to support all this will
again be interesting. Current implementation uses something similar to
LinkedHashtable. Have to see if something simpler can be implemented
or out of the box API :-)
It's my opinion that new filters get created to simulate state machine
changes and any other use is an ad hoc mechanism that can be more
cleanly refactored into a state machine mechanism. With that said aa
session w/ N fixed chains where each chain represents a state would
fit the bill. The number of states is fixed. The composition of the
state machine can be changed until the acceptor/connector have
established the connection.
Acceptor -> ChainMachine -> IoHandler
inside the chain machine:
S1: IOF1 -> IOF2 -> IOF3 -> IOF5 -> IOF4
S2: IOF1 -> IOF3 -> IOF5 -> IOF4
S3: IOF1 -> IOF2 -> IOF3 -> IOF4
From a user's perspective things are quite easy to grok and most
cases the chain machine degenerates into a single state chain.
Regards,
Alan