Hi Rémi,

give me a bit of time to review the code and come back to you with a clear answer.

Thanks!

On 07/02/2025 18:23, MARQUERIE Rémi wrote:
Hello,

Thanks for the response. I did more digging and now I just want to talk about 
my first issue as the second seems independent and a pain to reproduce.
So, my problem is that I have the AbstractIoSession.scheduledWriteMessages 
increase 3 times but decreased only once.
More detailed context:
  - I have a particular message send by the server called NotifyDeliver which 
is encode in 3 parts (see code of encodeOptimisedNotifyDeliver after)
  - In ProtocolCodecFilter.filterWrite the NotifyDeliver is encoded in 3 parts, 
and then in the while loop, each part are sent to the next filter. I noted that 
the 2 first parts are enclosed in the private class EncodedWriteRequest which 
only Override isEncoded so it returns true.
  - Each of the 3 message parts end up in HeadFilter.filterWrite where 
scheduledWriteMessages is increased each time. That is also where I noticed 
that prior to 2.1.1, scheduledWriteMessages was increased only
         - if (!writeRequest.isEncoded())
  - Here the 3 parts are also added a queue, and as M. Lécharny explained, the 
IoProcessor fires MessageSent events
  - The 3 corresponding event are fired as I saw 3 calls of 
DefaultIoFilterChain.fireMessageSent but here there is this code :
         if (!request.isEncoded()) {
             callNextMessageSent(head, session, request);
         }
  - Because the two first writeRequest are actually 2 EncodedWriteRequest, 
callNextMessageSent is done only on the 3rd part.
  - So, TailFilter.messageSent is only called once, and decreases 
scheduledWriteMessages (through ((AbstractIoSession) 
session).increaseWrittenMessages(writeRequest, now); ) only once.

I was able to make it work so scheduledWriteMessages is decreased 3 times by 
removing the if (!request.isEncoded())  condition in 
DefaultIoFilterChain.fireMessageSent and also removing this code from 
ProtocolCodecFilter.messageSent which was also blocking the chain to TailFilter:
         if (writeRequest instanceof EncodedWriteRequest) {
             return;
         }

I precise that my NotifyDeliver message is well received by my client (all data 
is checked and correct). The only problem is scheduledWriteMessages being 
incorrect and, as I said in my previous email, I was using it for another 
message checking the connection.

I hope I gave enough info to determine if I'm doing something bad or if it is a 
bug in Mina.

RM

The code encoding NotifyDeliver message :

   private static void encodeOptimisedNotifyDeliver (ProtocolEncoderOutput out,
                                                     NotifyDeliver 
notifyDeliver)
   {
     IoBuffer headerBuffer = IoBuffer.allocate (20);
     IoBuffer matchesBuffer = IoBuffer.allocate (256);
     IoBuffer attributesBuffer =
       notifyDeliver.original.rawAttributes.asReadOnlyBuffer ();
matchesBuffer.setAutoExpand (true); putLongArray (matchesBuffer, notifyDeliver.secureMatches);
     putLongArray (matchesBuffer, notifyDeliver.insecureMatches);
matchesBuffer.flip (); int frameSize = 4 + attributesBuffer.limit () + matchesBuffer.limit (); notifyDeliver.frameSize = frameSize; headerBuffer.putInt (frameSize);
     headerBuffer.putInt (NotifyDeliver.ID);
headerBuffer.flip ();

     out.write (headerBuffer);
     out.write (attributesBuffer);
     out.write (matchesBuffer);
   }

-----Message d'origine-----
De : Emmanuel Lécharny <elecha...@gmail.com>
Envoyé : jeudi 6 février 2025 17:04
À : users@mina.apache.org
Objet : Re: Problem with AbstractIoSession.scheduledWriteMessages [mina 2.1.X]

Hi,

you definitively should jump to 2.2.4 instead of transiting by 2.1.x. In any 
case, would you decide to use 2.X branch, use 2.1.10.

That being said,



On 06/02/2025 14:57, MARQUERIE Rémi wrote:
Hello,

First, I want to say that I’m not sure it’s a problem in Mina or the way we use 
it in our project.

Context and mina version:
I’m currently trying to upgrade the mina version used in my project from mina 
2.0.7 to 2.1.X (first trying to 2.1.7 then maybe to 2.1.10).

The problem :
The class AbstractIoSession has a member scheduledWriteMessages. It is 
increased when HeadFilter.filterWrite is called (file 
DefaultIoFilterChain.java) ; then it is decreased when the message is sent.

Actually, it's decreased when the message *has* been sent. Just to clarify, 
because the message goes through the chain back to the IoProcessor, and is 
stored in a queue. When the IoProcssor can send the message fully, it generates 
a MessageSent event, which is processed back by the  chain, where the counter 
can now be decremented.


In my problematic case, I use a ProtocolCodecFilter and for some message, when 
the filterWrite method is called, it goes into this while loop :

// Code in ProtocolCodecFilter.java
              // Write all the encoded messages now
              while (!bufferQueue.isEmpty()) {
                  Object encodedMessage = bufferQueue.poll();

                  if (encodedMessage == null) {
                      break;
                  }

                  // Flush only when the buffer has remaining.
                  if (!(encodedMessage instanceof IoBuffer) || ((IoBuffer) 
encodedMessage).hasRemaining()) {
                      if (bufferQueue.isEmpty()) {
                          writeRequest.setMessage(encodedMessage);
                          nextFilter.filterWrite(session, writeRequest);
                      } else {
                          SocketAddress destination = 
writeRequest.getDestination();
                          WriteRequest encodedWriteRequest = new 
EncodedWriteRequest(encodedMessage, null, destination);
                          nextFilter.filterWrite(session, encodedWriteRequest);
                      }
                  }
              }
// Fin Code in ProtocolCodecFilter.java

Which is find, it will just generate as many message to be written as there are 
enqueued message in the buffer.


Here we see 2 calls of nextFilter.filterWrite. In my case, the loop is done 3 
times so nextFilter.filterWrite is called 2 times with a new 
EncodedWriteRequest and once (the last) by passing the processed WriteRequest. 
Those 3 calls end up to HeadFilter.filterWrite and so scheduledWriteMessages is 
then equal to 3. When the message is sent, scheduledWriteMessages is decreased 
only once so now scheduledWriteMessages is 2.

It can't be. The counter is incremented in the HeadFilter every time a 
writeFilter call is made. Each message is contained in its own WriteRequest, 
and this is what matters.



I’ve noticed the problem appeared in 2.1.1 with this commit : “2d08d53 - Pushed 
my current changes related to the filterWrite refactoring”
diff --git
a/mina-core/src/main/java/org/apache/mina/core/filterchain/DefaultIoFi
lterChain.java
b/mina-core/src/main/java/org/apache/mina/core/filterchain/DefaultIoFi
lterChain.java
---
a/mina-core/src/main/java/org/apache/mina/core/filterchain/DefaultIoFi
lterChain.java
+++ b/mina-core/src/main/java/org/apache/mina/core/filterchain/Default
+++ IoFilterChain.java
@@ -907,4 +906,2 @@
-            if (!writeRequest.isEncoded()) {
-                s.increaseScheduledWriteMessages();
-            }
+            s.increaseScheduledWriteMessages();

So before this commit, increaseScheduledWriteMessages was called only once as 
the 2 first time the writeRequest isEncoded.

This scheduledWriteMessages is not used in mina (src or test), but in my 
project, we used it to check connection problems. As a temporary fix, I just 
removed the use of scheduledWriteMessages; and I thought a possible patch for 
mina would be to recheck the isEncoded like in 2.1.0.

BUT ! Then I tried using mina 2.1.10 and a new problem arise with the same 
message. So, a bit more of context:

    *   The client sends the problematic request message
    *   The server receives the request (triggering the 3 
scheduledWriteMessages increase)
    *   The it sends the associated response.
With mina 2.1.7, the client received one response and everything works after 
that, but not with mina 2.1.10 where for the next good request I receive a 
response for the previous problematic request and then the good response.

Seems like the problem is that 2 wrong messages never get send with MINA 2.1.7, 
AFAIU...

For clarity let’s call the problematic request and response PRqst and PResp , 
and let’s call anther Good Request/Response GRqst/GResp. From my client I see 
that :

    *   Send PRqst
    *   Receive PResp
    *   Wait some time // The problem appears wether I add this wait or not
    *   Send GRqst
    *   Receive PResp
    *   Receive GResp

So, because of this problem, I don’t know if it is a problem in Mina or how I 
use it. I searched the commits between 2.1.7 and 2.1.10 for clues, but could 
not find anything.
If someone could give me some more info, that would be great 😊


I may miss some points, because there are some missing context, but
basically:

- for every message that goes to the write chain and get queued to be sent back 
to the client, the writeMessage counter isincremented
- for every message unqueued from the pending message and physically sent to 
the client (ie for which the IoProcessor *can* actually write all the bytes in 
the socket, regardless of the client receiving them), the messageSent even is 
propagated to the Handler through the chain
- When a messageSent is processed, then the scheduledWritesMessages counter is 
decremented

At least, this is how it is supposed to work.


Now, back to your need: you want to avoid sending a problematic response to the 
client when it send a proper request.

The thing is that the first problematic message has most certainly generated 
many problematic response, and they haven't been read by the client, so they 
are pending in the IoProcessor queue until the client is ready to read 
something. They will stay there simply because it's up to the client to read an 
discard them!

What I mean is that the server either determinate that the incoming message is 
wrong, and don't send back a message the client wont read, or you are pretty 
much stuck...


Thanks, and have a nice day.

RM

--
------------------------ Emmanuel Lécharny emm...@worteks.com 
elecha...@apache.org ------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@mina.apache.org For additional 
commands, e-mail: users-h...@mina.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@mina.apache.org
For additional commands, e-mail: users-h...@mina.apache.org


--
------------------------ Emmanuel Lécharny emm...@worteks.com
elecha...@apache.org ------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@mina.apache.org
For additional commands, e-mail: users-h...@mina.apache.org

Reply via email to