mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Emmanuel Lecharny <elecha...@gmail.com>
Subject Re: [About the Filter Chain] Proposals
Date Tue, 04 Nov 2008 00:06:25 GMT
Jeanfrancois Arcand wrote:
> Salut,
>
>> Another option, and it's not a bad idea, would be to define a 
>> threadSafe chain, which can be modified, or a not synchronized chain, 
>> which can't be changed. We have to dig those ideas.
>
> Just for my understanding, does the chain be modified by the user? 
> Would it be too demanding to ask the user to sync its filter itself. 
> That's one of the reason why we have 2 mode in Grizzly, but that might 
> not be a good idea :-)
Yrs, the user can modify the chain (well, 'user' here means the guy who 
write the application using MINA :) But we can also think about a 
self-configuring system which add a new filter in the chain right in the 
middle of an event processing. A good exemple could also be to add a new 
logging filter when having some error we want to log, but only if we get 
this error.

In order to protect the chain against concurrent modification, the ideas 
I have are :
- always call the next filter using a getNextFilter() method which can 
contain some protected section
- define a thread-safe chain a bit like you can declare a protected 
collection (Collections.synchronizedCollection( set )). We may do the 
very same for the chain: ChainUtil.synchronizeChain( myChain).
- maybe set a simple volatile flag, used in the getNextFilter to avoid a 
heavy synchronization

Anyway, there are options here, and it can be user driven (as you create 
the chain before it is injected into the server, you can create it 
thread safe, or not).

It has to be tested in the branch...
>> But this is only what I have in mind, and I think we can ellaborate a 
>> bit more, possibly discarding my crazy ideas :)
>
> The getNext() approach is promising. At least in Tomcat they moved 
> their internal Valve architecture to exactly use that approach. 
> GlassFish forked Tomcat and the approach used is 
> preExecute/postExecute. There is pro and con for both 
> (preExecute/postExecute was faster when we measured long time ago) but 
> I would think for user is it simple using the getNext() (strange I say 
> that as I've implemented the pre/post :-)). I think it is simpler.
We have such code :

    public void messageReceived(IoSession session, Object message) {
        if (!(message instanceof IoBuffer)) {
            getNextFilter().messageReceived(session, message);
            return;
        }

        IoBuffer in = (IoBuffer) message;
        ProtocolDecoder decoder = getDecoder(session);
       
        if ( decoder == null) {
            ProtocolDecoderException pde = new ProtocolDecoderException(
                "Cannot decode if the decoder is null. Add the filter in 
the chain" +
                "before the first session is created" );
            getNextFilter().exceptionCaught(session, pde);
            return;
        }
       
        ProtocolDecoderOutput decoderOut = getDecoderOut(session, 
getNextFilter());
       
        if ( decoderOut == null) {
            ProtocolDecoderException pde = new ProtocolDecoderException(
                "Cannot decode if the decoder is null. Add the filter in 
the chain" +
                "before the first session is created" );
            getNextFilter().exceptionCaught(session, pde);
            return;
        }
       
        while (in.hasRemaining()) {
            int oldPos = in.position();
            try {
                synchronized (decoderOut) {
                    decoder.decode(session, in, decoderOut);
                }

                decoderOut.flush();
            } catch (Throwable t) {
                ...
            }
        }
    }

As you can see, (it's in the ProtocolCodecFilter) we have more than one 
place where we call the next filter, for different messages. 
Implementing such a behavior with pre(), callNext(), post() method would 
be quite a PITA to implement... (forget about this code, it's not 
necessarily a perfect exemple of good code, but it demonstracte what I mean)


Thanks !

-- 
--
cordialement, regards,
Emmanuel L├ęcharny
www.iktek.com
directory.apache.org



Mime
View raw message