I really like your approach, Dave. Some question though:

What would session.getFilterChain() return? It will be sessionChain, right?

Will IoFilterChain extend IoFilter and be just another IoFilter?

This is basically the same as nesting filter chains as I proposed yesterday (remember the (((A, B), C), D) thingy?) but it's a flat list of chains instead, right?

You still have the NextFilter problem. As I understand it these have to be static since IoFilter.init() is called when the filter is added to a chain. A NextFilter is passed to this method and the filter could remember this for future use.

I can't see how the last filter in a wrapped chain will know where to go next if the NextFilter given to it can't be created dynamically. Remember, sessionManagerChain and portChain will be shared by many connectionChains.

/Niklas

Irving, Dave wrote:


Explicitly asking users to add head/tail filter is a bad idea.
I agree. In fact - thats my point :o)
But I think it is a great idea. But we don't need to make a chain
be nested more than one level.
And head and tail filter must be hidden from user to prevent from
unexpected removal or reordering. Exactly. The ** user ** doesn't write the code above: This is in the acceptor (or whatever). The idea is that the user can contribute a chain (Jose's approach) how ever they like. The special "head tail" behaviour is encapsulated to the client who requires it: I.e, the acceptor / connector. This is what I like about the idea. Currently, if you write a filter chain, you need to care about that special head tail behaviour. Using this approach you wouldn't - because a chain is nothing more than a sequence of filters. Its the /acceptor / connector /who cares about the head / tail behaviour - so he can specify it directly.
Hopefully this example will clear up the creational logic:
Imagine this code is in SocketAcceptorDelegate.Worker#processSessions - when we've just found out we've got a new session: // Create the filter chain for the new connection / session BasicFilterChain connectionChain = new BasicFilterChain(); // Add the session manager chain to the connection chain connectionChain.addLast(sessionManagerChain); // Add the per-port chain to the connection chain connectionChain.addLast(portChain); // Let the user contribute to a new per-session chain (Jose's approach) BasicFilterChain sessionChain = new BasicFilterChain(); someChainBuilder.buildChain(sessionChain);
// Add the per-session filter to the connection chain
connectionChain.addLast(sessionChain); // Now create the filter which does ** our ** work (i.e, real handler writing) IoFilter workerFilter = new EndOfTheLineFilter(); connectionChain.add( workerFilter ); Notice that the /user /isn't specifying the worker filter - the SocketAcceptorDelegate is.
So I belive this gives us real benefits:
1) Makes the filter chain mechanism simpler (reduces complexity as we're now using composition rather than inheritance)
2) Paves the way for user contribution to chains (Jose's approach)
3) Doesn't require filter cloning or per-traversal clones
4) Is OO: The acceptor / connector is the actor who wants to specify "end of chain" behaviour: So he does so by means of adding a custom filter to the end of the built chain Does this clear it up at all?
What do you think about this approach?
Many thanks, Dave (give me sleep) Irving

This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you.


Reply via email to