About the Filters and the Chain, I also have some initial thoughts (even
if they are not recent). Here they are.
First, let's start with what we really need :
o A chain has a start
o A chain has an end
o Both start and end are Filter instances
o We have as many filters as we need in the chain
o Filters can be added or removed dynamically
o A chain is instanciated for each session (if we have 10K sessions, we
have 10K instances of chain)
o A filter can be activated (enabled) or disabled, dynamically
That being said, we have many ways to implement such a mechanism. let's
consider we are in a Filter, and we want to call the next filter. We
have three options here :
* The NextFilter is already computed, and is a part of the Filter's
data. This resolves to a direct call :
...
nextFilter.<action>( params );
...
* The NextFilter is computed dynamically :
...
nextFilter = computeNext( params );
nextFilter.<action>( params );
...
* The nextFilter is computed by the caller, and is a parameter :
public void <action>( Filter nextFilter, <other params>... ) {
...
nextFilter.<action>( params );
...
The current version (2.0) implements the third form. 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.
The first approach is way simpler, as is the second one.
Let's go a bit deeper : if there is an executor in the chain, suddenly
things get a bit muddy. The "one session = one chain instance" is still
correct, but we may have two (or more) messages being processed on one
session on the same chain. If the chain is dynamically modified, then it
may be ok for the thread modifying the chain, but not for the other
threads. Here is a picture describing this mechanism :
Thread1 /--->
[Filter3]--->[tail]
Thread2 [head]---> [filter1]--->[filter2]--->[executor]-*---->
[Filter3]--->[tail]
Thread3 \--->
[Filter3]--->[tail]
Now, if the Thread 2 modify the chain to add a Filter4, then there is no
guarantee that Thread1 will call it. That means we must protect the
chain against concurrent modifications.
Another drawback of the first approach is that you must declare an
instance of a Filter for your chain, as it carries some information
specific to your session. We would rather have a stateless Filter...
The second approach require an external system to give you the next
filter. It can be the session, which is passed as a parameter for each
filter call.In this case, if the external system is protected against
concurrent modifications, then we are safe (except if we want each
thread to define its own chain in the previous example... In this case,
the executor must be responsible for the chain duplication, and probably
store it in a ThreadLocal variable )
Not that simple...
Thoughts ?
Norman Maurer wrote:
Well I'm not a MINA committer but I would keep the "Filter" naming.
Like Emanuell said, its a well known "pattern".
Bye,
Norman
2009/11/26 Julien Vermillard <[email protected]>:
Le Thu, 26 Nov 2009 15:55:57 +0530,
Ashish <[email protected]> a écrit :
Have started looking into the FilterChain implementation and here are
some initial thoughts
1. Rename IoFilterChain as IoChannel - it gives a more clear picture
and is easy to understand like imagine as a Channel with multiple
stages aka IoFilters.
This came while I was drawing on paper to design something.
I propose IoPipe/IoPipeline, because for me a bunch of filter stacked on
each other is a Pipe in the Unix meaning.
2. Have captured a couple of API's that are core to IoChannel
IoSession getSession();
IoFilter getHead();
IoFilter getNextFilter(IoFilter currentFilter);
List<IoFilter> getAll();
void addFilter(String name, IoFilter filter);
void addAfter(String baseName, String filterName,
IoFilter filter);
void removeFilter(String filterName);
There are a lot more API's in current implementation. I am not sure if
we need replace API or not.
Also do we need the Generics version of these API's or its fine
without them?
This is just the initial list. Will checkin the files once the name
change is OK with everyone.
--
--
cordialement, regards,
Emmanuel Lécharny
www.iktek.com
directory.apache.org