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
>