You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Andrea Gariboldi <an...@gmail.com> on 2007/06/22 19:45:44 UTC

SocketAcceptor extensibility enhancement

Hi all,
    i started using MINA-sm to write an smtp server, mostly
to learn using it. i would like to extend SocketSessionImpl
to add protocol specific fields without using setAttribute,
that seems to me an underperforming method.

Lets take my SMTP implementation as an example, so if
i'am wrong you can insult me ;)

I have an SmtpCommandDecoder that extends TextLineDecoder,
and normally writes out some Class<? extends SmtpCommand> instance..
BUT, when the session is receiving message body, lets say between a DATA
command and a <CRLF>.<CRLF>, it writes out directly the message string,
so actually is something like:

public class SmtpCommandDecoder extends TextLineDecoder {
  .............

@Override
    public void decode(final IoSession session, ByteBuffer in,
            final ProtocolDecoderOutput out) throws Exception {

        super.decode(session, in, new ProtocolDecoderOutput() {
            public void write(Object message) {
                    if (session.containsAttribute(RECEIVING_DATA))   /*
<--------------LOOK HERE---------------------   */
                    {
                        if (endDataCommand.getName().equals(message))
                            out.write(endDataCommand);
                        else
                            out.write(message);
                    }
                    else
                    {
                        SmtpCommand cmd = parseCommand((String) message);
                        if (cmd != null)
                        {
                            if (cmd instanceof DataCommand)
                                session.setAttribute(RECEIVING_DATA, FLAG);

                            out.write(cmd);
                        }
                    }
            }

            private SmtpCommand parseCommand(String cmdLine) { ... }

  ...........



The highlighted instruction will be executed for each command for each
client session,
and actually wil search in a Map (BaseIoSession.attributes) the result. I
would like
to write something like:

1) solution one (not the best)

public void decode(final IoSession session, ByteBuffer in,
            final ProtocolDecoderOutput out) throws Exception {

if (((SmtpSession)session).isReceivingData())
....

2) solution two (great)

public void decode(final SmtpSession session, ByteBuffer in,
            final ProtocolDecoderOutput out) throws Exception {

if (session.isReceivingData())



I tried to implement solution 1 but:

1) The SocketAcceptor.newSession is not used:

    public IoSession newSession( SocketAddress remoteAddress )
    {
        throw new UnsupportedOperationException();
    }

   instead the processSessions method does somenthing like:

   SocketSessionImpl session = new SocketSessionImpl(...

2) SocketSessionImpl is not public

So my solution 1) patch proposal would be something like:

a) SocketAcceptor.newSession:

public IoSession newSession( SocketAddress remoteAddress )
    {
        throw new new SocketSessionImpl();
    }


b) SocketAcceptor.processSessions:

private void processSessions( Set<SelectionKey> keys ) throws IOException
        {
            .................
              SocketSession session = (SocketSession)newSession(null);
           ................
}

Solution 2, means use of generics, so no performance gains between solution
1)(casting) and 2)(generics)
but probably solution 2) means a lot of work.


now you can insult me. ;)

bye,
AAA

Re: SocketAcceptor extensibility enhancement

Posted by Maarten Bosteels <mb...@gmail.com>.
Hi Andrea,

What about storing one instance of SmtpSession as an attribute of IoSession
?
You could create and store the SmtpSession in IoHandler.sessionOpened

Your decoder would look like:

public void decode(final IoSession session, ByteBuffer in,
           final ProtocolDecoderOutput out) throws Exception {
   SmtpSession smtpSession = session.getAttribute("SMTP_SESSION");
   decode(smtpSession, in, out);
}

public void decode(final SmtpSession session, ByteBuffer in,
           final ProtocolDecoderOutput out) throws Exception {
if (session.isReceivingData()) {
...
}

Maarten

On 6/22/07, Andrea Gariboldi <an...@gmail.com> wrote:
>
> Hi all,
>     i started using MINA-sm to write an smtp server, mostly
> to learn using it. i would like to extend SocketSessionImpl
> to add protocol specific fields without using setAttribute,
> that seems to me an underperforming method.
>
> Lets take my SMTP implementation as an example, so if
> i'am wrong you can insult me ;)
>
> I have an SmtpCommandDecoder that extends TextLineDecoder,
> and normally writes out some Class<? extends SmtpCommand> instance..
> BUT, when the session is receiving message body, lets say between a DATA
> command and a <CRLF>.<CRLF>, it writes out directly the message string,
> so actually is something like:
>
> public class SmtpCommandDecoder extends TextLineDecoder {
>   .............
>
> @Override
>     public void decode(final IoSession session, ByteBuffer in,
>             final ProtocolDecoderOutput out) throws Exception {
>
>         super.decode(session, in, new ProtocolDecoderOutput() {
>             public void write(Object message) {
>                     if (session.containsAttribute(RECEIVING_DATA))   /*
> <--------------LOOK HERE---------------------   */
>                     {
>                         if (endDataCommand.getName().equals(message))
>                             out.write(endDataCommand);
>                         else
>                             out.write(message);
>                     }
>                     else
>                     {
>                         SmtpCommand cmd = parseCommand((String) message);
>                         if (cmd != null)
>                         {
>                             if (cmd instanceof DataCommand)
>                                 session.setAttribute(RECEIVING_DATA,
> FLAG);
>
>                             out.write(cmd);
>                         }
>                     }
>             }
>
>             private SmtpCommand parseCommand(String cmdLine) { ... }
>
>   ...........
>
>
>
> The highlighted instruction will be executed for each command for each
> client session,
> and actually wil search in a Map (BaseIoSession.attributes) the result. I
> would like
> to write something like:
>
> 1) solution one (not the best)
>
> public void decode(final IoSession session, ByteBuffer in,
>             final ProtocolDecoderOutput out) throws Exception {
>
> if (((SmtpSession)session).isReceivingData())
> ....
>
> 2) solution two (great)
>
> public void decode(final SmtpSession session, ByteBuffer in,
>             final ProtocolDecoderOutput out) throws Exception {
>
> if (session.isReceivingData())
>
>
>
> I tried to implement solution 1 but:
>
> 1) The SocketAcceptor.newSession is not used:
>
>     public IoSession newSession( SocketAddress remoteAddress )
>     {
>         throw new UnsupportedOperationException();
>     }
>
>    instead the processSessions method does somenthing like:
>
>    SocketSessionImpl session = new SocketSessionImpl(...
>
> 2) SocketSessionImpl is not public
>
> So my solution 1) patch proposal would be something like:
>
> a) SocketAcceptor.newSession:
>
> public IoSession newSession( SocketAddress remoteAddress )
>     {
>         throw new new SocketSessionImpl();
>     }
>
>
> b) SocketAcceptor.processSessions:
>
> private void processSessions( Set<SelectionKey> keys ) throws IOException
>         {
>             .................
>               SocketSession session = (SocketSession)newSession(null);
>            ................
> }
>
> Solution 2, means use of generics, so no performance gains between
> solution
> 1)(casting) and 2)(generics)
> but probably solution 2) means a lot of work.
>
>
> now you can insult me. ;)
>
> bye,
> AAA
>