Apache Directory Project - [mina] Refactoring MINA IoFilterChain (Was: IoFilters: DIRMINA-121 / 122)

This is Interesting: Free IT Magazines  
Home > Archive > Apache Directory Project > November 2005 > [mina] Refactoring MINA IoFilterChain (Was: IoFilters: DIRMINA-121 / 122)





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author [mina] Refactoring MINA IoFilterChain (Was: IoFilters: DIRMINA-121 / 122)
Trustin Lee

2005-11-14, 8:45 pm

Hi all,

We've talked about refactoring the current IoFilterChain implementation, and
I'd like to address some issues:

1) There should be only *one* NextFilter implementation for all filters in
the same chain for thread safety, and upstream/downstream (forwarding)
operations should be executed in head or tail filter. It can be overriden by
overriding createHeadFilter and createTailFilter. (and this is the same way
Dave suggested to us, but the current implementation hides head and tail
from the filter list to keep OOP encapsulation principal

2) We need to carefully consider if we have any other use case than having
concrete number of filter chain. I think we can have only three chains per
session at maximum. So I'm afraid this is an overengineering. Of course we
can provide more than one chain in session level, but I think we don't need
it actually because we can simply append the chain by adding
IoFilterChain.addAllLast() and addAllFirst(), and etc.

3) Should we pass IoHandler as a parameter even if I can get it
IoSession.getHandler()? Please let me know if I am missing something.

4) We cannot simply expose IoFilterChain.setIoProcessor() method because it
can break MINA so easily. So I'd like to suggest hiding setIoProcessor()
like this:

public void setFilterChain( IoFilterChain chain ) {
this.chain = new TransportTypeSpecificFilterChain( chain ); //
TransportTypeSpecificFilterChain extends IoFilterChainProxy.
}

public IoFilterChain getFilterChain() {
return this.chain.getFilterChain(); // Unwrap
}

Only TransportTypeSpecificFilterChain will provide setIoHandler or something
like that. But I think we already have doWrite and doClose in
AbstrctIoFilterChain and there are existing subclasses that implement them.
So I don't see much difference here except the behavior of
get/setFilterChain().

And please note that per-port and per-session filter chain should be cleared
(destroying all filters) when port is unbound or session is closed. This
means they are one-time use only because destroy call on a filter means
removal from a chain and vice versa. So we cannot have
IoSession.setFilterChain() because the specified chain will be cleared when
the connection is closed so it will prevent from specifying the same chain
for more than one sessions.

The biggest problem is that IoFilter.init() and destroy() is invoked
together when IoFilter.add(), remove(), and clear() is invoked. (It's
because the filter can be added or removed at any time.) To do so, IoFilter
has to remember who its parent is (IoSession or IoSessionManager). This
means we have to specify the correct parent when we construct a chain
unfortunately.

So I have to admit that there are so much complexity unfortunately to
provide setFilterChain() simply. Any solutions?

Not let's consider Jose's IoFilterChainBuilder. It is really simple solution
and work without any big changes. The only problem with the builder pattern
is that it can be abused to contain more than just building. A user can even
call System.exit(0) there. But it is entirely up to users eventually. So
I'd like to choose Jose's approach. I thought his approach adds more
complexity to the API, but now I think it is a way simpler and easy to
understand.

Cheers,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Trustin Lee

2005-11-14, 8:45 pm

2005/11/15, Trustin Lee <trustin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
>
> 1) There should be only *one* NextFilter implementation for all filters in
> the same chain for thread safety, and upstream/downstream (forwarding)
> operations should be executed in head or tail filter. It can be overridenby
> overriding createHeadFilter and createTailFilter. (and this is the same way
> Dave suggested to us, but the current implementation hides head and tail
> from the filter list to keep OOP encapsulation principal



I forgot to mention that we can remove createHead/TailFilter and let users
to specify them as constructor parameters.

Not let's consider Jose's IoFilterChainBuilder. It is really simple solution
> and work without any big changes. The only problem with the builder pattern
> is that it can be abused to contain more than just building. A user can even
> call System.exit(0) there. But it is entirely up to users eventually.
> So I'd like to choose Jose's approach. I thought his approach adds more
> complexity to the API, but now I think it is a way simpler and easy to
> understand.



Not -> Now

Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Trustin Lee

2005-11-15, 5:45 pm

Hi Niklas,

2005/11/15, Niklas Therning <niklas-8FIgwK2HfyIwFerOooGFRg@public.gmane.org>:
>
> If we forget about the IoFilterChain.getNextFilter() methods for the
> moment I don't really understand why there has to be one NextFilter.



It is because NextFilter can be cached by a filter in case it have to emit
the event even if any I/O event or request didn't occur. For example, there
can be a customized dynamic timeout filter.

With the solution I and Dave talked about Entry.nextFilter would go
> away. They would have to be created on the fly for each filter
> invocation in a chain. I realize that it wouldn't be possible to
> implement IoFilterChain.getNextFilter() if Entry.nextFilter wouldn't
> exist but are they really needed? If we are going to chain chains
> without copying them we will have to propagate the next IoHandler
> through the chain at filter time.



You're right. getNextFilter() is not actually required to be exposed, but it
is still true that a filter should be able to emit any event at any time
using nextFilter instance it cached.

I'm only interested in having at most three chains really. One tied to
> the SessionManager. This is where I would put the ThreadPoolFilter. One
> tied to the port. This is where I would put the SSLFilter. And one
> private to the IoSession. There should not be an
> IoSession.setFilterChain() method.



I see.

> 3) Should we pass IoHandler as a parameter even if I can get it
>
> The SessionManager (or SocketIoProcessor) will simply call
>
> this.filterChain.sessionOpened( session, session.getHandler() );
>
> If this.filterChain is Dave's ChainedFilterChain
> this.filterChain.sessionOpened() could look like:
>
> public void sessionOpened( session, handler ) {
> this.firstChain.sessionOpened( session, new
> IoFilterToIoHandlerAdapter(handler, this.secondFilter)) );
> }



I didn't get it yet. Can't we simply override head/tail filter for each
chain?

Yes, setIoProcessor() isn't very nice, I agree. And I don't have a
> solution for it except that copying the chain passed to setFilterChain()
> into something like an IoProcessorAwareFilterChain. I can't see how the
> above solves this. How does the wrapped chain know where to route
> write() / close() calls? Or is it just to prevent setIoProcessor() from
> being called?



Yes that's also a problem... so we have to copy the chain. (Sorry for the
confusion ;) But copying the chain rises another problem; init() and
destroy() is called immediately when a filter is added or removed.

> The biggest problem is that IoFilter.init () and destroy() is invoked
>
> I don't understand. Could you describe the problem a bit more?



As you know, there's no init() or destroy() in IoFilterChain. This means
there's no life cycle in IoFilterChain. The life cycle only exists in
filter-level. So when you add a filter to a chain, IoFilter.init() is called
imediately to initialize the filter. And IoFilter.destroy() is invoked when
the filter is removed from the chain. I didn't put init() or destroy() to
IoFilterChain because filters can be added and removed whenever a user
wants. User could even add filters after init() is invoked, and then we
should call IoFilter.init() immediately, so there's no much reason to
provide init() and destroy() in IoFilterChain.

So we know we have to call init() and destroy() when a filter is added. The
init() and destroy() method requires an IoFilterChain parameter as a parent..
(I made a mistake in my previous post. It requires IoFilterChain as a
parent) It is because one filter instance can be added to more than one
chains.

Now let's talk about cloning the chain. Take a look at this code:

IoFilterChain newFilterChain = new ...;
IoFilter filterA = new FilterA();
newFilterChain.addLast( "a", filterA);

acceptor.setFilterChain( newFilterChain ); // internally newFilterChain is
cloned.

This code will call filterA.init() twice with different parent
(IoFilterChain). This means user have to call newFilterChain.clear()
explicitly. Of course user will have to call acceptor.getFilterChain().clear()
when it shuts down, but two calls and one call are different IMHO.

Yes it's complex. But I wouldn't say that the current implementation is
> much simpler. It took quite some time and debugging to figure out how
> the filter chains work. (Maybe that's just me being really stupid ;) )
> What I like about this approach (except for setIoProcessor() which isn't
> really acceptable) is that the configuration of chains are totally
> detached and independent from the SessionManager.



Right, I love that advantage you mentioned. To work around the init() and
destroy() issue, the IoFilterChain implementation that user can construct
and that doesn't invoke init() and destroy() at all. But it's too tricky.
What about just introducing IoFilterConfig with minimal interface?

public interface IoFilterConfig { // perhaps we can implement is as a
concrete class simply.
public String getName();
public IoFilter getFilter();
}

and accepting a List of IoFilterConfigs?

If so, the implemtation of IoAcceptor.setFilterChain() will be...

public void setFilterChain(List filterConfigs) throws Exception {
this.chain.clear();
for( Iterator i = filterConfigs.iterator(); i.hasNext(); ) {
Object o = i.next();
if( o instanceof IoFilterConfig ) {
IoFilterConfig cfg = ( IoFilterConfig ) o;
this.chain.addLast( cfg.getName(), cfg.getFilter() );
} else if( o instanceof IoFilter ) {
IoFilter filter = ( IoFilter ) o;
this.chain.addLast( someAnonymousNameBasedOnFilterType, cfg.getFilter() );
}
}
}

WDYT?

Maybe I have totally misunderstood what Jose meant but I cant see how
> that would simplify anything. You would still have the problem of wiring
> the three chains together. Or am I missing something fundamental? As I
> said previously, the wiring of chains is problem number 1, how to
> configure per-port chains is problem number 2.



For problem #1, yes, we still have to resolve that problem. But Jose's
approach solves Problem #2. We can pass port-level filter chain to the
builder.

Cheers,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Trustin Lee

2005-11-15, 5:45 pm

2005/11/15, Niklas Therning <niklas-8FIgwK2HfyIwFerOooGFRg@public.gmane.org>:
>
> I just realized that when calling IoSession.write() the concrete
> IoSession implementation will always know the final destination of the
> write event. For SocketSessionImpl the final destination is always
> SocketIoProcessor.
>
> So the IoFilterChain methods for downstream events look like this:
>
> void write( IoSession session, WriteRequest writeRequest, IoProcessor p
> ) throws Exception;
>
> SocketSessionImpl's write() method looks like this:
>
> public WriteFuture write( Object message ) {
> this.filterChain.write(this, new WriteRequest(),
> SocketIoProcesso.getInstance());
> }



What is the difference from overriding the head filter of
sessionmanager-level chain to call SocketIoProcessor.flush() explicitly? We
can still get rid of SocketSessionManagerFilterChain without introducing a
new parameter.

I'll check in this change so you can see it more clearly.

Cheers,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Irving, Dave

2005-11-15, 5:45 pm

I too agree that setIoProcessor isn't all that nice - and what I was
trying to think about last night was ways to get away from it.
Im not so tired this morning (although 4 hours sleep didn't help
much...) but I'll try to explain my approach a bit more clearly.
It kind of boils down to a few points:

1) We want to chain "sequences" of filters (a filter chain) together
2) Soon we want to be able to let users build their own filters=20
3) We want to preserve OOP

To me, the current filter chain / filter implementation looks quite
complicated. I haven't got familiar enough with the code yet to know
whether ths complexity is an unfortunate necessity.
Just so we know what my proposed approach is, I'll try and describe the
basics here:

1) I don't see how refactoring the chains affects Jose's approach. If we
have individual chains, we can still pass them to a builder to be
populated
2) Why not make IoFilterChain move towards the composite pattern? A
filter chain is just a special type of filter which filters in a
sequence. No special head, no special tail. Just a sequence 0..n. So
given some "BasicFilterChain" impl, we can add both individual filters
and filter chains to the chain. NextFilters can ** still ** be cached by
individual filters - no change there.
3) I think filters can still be used ** without ** cloning and without
special "setIoProcessor" methods. Asume that we have (2). When a new
connection is established, all we have to do is "hook up" our sub
chains:

BasicFilterChain connectionChain =3D new BasicFilterChain();
connectionChain.addLast(sessionManagerChain);=20
connectionChain.addLast(portChain);
BasicFilterChain sessionChain =3D new BasicFilterChain();
someChainBuilder.buildChain(sessionChain); // Jose's approach
connectionChain.addLast(sessionChain);

connectionChain.add(endOfTheLineFilter);

And that's it - connectionChain becomes the uniqueue chain for a
connection. The last addition, the "endOfTheLineFilter" - is just a
filter that does the "real" work (like Niklas' IoProcessor approach -
but now encapsulated in a filter). Because this is per-connection, the
"endOfTheLine" filter can be provided with the collaborators it needs to
do its job without affecting any other filter.
This doesn't require any "cloning" of chains, or creation of NextFilters
per traversal either.

This to me seems like a much cleaner approach - but I must be missing
something?

Dave


This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Trustin Lee

2005-11-15, 5:45 pm

Hi Dave,

2005/11/15, Irving, Dave <dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org>:
>
> To me, the current filter chain / filter implementation looks quite
> complicated. I haven't got familiar enough with the code yet to know
> whether ths complexity is an unfortunate necessity.



Yes, it is really complex.

Just so we know what my proposed approach is, I'll try and describe the
> basics here:
>
> 1) I don't see how refactoring the chains affects Jose's approach. If we
> have individual chains, we can still pass them to a builder to be
> populated



Right there's no much relationship.

2) Why not make IoFilterChain move towards the composite pattern? A
> filter chain is just a special type of filter which filters in a
> sequence. No special head, no special tail. Just a sequence 0..n. So
> given some "BasicFilterChain" impl, we can add both individual filters
> and filter chains to the chain. NextFilters can ** still ** be cached by
> individual filters - no change there.
> 3) I think filters can still be used ** without ** cloning and without
> special "setIoProcessor" methods. Asume that we have (2). When a new
> connection is established, all we have to do is "hook up" our sub
> chains:
>
> BasicFilterChain connectionChain = new BasicFilterChain();
> connectionChain.addLast(sessionManagerChain);
> connectionChain.addLast(portChain);
> BasicFilterChain sessionChain = new BasicFilterChain();
> someChainBuilder.buildChain(sessionChain); // Jose's approach
> connectionChain.addLast(sessionChain);
>
> connectionChain.add(endOfTheLineFilter);



Explicitly asking users to add head/tail filter is a bad idea. 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.

Cheers,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Trustin Lee

2005-11-15, 5:45 pm

Hi,

2005/11/15, Niklas Therning <niklas-8FIgwK2HfyIwFerOooGFRg@public.gmane.org>:
>
> Trustin Lee wrote:
>
> If the user can change the filter chain of an IoAcceptor by calling
> setFilterChain() you won't be able to override any method to inject this
> behaviour. Likewise if there is a bind(address, chain, handler) method.
> Unless you copy the user supplied chain into some IoFilterChain
> implementation which we have control over. And from what I understand
> copying is out of the question. Or am I missing something?



If we're going to use setfilterChain only for the initial configuration,
then we can copy. Otherwise we cannot. The problem here is that we cannot
easily reuse IoFilterChain because it contains too much information.

Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Irving, Dave

2005-11-15, 5:45 pm


> 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 copiesand inform the sender. Thank you.

Irving, Dave

2005-11-15, 5:45 pm

> Its the acceptor / connector who cares about the head / tail behaviour
- so he can specify it directly

Just to clarify: With this approach there is no explicit head / tail.
The SocketAcceptorDelegate et al just add their work as the last filter
in the per-connection chain.
The user is never exposed to the whole per connection chain (they only
ever see the per session chain) - so it is impossible for them to tinker
with it

Dave

________________________________

From: Irving, Dave [mailto:dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org]
Sent: 15 November 2005 09:41
To: Apache Directory Developers List
Subject: RE: [mina] Refactoring MINA IoFilterChain (Was: IoFilters:
DIRMINA-121 / 122)



> 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.


Irving, Dave

2005-11-15, 5:45 pm

Niklas Therning wrote:

>I really like your approach, Dave. Some question though:
> What would session.getFilterChain() return? It will be sessionChain,

right?

Yes. This allows IoHandlers or who-ever to contribute to the session
chain.=20
They ** never ** get access to the "connection chain" (which is a
private implementation detail of SocketAcceptorDelegate etc).

> Will IoFilterChain extend IoFilter and be just another IoFilter?


Depends. I think at the moment there's not all that much need for true
composite - as Trustin says.
However, I don't think its any more or less work either way - and I
think its cleaner to have a chain as a special type of filter.=20
However, this ** could ** be blown away by the NextFilter problem.

> This is basically the same as nesting filter chains as I proposed

yesterday (remember the (((A, B), C), D) thingy?)=20
> but it's a flat list of chains instead, right?


Yeah - I think we were both talking about the same thing all along but
didn't realise it in our respective tiredness :o)

> You still have the NextFilter problem.=20
> As I understand it these have to be static since IoFilter.init() is

called when the filter is added to a chain.=20
> A NextFilter is passed to this method and the filter could remember

this for future use.

Yes - I certainly do have a NextFilter problem. This is quite similar to
the "this problem" often found when employing the decorator pattern.
Im going to spend some time this morning thinking about how we can get
round it cleanly and transparently: But I understand that support for
NextFilter caching is required, important, and must not be lost.

> I can't see how the last filter in a wrapped chain will know where to

go next if the NextFilter given=20
> to it can't be created dynamically.=20
> Remember, sessionManagerChain and portChain will be shared by many

connectionChains.

Yep - Im going to have to think about that this morning / this
afternoon.
However, I believe that finding a solution is worth it - as Im sure
we're on to a clean solution :o)


> /Niklas


Dave


This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Irving, Dave

2005-11-15, 5:45 pm


> So do I! Keep us posted.

(The NextFilter problem)

Ok, I've thought about it, and I can only really think of one solution.
The problem is that it sounds like we have to support completely
asyncronous invocations on NextFilter.
The issue there is that without cloning filters, a given port filter
logically applies to ALL chains it belongs to...

Except that we should remember that a full connection chain is always
associated with a connection (IoSession). And there would always be a
single connection chain per connection.

So why don't we just dispatch based on IoSession??

I.e, we have something like a "ConnectionChains" class which holds all
chains - mapped against IoSessions.
The final filter of a sub-chain (sessionManager chain, port chain,
session chain) is set by ConnectionChains to some private inner class.
When the last filter of a sub-chain is invoked, ConnectionChains does a
( O(1) ) look up for the correct ConnectionChain based on session and
delegates.

This allows us to get all the benefits previously discussed and solves
the NextFilter problem (including completely asyncronous calls to
NextFilter) without requiring cloning (which could be costly for some
filters).

How does that sound?


> /Niklas


Dave


This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Trustin Lee

2005-11-15, 5:45 pm

Hi all,

2005/11/15, Niklas Therning <niklas-8FIgwK2HfyIwFerOooGFRg@public.gmane.org>:
>
>
> Please do that. Maybe that will make me understand!



The change was not really trivial, so I couldn't make it in short time. You
guys look really eager to refactor my overcomplex code, please go ahead, and
let's find out its problem. ;)

Cheers,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Trustin Lee

2005-11-15, 5:45 pm

Hi Dave,

I started to like your suggestion, and I'd like to see its realization.

2005/11/15, Irving, Dave <dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org>:
>
> So why don't we just dispatch based on IoSession??
>
> I.e, we have something like a "ConnectionChains" class which holds all
> chains - mapped against IoSessions.
> The final filter of a sub-chain (sessionManager chain, port chain,
> session chain) is set by ConnectionChains to some private inner class.
> When the last filter of a sub-chain is invoked, ConnectionChains does a
> ( O(1) ) look up for the correct ConnectionChain based on session and
> delegates.



Good idea. Perhaps we can use session attributes here?

This allows us to get all the benefits previously discussed and solves
> the NextFilter problem (including completely asyncronous calls to
> NextFilter) without requiring cloning (which could be costly for some
> filters).
>
> How does that sound?



Sounds cool.

BTW J-F once asked us about emitting an event virtually (not a real I/O
event but fabricated one). I guess we can support this in our
ConnectionChain by exposing event emitting methods like I did in
AbstractIoFilterChain?

Cheers,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Irving, Dave

2005-11-15, 5:45 pm

Hi Trustin,

Im really sorry if anything I said came accross like I was critisising
the current implementation. I certainly didn't mean it do :o)
I was simply searching for a clean way to enable 121 and 122 to get
solved in a clean way - and it seemed that refactoring the existing
chain mechanics might be a reasonable way to do that.
Thanks for your comments - I'll try and address them here:

> I started to like your suggestion, and I'd like to see its

realization.

I'll start working on it in earnest :o) Hopefully I'll be able to report
back with a patch in the next few days.

a [vbcol=seagreen]
[vbcol=seagreen]
> Good idea. Perhaps we can use session attributes here?


Session attributes are definately the best way to go here. It means we
dont need to hold a mapping within ConnectionChains - and we dont need
additional syncronization. I hadn't yet thought about how I'd implement
the mapping efficiently - so this suggestion is really very very useful
to me. Thanks!!!

> BTW J-F once asked us about emitting an event virtually (not a real

I/O event but fabricated one).
> I guess we can support this in our ConnectionChain by exposing event

emitting methods like I did in AbstractIoFilterChain?

Sure!

Have an IoEventProcessor interface or some-such. The ConnectionChains
(or whatever) can implement this ( - to kick off traversal like
AbstractIoFilterChain does).
This can then be exposed to the user (without having to expose the
connection chain - which would be dangerous for obvious reasons).

E.g:
IoEventProcessor processor = somthing.getEventProcessor();
processor.messageReceived(session, message);

Viola - virtual Io events propogating right through the correct
connection chain :o)

Dave


________________________________

From: Trustin Lee [mailto:trustin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org]
Sent: 15 November 2005 12:18
To: Apache Directory Developers List
Subject: Re: [mina] Refactoring MINA IoFilterChain (Was: IoFilters:
DIRMINA-121 / 122)


Hi Dave,

I started to like your suggestion, and I'd like to see its realization.



2005/11/15, Irving, Dave <dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org >:

So why don't we just dispatch based on IoSession??

I.e, we have something like a "ConnectionChains" class which
holds all
chains - mapped against IoSessions.
The final filter of a sub-chain (sessionManager chain, port
chain,
session chain) is set by ConnectionChains to some private inner
class.
When the last filter of a sub-chain is invoked, ConnectionChains
does a
( O(1) ) look up for the correct ConnectionChain based on
session and
delegates.


Good idea. Perhaps we can use session attributes here?



This allows us to get all the benefits previously discussed and
solves
the NextFilter problem (including completely asyncronous calls
to
NextFilter) without requiring cloning (which could be costly for
some
filters).

How does that sound?


Sounds cool.

BTW J-F once asked us about emitting an event virtually (not a real I/O
event but fabricated one). I guess we can support this in our
ConnectionChain by exposing event emitting methods like I did in
AbstractIoFilterChain?

Cheers,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/


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 copiesand inform the sender. Thank you.

Trustin Lee

2005-11-15, 5:45 pm

2005/11/15, Irving, Dave <dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org>:
>
> Hi Trustin,
> Im really sorry if anything I said came accross like I was critisising
> the current implementation. I certainly didn't mean it do :o)
>


No problem. I don't feel bad at all. We're all here to make MINA the best
network application framework as you know. I think we can even beat ACE in
the near future ;)

Cheers,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Jose Alberto Fernandez

2005-11-15, 5:45 pm

> From: Irving, Dave [mailto:dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org]
>=20
> It kind of boils down to a few points:
>=20
> 1) We want to chain "sequences" of filters (a filter chain) together


Ok, why is it that we want to do this? What is it that we are trying to
solve?

> 2) Why not make IoFilterChain move towards the composite pattern? A
> filter chain is just a special type of filter which filters in a
> sequence. No special head, no special tail. Just a sequence 0..n. So
> given some "BasicFilterChain" impl, we can add both individual filters
> and filter chains to the chain. NextFilters can ** still ** be cached

by
> individual filters - no change there.


Well, you could define today your own filter that encapsulates a filter
chain inside and that does this propagation. The only thing you cannot
do with such an arrangement is modify the encapsulated chain from
outside (unless you know is being encapsulated and make the
corresponding calls on the encapsulating filter).

public class EncapsulatedChainFilter(IoFilterChain chain) {
// Implementation delegates all methods to the chain and the
head and tail use the nextfilter object to connect up or down as
required.
}

Jose Alberto


Irving, Dave

2005-11-15, 5:45 pm


=20
[vbcol=seagreen]
> Ok, why is it that we want to do this? What is it that we are trying

to solve?

One motivation is that concrete chain implementations currently specify
"end of chain" behaviour (e.g: SocketSessionManagerFilterChain,
DatagramSessionManagerFilterChain etc).
When we were originally looking at implementing 121 / 122, Niklas
suggested that it would be nice to refactor this - and I agree - as it
makes it more difficult to chain arbitrary filter chains in to longer
chains.
By doing the refactor, the "special" operations (currently provided by
SocketSessionManagerFilterChain et al) are provided by composition -
leaving a single basic chain implementation.

> Well, you could define today your own filter that encapsulates a

filter chain inside and that does this propagation.=20
> The only thing you cannot do with such an arrangement is modify the

encapsulated chain from outside=20
> (unless you know is being encapsulated and make the corresponding

calls on the encapsulating filter).

> public class EncapsulatedChainFilter(IoFilterChain chain) {
> // Implementation delegates all methods to the chain and the

head and tail use the=20
> // nextfilter object to connect up or down as required.
> }


There is then a "NextFilter" problem. Each filter must be able to cache
its NextFilter to enable event propogation asyncronously. Say we used
the EncapsulatedChainFilter to hook together the sessionManager, port
and session chains for a connection. The problem would be that when the
last filter in, say, the port chain completed, we wouldn't be able to
route to the correct next filter chain (as sessionManager / port chains
are reused across connections).
That's why I suggested "ConnectionChains" (or whatever) which
encapsulates several connection chains, and performs routing based on
the session (very cheap using a Session attribute). (ConnectionChains
stuff is all behind the scenes).

What I think we end up with is a simple way to combine arbitrary chains
without requiring explicit subclassing for each use case.


> Jose Alberto


Dave


This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Jose Alberto Fernandez

2005-11-15, 5:45 pm

> From: Irving, Dave [mailto:dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org]
>=20
>=20
together[vbcol=seagreen]
>=20
> to solve?
>=20
> One motivation is that concrete chain implementations currently

specify
> "end of chain" behaviour (e.g: SocketSessionManagerFilterChain,
> DatagramSessionManagerFilterChain etc).
> When we were originally looking at implementing 121 / 122, Niklas
> suggested that it would be nice to refactor this - and I agree - as it
> makes it more difficult to chain arbitrary filter chains in to longer
> chains.


Why is it that we want to chain arbitrary filter chains into longer
chains?
It seems that the reason for the requirement is the requirement itself.
But what is the reason for it?

I may be mistaken, but it seems to me the whole reason for this is to be
able, eventually, to specify a chain in a spring based model and set it
up during configuration. Am I off the mark here?

Wouldn't it be simpler (or less disruptive) to simply configure some
other object (lets say a ChainBuilder) with all the filters one
requires, and during execution (the call to build) it will just add all
the filters to the chain programmatically. No need to re-engineer
everything just one smart spring aware builder.

Would this solve any of the user patterns we are trying to deal with in
here?

Jose Alberto


Irving, Dave

2005-11-15, 5:45 pm

=20

> Why is it that we want to chain arbitrary filter chains into longer

chains?
> It seems that the reason for the requirement is the requirement

itself.
> But what is the reason for it?


As per Niklas' email, we'll need to support a combined sessionManager
chain, port chain and connection chain.
Is there a clean way to do this that I've missed? Im certainly not
interested in doing work for works sake :o)

> I may be mistaken, but it seems to me the whole reason for this is to

be able, eventually, to specify a chain=20
> in a spring based model and set it up during configuration. Am I off

the mark here?

I think the refactoring we are talking about is not related to spring
configuration per-se. In all cases, the three layers of chains will be
available to be populated by a builder or whatever. The problem we are
solving, as far as I can tell, is how to have re-usable chains of
filters (sessionManager, port, session) cleanly and efficiently (i.e,
not having to clone).

> Wouldn't it be simpler (or less disruptive) to simply configure some

other object (lets say a ChainBuilder)=20
> with all the filters one requires, and during execution (the call to

build) it will just add all the=20
> filters to the chain programmatically. No need to re-engineer

everything just one smart spring aware builder.

As above, the spring configuration is not the direct motivation for the
refactoring.

> Would this solve any of the user patterns we are trying to deal with

in here?

Niklas wants to specify re-usable port chains, and presumably its
helpful to be able to specify re-usable session manager level chains
(acceptor / connector). The problem to solve is how to cleanly hook
these chains together.=20
It seems that the proposed refactoring is quite a simple and transparent
way of doing this - but if I've missed an existing easy and clean way to
do this - please let me know - as I don't want to head down the wrong
path!=20

> Jose Alberto


Dave


This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Jose Alberto Fernandez

2005-11-15, 5:45 pm

> From: Niklas Therning [mailto:niklas-8FIgwK2HfyIwFerOooGFRg@public.gmane.org]
>=20
> Jose Alberto Fernandez wrote:
>=20
be[vbcol=seagreen]
it[vbcol=seagreen]
all[vbcol=seagreen]
in[vbcol=seagreen]
> I've actually thought of adding such a feature to the
> AbstractIoAcceptorFactoryBean. I think it would require a proxy for

the
> real IoHandler which intercepts sessionCreated() and simply adds the
> appropriate port-specific filters to the session's filter chain before
> forwarding to the real IoHandler. It's not a bad idea at all and I

might
> do it that way in the meantime. Thanks for pointing that out!
>=20


But remember the spirit of 121/122 is that you will have port level
filters.
The builder will configure the port level filters (which as I understand
today gets cloned when a session is created). So in this scenario you do
not need to play with sessionCreated or anything, the spring configured
builder will just apply the filters during binding and then the
IoHandler is free to do whatever it requires.=20

Now, in this model it is very simple to define composite builders since
they just need to call the build method on each one of its components
passing the chain. This will allow a very simple and straight forward
composition patters.

> But I also think that the refactoring Dave is working on will make the
> code simpler to understand/maintain and give more flexibilty. Let's

see
> what he comes up with and take it from there.


Simplification is good, and I am all for it. But the current solutions
seem to be requiring exposing more and more things tat users can break
instead of less. That looks like more complexity to me. May be I am
mistaken.

To be truthful, I have not even look at the 0.9 code. I work in 0.8 and
the implementation there seem to be quite simple and easy to understand.
Filters do not have init/destroy calls which from the conversation here
seem to be causing a lot of trouble. To me filters should be as
stateless as possible (they can keep any state they want in the
session).

And finally (this is getting way too long), I do not think one should be
able to cache the NextFilter object, just like that. It sounds wrong to
me.
Instead, I would suggest providing two methods:

1) String NextFilter.getCurrentFilterName() : allows a filter to get
its name on the chain (I would enforce names to be unique).

2) NextFilter IoFilterChain.getNextFilterFor(String name) : returns the
NextFilter instance that can be use to send something across. If the
named filter is no longer in the chain, you get null or some exception.

With something like this I think one really can simplify things.

Comments?

Jose Alberto


Jose Alberto Fernandez

2005-11-15, 5:45 pm

> From: Irving, Dave [mailto:dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org]
>=20
>=20
> As per Niklas' email, we'll need to support a combined sessionManager
> chain, port chain and connection chain.
> Is there a clean way to do this that I've missed? Im certainly not
> interested in doing work for works sake :o)
>=20


My understanding of Niklas e-mail was that his main reason WAS spring.

>=20
> I think the refactoring we are talking about is not related to spring
> configuration per-se. In all cases, the three layers of chains will be
> available to be populated by a builder or whatever. The problem we are
> solving, as far as I can tell, is how to have re-usable chains of
> filters (sessionManager, port, session) cleanly and efficiently (i.e,
> not having to clone).
>=20


As long as you have addBefore/addAfter (which exist on 0.8, not sure
about 0.9) you will have to clone, as the filter chain is mutable. The
best you can do is to implement lazy copy. I do not see a real way out
of it.

>=20
> Niklas wants to specify re-usable port chains, and presumably its
> helpful to be able to specify re-usable session manager level chains
> (acceptor / connector). The problem to solve is how to cleanly hook
> these chains together.
> It seems that the proposed refactoring is quite a simple and

transparent
> way of doing this - but if I've missed an existing easy and clean way

to
> do this - please let me know - as I don't want to head down the wrong
> path!


So what happens when I call IoFilterChain.addFirst() on
sessionCreated(). As I said the best you can do is lazy copy.

Jose Alberto


Irving, Dave

2005-11-15, 5:45 pm

=20
> Now, in this model it is very simple to define composite builders

since they just need to call the build method on=20
> each one of its components passing the chain. This will allow a very

simple and straight forward composition patters.

This doesn't change.

the=20[vbcol=seagreen]
see[vbcol=seagreen]
[vbcol=seagreen]
> Simplification is good, and I am all for it. But the current solutions

seem to be requiring exposing more=20
> and more things tat users can break instead of less. That looks like

more complexity to me. May be I am mistaken.

I think maybe I've made the change sound like more than it is.

All my first patch will do is make it easy for the inner workings of
mina to chain sub-chains together.=20
Basically, Im implementing your "EncapsulatedChainFilter" (in a slightly
different way to how you described).=20
As part of this, the AbstractIoHandler subclasses which provide
transport specific behaviour will be refactored in to normal filters
(this is an implementation detail of the change).

=46rom the API perspective, nothing more will be exposed to the user (at
all) except for the following:

- Ability to populate an acceptor specific chain with a builder
- Alibity to populate a port specific chain with a builder
- Ability to populate a session specific chain with a builder

The filter chain used for a given session will be the sequence of
acceptor chain, port chain, session chain.

Nothing else will change from the users perspective. If my
implementation makes it any easier for the user to break things, then
I've screwed up and any patch should be thrown in the bin :o)

Dave






This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Irving, Dave

2005-11-15, 5:45 pm



> My understanding of Niklas e-mail was that his main reason WAS spring.


At the moment though, a handler which wants a certain filter per port
must have this logic (directly, or injected) in the handler.
It seems like a nice feature to be able to specify filters on a per
acceptor and port level.


> As long as you have addBefore/addAfter (which exist on 0.8, not sure

about 0.9) you will have to clone,=20
> as the filter chain is mutable. The best you can do is to implement

lazy copy. I do not see a real way out of it.

A mutable chain is fine with the proposed approach. The implementation
details have been discussed in earlier emails, but basically an owning
"CommandChains" (or something) class fixes the head and tail of
sub-chains (which users cant do) to manage sub-chain routing.
What this means is that whatever a user can currently do to a filter
chain, they will still be able to do after the chain.


> So what happens when I call IoFilterChain.addFirst() on

sessionCreated(). As I said the best you can do is lazy copy.

I don't think so. The filter chain a ** user ** is exposed to is just
the per session chain. The user can still make any changes to this as
they desire. They can clear it if they want!=20
The crucial bit is that the implementation (which the user doesn't see)
has fixed head and tail filters to manage the sub-chain routing. Users
can play with the filters all they want.

Hope this is clearer

> Jose Alberto



Dave


This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Jose Alberto Fernandez

2005-11-15, 5:45 pm

So, there is no way for me to impose a Blacklist filter specific to a
handler before I do SSL and all other stuff someone else has configured
already at port level?

That does not sound right.

Jose Alberto

P.S. Do not take me wrong, I want the least amount of copying as
possible. As a matter of fact, once we have port level filters I would
move all session level settings to port level settings. Nothing else
makes sense to me.
Session level filters should only be used in very specific cases related
to the actual session you are working with. Hence, lazy copying will be
reduced to a minimum.

Jose Alberto

> -----Original Message-----
> From: Irving, Dave [mailto:dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org]=20
> Sent: 15 November 2005 15:12
> To: Apache Directory Developers List
> Subject: RE: [mina] Refactoring MINA IoFilterChain (Was:=20
> IoFilters: DIRMINA-121 / 122)
>=20
>=20
>=20
> WAS spring.
>=20
> At the moment though, a handler which wants a certain filter=20
> per port must have this logic (directly, or injected) in the handler.
> It seems like a nice feature to be able to specify filters on=20
> a per acceptor and port level.
>=20
>=20
> about 0.9) you will have to clone,=20
> lazy copy. I do not see a real way out of it.
>=20
> A mutable chain is fine with the proposed approach. The=20
> implementation details have been discussed in earlier emails,=20
> but basically an owning "CommandChains" (or something) class=20
> fixes the head and tail of sub-chains (which users cant do)=20
> to manage sub-chain routing.
> What this means is that whatever a user can currently do to a=20
> filter chain, they will still be able to do after the chain.
>=20
>=20
> sessionCreated(). As I said the best you can do is lazy copy.
>=20
> I don't think so. The filter chain a ** user ** is exposed to=20
> is just the per session chain. The user can still make any=20
> changes to this as they desire. They can clear it if they want!=20
> The crucial bit is that the implementation (which the user=20
> doesn't see) has fixed head and tail filters to manage the=20
> sub-chain routing. Users can play with the filters all they want.
>=20
> Hope this is clearer
>=20
>=20
>=20
> Dave
>=20
>=20
> This e-mail and any attachment is for authorised use by the=20
> intended recipient(s) only. It may contain proprietary=20
> material, confidential information and/or be subject to legal=20
> privilege. It should not be copied, disclosed to, retained or=20
> used by, any other party. If you are not an intended=20
> recipient then please promptly delete this e-mail and any=20
> attachment and all copies and inform the sender. Thank you.
>=20


Irving, Dave

2005-11-15, 5:45 pm

> So, there is no way for me to impose a Blacklist filter specific to a
handler before I do SSL=20
> and all other stuff someone else has configured already at port level?


Every filter has the ability to know what handler a filter invocation
applies to if it really needs to (Each filter method is given a
IoSession. Then there is IoSession#getHandler).

> Session level filters should only be used in very specific cases

related to the actual session you are working with.=20
> Hence, lazy copying will be reduced to a minimum.


So presumably your blacklist filter would be at the port (or even
session manager) level - in which case you would configure it to come
before SSL.

Could you explain the problem further as Im not understanding how the
proposed chains wouldn't work for your example.

Dave



This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Jose Alberto Fernandez

2005-11-15, 5:45 pm

> From: Irving, Dave [mailto:dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org]=20
>=20
> specific to a
> handler before I do SSL=20
> port level?
>=20
> Every filter has the ability to know what handler a filter=20
> invocation applies to if it really needs to (Each filter=20
> method is given a IoSession. Then there is IoSession#getHandler).
>=20
> related to the actual session you are working with.=20
>=20
> So presumably your blacklist filter would be at the port (or=20
> even session manager) level - in which case you would=20
> configure it to come before SSL.
>=20
> Could you explain the problem further as Im not understanding=20
> how the proposed chains wouldn't work for your example.
>=20


Well the point, in this hypotetical case, is that I do not want to use
this=20
Blacklist filter on ALL my ports (IoAcceptor level). Lets assume this
filter is really part of the protocol I am implementing, independently
of whether I decide to use SSL or not. It would be nice if at each level
I can have access to the entire chain (from the socket to the handler)
and for me to manipulate as I please. You could be able to implement
handlers that can reconfigure its entire chain as they go, if so they
please.

Now, for this to be safe, you would need to do lazy copy, so that when
such an action occurs you stop sharing.

Jose Alberto

Irving, Dave

2005-11-15, 5:45 pm

> Well the point, in this hypotetical case, is that I do not want to use

> this Blacklist filter on ALL my ports (IoAcceptor level). Lets assume

this=20
> filter is really part of the protocol I am implementing, independently

of whether=20
> I decide to use SSL or not.=20


Ok, I see. However, even in this hypothetical case: Wouldn't you just
configure SSL at the port level too (not acceptor level).
Then there wouldn't be a problem.

Sorry for probing - Im just trying to establish whether there is any
real need for exposing the whole chain on a per connection basis. If
there is, it makes this change a fair bit more complicated :o)

> It would be nice if at each level I can have access to=20
> the entire chain (from the socket to the handler) and for me to

manipulate as I=20
> please. You could be able to implement handlers that can reconfigure

its entire chain=20
> as they go, if so they please.


> Now, for this to be safe, you would need to do lazy copy, so that when

such an action=20
> occurs you stop sharing.


I hadn't planned to expose the whole chain as part of 121 / 122. I think
its probably quite a bit more complicated to implement than what we're
planning to do at the moment.=20
If we do really need it - it would be good to know at the earliest
opportunity - as Im starting to implement a proposed solution for
121/122 now=20

> Jose Alberto


Thanks,

Dave



This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Jose Alberto Fernandez

2005-11-15, 5:45 pm

> From: Irving, Dave [mailto:dave.irving-iKsOTpgdUR76V6G2DxALlg@public.gmane.org]=20
>=20
> Ok, I see. However, even in this hypothetical case: Wouldn't=20
> you just configure SSL at the port level too (not acceptor level).
> Then there wouldn't be a problem.
>=20
> Sorry for probing - Im just trying to establish whether there=20
> is any real need for exposing the whole chain on a per=20
> connection basis. If there is, it makes this change a fair=20
> bit more complicated :o)
>=20


Yes, for this specific example, you may be right. But lets assume some
other.
Lets assume I have a port level filter configuration consisting of:
threadFilter,=20
kerberosFilter, codecFilter, and someFilterManager.

Now, as part as the protocol, the client may request TLS privacy once
authenticated.
So, on a particular session, the client requests privacy, which means
adding the SSLFilter
after threadFilter and activate it. Now I want this change only for this
session, not for all the sessions on this port. I cannot do SSL at the
end of the chain because I need to decode first.

This means I need to reconfigure the chain, just for this session. Now
the current solution requires my to setup the entire chain on a session
by session basis (which is really waistful as we all agree). If instead
you share the chain, and only do the cloning on demand (when SSL is
reqested by a session) then you can save on average.

And since you have only one chain (either shared or private) at any
given point in time, the implementation has to be simpler. I do not see
how it may become more complicated.

Jose Alberto


Irving, Dave

2005-11-15, 5:45 pm

Jose Alberto wrote:

> Now, as part as the protocol, the client may request=20
> TLS privacy once authenticated.
> So, on a particular session, the client requests privacy,=20
> which means adding the SSLFilter after threadFilter and activate it.=20
> Now I want this change only for this session, not for all the sessions


> on this port. I cannot do SSL at the end of the chain because I need=20
> to decode first.


Thanks - that makes perfect sense and I see where you are coming from
now.

> And since you have only one chain (either shared or private) at any

given point in=20
> time, the implementation has to be simpler. I do not see how it may

become more complicated.

If we're supporting sharing, then we need the existing proposed changes
to support that. The lazy copying comes on top of this - so Im not sure
the overall change would be simpler.
To support this, we'd need to work out how to do the lazy copying you
are talking about.
I don't think its so simple as IoFilters are initialised with a
NextFilter and are allowed to use that filter at any time to make
requests. So we'd either have to change the way they do this as you
discussed earlier (effects all filter implementations) or we'd have to
make them cloneable (or whatever. Again - effects all filter
implementations).
Either change is likely to have big impacts - and with my level of Mina
experience I think I'd have to take a back seat and leave it to the
experts (which is the best thing all round if there is a better way to
do this that Im not yet up to implementing).

The only easy way I can think of doing what you want (without requiring
changes to the Filter API) is as follows:

We now have the ability to make "chains of chains" very simply (routing
based on session).
There is nothing to stop us allowing a session to make a chain
"contribution" at any point along the "chain of chains".
E.g, in your IoHandler you realise that your client has requested TLS
which must come before anything else.
You'd do this:

IoFilterChain chain =3D IoSession.getSessionChainBefore("sessionManager");
// configure the chain how you like
chain.addLast(myTlsFilter);

The chain would be created on demand and you could modify it however you
wanted. For all subsequent traffic, your tls filter would be the first
filter used.

Most users would probably not need this however, and would just get the
"regular" session chain:
IoFilterChain sessionChain =3D IoSession.getFilterChain();


I understand that this may not be good enough: For example, you may now
say that if they want TLS, you should remove some other filter that was
configured at the port level. This solution wouldn't support that as it
stands. (I suppose it would be possible to opt out of filters with more
work though).


So, in summarry (sorry, it was long again), I don't see how the Lazy
Copying can work without changes to the API and semantics of IoFilter -
which Im not experienced enough to contribute to.=20
Please let me know if my proposed additional change is likely to be of
use to you.

> Jose Alberto


Many thanks,

Dave







This e-mail and any attachment is for authorised use by the intended recipi=
ent(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 recipien=
t then please promptly delete this e-mail and any attachment and all copies=
and inform the sender. Thank you.

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com