You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Emmanuel Lecharny <el...@gmail.com> on 2008/11/11 01:11:13 UTC

[MessageSent] let's remove it...

Hi guys,

a few days ago, Julien suggested that we should remove this event. I 
never used it, found it a bit cumbersome, but didn't had time to double 
check what's doing.

Let's go back to the mailing list...

Back in july, I posted a mail where I questionned some code :

ProtocolCodecFilter.filterWrite() {
>    ...
>        ProtocolEncoder encoder = getEncoder(session);
>        ProtocolEncoderOutputImpl encoderOut = getEncoderOut(session,
>                nextFilter, writeRequest);
> 
>        try {
>            encoder.encode(session, message, encoderOut);
> 
>            // Here, the encoded message is sent.
>            encoderOut.flush();
> 
>            // Here an empty message is sent...
>            nextFilter.filterWrite(session, new WriteRequest(
>                    new MessageByteBuffer(writeRequest.getMessage()),
>                    writeRequest.getFuture(),
> writeRequest.getDestination()));

There are two places in this code where the message is written : in the encoderOut.flush()  and in the filterWrote() call.

Trustin replied saying :

"The two code blocks above are effectively same. The reason we call 
filterWrite once more with an empty buffer (MessageByteBuffer or 
MessageWriteRequest) is to generate a proper messageSent event which 
corresponds to the written message. Let me know if there's more 
efficient way to take care of messageSent events."

There is an obvious way to be more efficient here : simply not sending 
this messageSent event !


But this is not a good enough reason to remove it. Let's dig another mail.

https://issues.apache.org/jira/browse/DIRMINA-574

Steps to reproduce:
1) Connection is closed at the socket level.
2) A user writes a message.
3) the message is encoded by a ProtocolCodecFilter.
4) MINA notices the closed socket and fires a sessionClosed event.
5) After the sessionClosed event is fired, IoFilterChain.clear() is called.
6) MINA tries to write the user write request, but the session is closed already - all write requests are discarded.
7) Before MINA discards all write requests, MINA checks if the first item in the queue is an empty buffer, which means a special separator which is handled by ProtocolCodecFilter.
8) If there's an empty buffer in the head of the queue, MINA fires a messageSent event with the empty buffer in the hope that ProtocolCodecFilter will catch it.
9) However, the filter chain is empty and therefore IoHandler implementation gets ClassCastException.


At step 8, we send a MessageSent event, which leads to an Exception. Clearly, this is not good. Removing the MessageSent event will immediatly solve this blocker issue.

Last, not least, another mail states that :

"Also, I'd like to make a plug for removing messageSent() callbacks and having the end-user API rely on WriteFutures instead. It's a hassle to
write new filters when you have to worry about passing back the correct object."

Using WriteFuture will clearly be a better way to get the message as it has been posted to the chain, instead to having to encode it back, as it's currently done.

Anyone disagree ? Anything I missed ?

Thanks !

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



Re: Re : [MessageSent] let's remove it...

Posted by Maarten Bosteels <mb...@gmail.com>.
+1

On Tue, Nov 11, 2008 at 11:59 AM, Edouard De Oliveira
<do...@yahoo.fr>wrote:

> lol
> Emm did you pay Rajeshwari just to support your proposal ? DIRMINA-634
> should also be resolved by removing messageSent event
> which seems to be an unnecessary event that makes code even more cloudy.
>
> so +1
>
>  Cordialement, Regards,
> -Edouard De Oliveira-
> http://tedorg.free.fr/en/main.php
>
>
>
>
> ________________________________
> De : Mark Webb <el...@gmail.com>
> À : dev@mina.apache.org
> Envoyé le : Mardi, 11 Novembre 2008, 4h18mn 53s
> Objet : Re: [MessageSent] let's remove it...
>
> spot on.  +1.  remove it.
>
>
>
> On Mon, Nov 10, 2008 at 7:11 PM, Emmanuel Lecharny <el...@gmail.com>
> wrote:
> > Hi guys,
> >
> > a few days ago, Julien suggested that we should remove this event. I
> never
> > used it, found it a bit cumbersome, but didn't had time to double check
> > what's doing.
> >
> > Let's go back to the mailing list...
> >
> > Back in july, I posted a mail where I questionned some code :
> >
> > ProtocolCodecFilter.filterWrite() {
> >>
> >>   ...
> >>       ProtocolEncoder encoder = getEncoder(session);
> >>       ProtocolEncoderOutputImpl encoderOut = getEncoderOut(session,
> >>               nextFilter, writeRequest);
> >>
> >>       try {
> >>           encoder.encode(session, message, encoderOut);
> >>
> >>           // Here, the encoded message is sent.
> >>           encoderOut.flush();
> >>
> >>           // Here an empty message is sent...
> >>           nextFilter.filterWrite(session, new WriteRequest(
> >>                   new MessageByteBuffer(writeRequest.getMessage()),
> >>                   writeRequest.getFuture(),
> >> writeRequest.getDestination()));
> >
> > There are two places in this code where the message is written : in the
> > encoderOut.flush()  and in the filterWrote() call.
> >
> > Trustin replied saying :
> >
> > "The two code blocks above are effectively same. The reason we call
> > filterWrite once more with an empty buffer (MessageByteBuffer or
> > MessageWriteRequest) is to generate a proper messageSent event which
> > corresponds to the written message. Let me know if there's more efficient
> > way to take care of messageSent events."
> >
> > There is an obvious way to be more efficient here : simply not sending
> this
> > messageSent event !
> >
> >
> > But this is not a good enough reason to remove it. Let's dig another
> mail.
> >
> > https://issues.apache.org/jira/browse/DIRMINA-574
> >
> > Steps to reproduce:
> > 1) Connection is closed at the socket level.
> > 2) A user writes a message.
> > 3) the message is encoded by a ProtocolCodecFilter.
> > 4) MINA notices the closed socket and fires a sessionClosed event.
> > 5) After the sessionClosed event is fired, IoFilterChain.clear() is
> called.
> > 6) MINA tries to write the user write request, but the session is closed
> > already - all write requests are discarded.
> > 7) Before MINA discards all write requests, MINA checks if the first item
> in
> > the queue is an empty buffer, which means a special separator which is
> > handled by ProtocolCodecFilter.
> > 8) If there's an empty buffer in the head of the queue, MINA fires a
> > messageSent event with the empty buffer in the hope that
> ProtocolCodecFilter
> > will catch it.
> > 9) However, the filter chain is empty and therefore IoHandler
> implementation
> > gets ClassCastException.
> >
> >
> > At step 8, we send a MessageSent event, which leads to an Exception.
> > Clearly, this is not good. Removing the MessageSent event will immediatly
> > solve this blocker issue.
> >
> > Last, not least, another mail states that :
> >
> > "Also, I'd like to make a plug for removing messageSent() callbacks and
> > having the end-user API rely on WriteFutures instead. It's a hassle to
> > write new filters when you have to worry about passing back the correct
> > object."
> >
> > Using WriteFuture will clearly be a better way to get the message as it
> has
> > been posted to the chain, instead to having to encode it back, as it's
> > currently done.
> >
> > Anyone disagree ? Anything I missed ?
> >
> > Thanks !
> >
> > --
> > --
> > cordialement, regards,
> > Emmanuel Lécharny
> > www.iktek.com
> > directory.apache.org
> >
> >
> >
>
>
>
>
>

Re : [MessageSent] let's remove it...

Posted by Edouard De Oliveira <do...@yahoo.fr>.
lol
Emm did you pay Rajeshwari just to support your proposal ? DIRMINA-634 should also be resolved by removing messageSent event
which seems to be an unnecessary event that makes code even more cloudy.

so +1

 Cordialement, Regards,
-Edouard De Oliveira-
http://tedorg.free.fr/en/main.php




________________________________
De : Mark Webb <el...@gmail.com>
À : dev@mina.apache.org
Envoyé le : Mardi, 11 Novembre 2008, 4h18mn 53s
Objet : Re: [MessageSent] let's remove it...

spot on.  +1.  remove it.



On Mon, Nov 10, 2008 at 7:11 PM, Emmanuel Lecharny <el...@gmail.com> wrote:
> Hi guys,
>
> a few days ago, Julien suggested that we should remove this event. I never
> used it, found it a bit cumbersome, but didn't had time to double check
> what's doing.
>
> Let's go back to the mailing list...
>
> Back in july, I posted a mail where I questionned some code :
>
> ProtocolCodecFilter.filterWrite() {
>>
>>   ...
>>       ProtocolEncoder encoder = getEncoder(session);
>>       ProtocolEncoderOutputImpl encoderOut = getEncoderOut(session,
>>               nextFilter, writeRequest);
>>
>>       try {
>>           encoder.encode(session, message, encoderOut);
>>
>>           // Here, the encoded message is sent.
>>           encoderOut.flush();
>>
>>           // Here an empty message is sent...
>>           nextFilter.filterWrite(session, new WriteRequest(
>>                   new MessageByteBuffer(writeRequest.getMessage()),
>>                   writeRequest.getFuture(),
>> writeRequest.getDestination()));
>
> There are two places in this code where the message is written : in the
> encoderOut.flush()  and in the filterWrote() call.
>
> Trustin replied saying :
>
> "The two code blocks above are effectively same. The reason we call
> filterWrite once more with an empty buffer (MessageByteBuffer or
> MessageWriteRequest) is to generate a proper messageSent event which
> corresponds to the written message. Let me know if there's more efficient
> way to take care of messageSent events."
>
> There is an obvious way to be more efficient here : simply not sending this
> messageSent event !
>
>
> But this is not a good enough reason to remove it. Let's dig another mail.
>
> https://issues.apache.org/jira/browse/DIRMINA-574
>
> Steps to reproduce:
> 1) Connection is closed at the socket level.
> 2) A user writes a message.
> 3) the message is encoded by a ProtocolCodecFilter.
> 4) MINA notices the closed socket and fires a sessionClosed event.
> 5) After the sessionClosed event is fired, IoFilterChain.clear() is called.
> 6) MINA tries to write the user write request, but the session is closed
> already - all write requests are discarded.
> 7) Before MINA discards all write requests, MINA checks if the first item in
> the queue is an empty buffer, which means a special separator which is
> handled by ProtocolCodecFilter.
> 8) If there's an empty buffer in the head of the queue, MINA fires a
> messageSent event with the empty buffer in the hope that ProtocolCodecFilter
> will catch it.
> 9) However, the filter chain is empty and therefore IoHandler implementation
> gets ClassCastException.
>
>
> At step 8, we send a MessageSent event, which leads to an Exception.
> Clearly, this is not good. Removing the MessageSent event will immediatly
> solve this blocker issue.
>
> Last, not least, another mail states that :
>
> "Also, I'd like to make a plug for removing messageSent() callbacks and
> having the end-user API rely on WriteFutures instead. It's a hassle to
> write new filters when you have to worry about passing back the correct
> object."
>
> Using WriteFuture will clearly be a better way to get the message as it has
> been posted to the chain, instead to having to encode it back, as it's
> currently done.
>
> Anyone disagree ? Anything I missed ?
>
> Thanks !
>
> --
> --
> cordialement, regards,
> Emmanuel Lécharny
> www.iktek.com
> directory.apache.org
>
>
>



      

Re: [MessageSent] let's remove it...

Posted by Mark Webb <el...@gmail.com>.
spot on.  +1.  remove it.



On Mon, Nov 10, 2008 at 7:11 PM, Emmanuel Lecharny <el...@gmail.com> wrote:
> Hi guys,
>
> a few days ago, Julien suggested that we should remove this event. I never
> used it, found it a bit cumbersome, but didn't had time to double check
> what's doing.
>
> Let's go back to the mailing list...
>
> Back in july, I posted a mail where I questionned some code :
>
> ProtocolCodecFilter.filterWrite() {
>>
>>   ...
>>       ProtocolEncoder encoder = getEncoder(session);
>>       ProtocolEncoderOutputImpl encoderOut = getEncoderOut(session,
>>               nextFilter, writeRequest);
>>
>>       try {
>>           encoder.encode(session, message, encoderOut);
>>
>>           // Here, the encoded message is sent.
>>           encoderOut.flush();
>>
>>           // Here an empty message is sent...
>>           nextFilter.filterWrite(session, new WriteRequest(
>>                   new MessageByteBuffer(writeRequest.getMessage()),
>>                   writeRequest.getFuture(),
>> writeRequest.getDestination()));
>
> There are two places in this code where the message is written : in the
> encoderOut.flush()  and in the filterWrote() call.
>
> Trustin replied saying :
>
> "The two code blocks above are effectively same. The reason we call
> filterWrite once more with an empty buffer (MessageByteBuffer or
> MessageWriteRequest) is to generate a proper messageSent event which
> corresponds to the written message. Let me know if there's more efficient
> way to take care of messageSent events."
>
> There is an obvious way to be more efficient here : simply not sending this
> messageSent event !
>
>
> But this is not a good enough reason to remove it. Let's dig another mail.
>
> https://issues.apache.org/jira/browse/DIRMINA-574
>
> Steps to reproduce:
> 1) Connection is closed at the socket level.
> 2) A user writes a message.
> 3) the message is encoded by a ProtocolCodecFilter.
> 4) MINA notices the closed socket and fires a sessionClosed event.
> 5) After the sessionClosed event is fired, IoFilterChain.clear() is called.
> 6) MINA tries to write the user write request, but the session is closed
> already - all write requests are discarded.
> 7) Before MINA discards all write requests, MINA checks if the first item in
> the queue is an empty buffer, which means a special separator which is
> handled by ProtocolCodecFilter.
> 8) If there's an empty buffer in the head of the queue, MINA fires a
> messageSent event with the empty buffer in the hope that ProtocolCodecFilter
> will catch it.
> 9) However, the filter chain is empty and therefore IoHandler implementation
> gets ClassCastException.
>
>
> At step 8, we send a MessageSent event, which leads to an Exception.
> Clearly, this is not good. Removing the MessageSent event will immediatly
> solve this blocker issue.
>
> Last, not least, another mail states that :
>
> "Also, I'd like to make a plug for removing messageSent() callbacks and
> having the end-user API rely on WriteFutures instead. It's a hassle to
> write new filters when you have to worry about passing back the correct
> object."
>
> Using WriteFuture will clearly be a better way to get the message as it has
> been posted to the chain, instead to having to encode it back, as it's
> currently done.
>
> Anyone disagree ? Anything I missed ?
>
> Thanks !
>
> --
> --
> cordialement, regards,
> Emmanuel Lécharny
> www.iktek.com
> directory.apache.org
>
>
>

Re: AW: [MessageSent] let's remove it... no---signature

Posted by Emmanuel Lecharny <el...@gmail.com>.
Steve Ulrich wrote:
> Hi!
>
> AFAIK, the messageSent is the only way to react when a message is finally
> sent. 
Yes, but because no alternate solution was discussed. And even if it was 
the only solution, it's a pretty atrocious one : having to go through 
the chain a second time just to get some stats sounds silly to me. So 
let's try to find a better way. And the fact that this is closely linked 
to a filter is even worse (what if you don't use a ProtocolCodecFilter ?).
> filterWrite is already called *before* the message is passed to the
> cable.
>   
> How can I implement timings, like request/response timeout filters?
> Using filterWrite for this could be problematic for decoding will consume
> some undefined/-able amount of the time(out).
>   
> If there's another way to do this, let me know.
>   
So let's think a second time about the way the protocolCodecFilter 
works, when a message is to b sent back to the client. It receives a 
Message, encode it, and write it to the cient. If you look at the 
current implementation :

        public void flushWithoutFuture(int index) throws Exception {
            Queue<Object> bufferQueue = getMessageQueue();
            for (;;) {
                Object encodedMessage = bufferQueue.poll();
                if (encodedMessage == null) {
                    break;
                }

                // Flush only when the buffer has remaining.
                if (!(encodedMessage instanceof IoBuffer) ||
                        ((IoBuffer) encodedMessage).hasRemaining()) {
                    SocketAddress destination = 
writeRequest.getDestination();
                    WriteRequest writeRequest = new EncodedWriteRequest(
                        encodedMessage, null, destination);
                    IoFilter nextFilter = session.getFilterOut(index+1);
                    nextFilter.filterWrite(index+1, session, writeRequest);
                }
            }
        }

you can see that we loop on the message Queue, flushing every message 
one by one. Three things :
- first, if we have more than one message one the queue, I don't see how 
we can generate this MessageSent message.
- second, as the encoder will generate a full IoBuffer for each separate 
message, I don't see how it's necessary to send it again.
- third, this is not because we have generated an empty message and 
faked to send it that the message has been sent. It's just a damn hack 
to pretend the message has been sent.

Now, it's all about semantic : when do we want to *know* that a message 
has been sent ? When the client has sent an ack ? There is no way to 
enforce this.

What about considering that the message is sent as soon as we have 
written in the chjain, associated with a writeFuture marked as 'done' ? 
The problem is that the codec just send the data without creating a future.

At some point, we will need to get a feedback from the low level layers 
telling us that the message (being a IoBuffer at this point) has been 
successfully sent : a WriteFutuer in a 'completed' state should do the 
trick. A filter checking able to check this write future when it's set 
to 'don' should do the trick.

This is not simple : if we consider that we send data on a non-blocking 
IO, we have to assume that the message has been sent even if the socket 
is full, and we may perfectly write in a socket which will be close 
before the full message has been sent. Let's say that it's a best effort 
approach. 

Anyway, I think it's feasible with a WriteFuture.

As usual, I may be wrong. May be I'm totally off rail, just tell me then :)

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



AW: [MessageSent] let's remove it... no---signature

Posted by Steve Ulrich <st...@proemion.com>.
Hi!

AFAIK, the messageSent is the only way to react when a message is finally
sent. filterWrite is already called *before* the message is passed to the
cable.
How can I implement timings, like request/response timeout filters?
Using filterWrite for this could be problematic for decoding will consume
some undefined/-able amount of the time(out).
If there's another way to do this, let me know.

regards

Steve

> Emmanuel Lecharny [mailto:elecharny@gmail.com] wrote:
>
> Hi guys,
>
> a few days ago, Julien suggested that we should remove this event. I
> never used it, found it a bit cumbersome, but didn't had time to double
> check what's doing.
>
> Let's go back to the mailing list...
>
> Back in july, I posted a mail where I questionned some code :
>
> ProtocolCodecFilter.filterWrite() {
> >    ...
> >        ProtocolEncoder encoder = getEncoder(session);
> >        ProtocolEncoderOutputImpl encoderOut = getEncoderOut(session,
> >                nextFilter, writeRequest);
> >
> >        try {
> >            encoder.encode(session, message, encoderOut);
> >
> >            // Here, the encoded message is sent.
> >            encoderOut.flush();
> >
> >            // Here an empty message is sent...
> >            nextFilter.filterWrite(session, new WriteRequest(
> >                    new MessageByteBuffer(writeRequest.getMessage()),
> >                    writeRequest.getFuture(),
> > writeRequest.getDestination()));
>
> There are two places in this code where the message is written : in the
> encoderOut.flush()  and in the filterWrote() call.
>
> Trustin replied saying :
>
> "The two code blocks above are effectively same. The reason we call
> filterWrite once more with an empty buffer (MessageByteBuffer or
> MessageWriteRequest) is to generate a proper messageSent event which
> corresponds to the written message. Let me know if there's more
> efficient way to take care of messageSent events."
>
> There is an obvious way to be more efficient here : simply not sending
> this messageSent event !
>
>
> But this is not a good enough reason to remove it. Let's dig another
> mail.
>
> https://issues.apache.org/jira/browse/DIRMINA-574
>
> Steps to reproduce:
> 1) Connection is closed at the socket level.
> 2) A user writes a message.
> 3) the message is encoded by a ProtocolCodecFilter.
> 4) MINA notices the closed socket and fires a sessionClosed event.
> 5) After the sessionClosed event is fired, IoFilterChain.clear() is
> called.
> 6) MINA tries to write the user write request, but the session is
> closed already - all write requests are discarded.
> 7) Before MINA discards all write requests, MINA checks if the first
> item in the queue is an empty buffer, which means a special separator
> which is handled by ProtocolCodecFilter.
> 8) If there's an empty buffer in the head of the queue, MINA fires a
> messageSent event with the empty buffer in the hope that
> ProtocolCodecFilter will catch it.
> 9) However, the filter chain is empty and therefore IoHandler
> implementation gets ClassCastException.
>
>
> At step 8, we send a MessageSent event, which leads to an Exception.
> Clearly, this is not good. Removing the MessageSent event will
> immediatly solve this blocker issue.
>
> Last, not least, another mail states that :
>
> "Also, I'd like to make a plug for removing messageSent() callbacks and
> having the end-user API rely on WriteFutures instead. It's a hassle to
> write new filters when you have to worry about passing back the correct
> object."
>
> Using WriteFuture will clearly be a better way to get the message as it
> has been posted to the chain, instead to having to encode it back, as
> it's currently done.
>
> Anyone disagree ? Anything I missed ?
>
> Thanks !
>
> --
> --
> cordialement, regards,
> Emmanuel Lécharny
> www.iktek.com
> directory.apache.org
>