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


Reply via email to