[ 
https://issues.apache.org/jira/browse/DIRMINA-966?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Emmanuel Lecharny updated DIRMINA-966:
--------------------------------------
    Description: 
AbstractPollingConnectionlessIoAcceptor.write method...

within the "for ( ;; )" loop if the channel write fails to send, indicated by 0 
being returned, the message is re-enqueued.  However the loop is not exited and 
the same message is tried again.  For each failure to send the same message 
over and over a new WriteRequest is added to the queue and the message will be 
sent again for each WriteRequest.

Even though the WriteRequest references the same IoBuffer, after each 
successful write the IoBuffer is reset which enables each subsequent 
WriteRequest in the queue to send it again.

I have had instances where the kernel buffer is full and delays for up to 500ms 
or so which resulted in ~ 300 duplicate messages being sent.

Here is the block of code in question within the for ( ;; ) loop:

{code}
int localWrittenBytes = send( session, buf, destination );

if ( ( localWrittenBytes == 0 ) || ( writtenBytes >= maxWrittenBytes ) )
{
   // Kernel buffer is full or wrote too much
   setInterestedInWrite( session, true );

   session.getWriteRequestQueue().offer( session, writeRequest );
   scheduleFlush( session );
}
else
{
   setInterestedInWrite( session, false );

   // Clear and fire event
   session.setCurrentWriteRequest( null );
   writtenBytes += localWrittenBytes;
   buf.reset();
   session.getFilterChain().fireMessageSent( writeRequest );

   break;
}
{code}

Possible fixes:

 * adding a "break;" after the message has been re-queued would certainly 
resolve this but then messages could be delivered out of order.
 * don't re-queue the message and just loop back through trying to send it 
again.

Workaround:

 * ensure that the SO_SNDBUF size is sufficiently large which could, depending 
on the application, alleviate the issue altogether or make it less likely to 
occur.


  was:
AbstractPollingConnectionlessIoAcceptor.write method...

within the "for ( ;; )" loop if the channel write fails to send, indicated by 0 
being returned, the message is re-enqueued.  However the loop is not exited and 
the same message is tried again.  For each failure to send the same message 
over and over a new WriteRequest is added to the queue and the message will be 
sent again for each WriteRequest.

Even though the WriteRequest references the same IoBuffer, after each 
successful write the IoBuffer is reset which enables each subsequent 
WriteRequest in the queue to send it again.

I have had instances where the kernel buffer is full and delays for up to 500ms 
or so which resulted in ~ 300 duplicate messages being sent.

Here is the block of code in question within the for ( ;; ) loop:

int localWrittenBytes = send( session, buf, destination );

if ( ( localWrittenBytes == 0 ) || ( writtenBytes >= maxWrittenBytes ) )
{
   // Kernel buffer is full or wrote too much
   setInterestedInWrite( session, true );

   session.getWriteRequestQueue().offer( session, writeRequest );
   scheduleFlush( session );
}
else
{
   setInterestedInWrite( session, false );

   // Clear and fire event
   session.setCurrentWriteRequest( null );
   writtenBytes += localWrittenBytes;
   buf.reset();
   session.getFilterChain().fireMessageSent( writeRequest );

   break;
}

Possible fixes:

 * adding a "break;" after the message has been re-queued would certainly 
resolve this but then messages could be delivered out of order.
 * don't re-queue the message and just loop back through trying to send it 
again.

Workaround:

 * ensure that the SO_SNDBUF size is sufficiently large which could, depending 
on the application, alleviate the issue altogether or make it less likely to 
occur.



> NIO Datagram messages can get duplicated when unable to be sent by the 
> underlying DatagramChannel
> -------------------------------------------------------------------------------------------------
>
>                 Key: DIRMINA-966
>                 URL: https://issues.apache.org/jira/browse/DIRMINA-966
>             Project: MINA
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 2.0.7
>            Reporter: Michael McKnight
>
> AbstractPollingConnectionlessIoAcceptor.write method...
> within the "for ( ;; )" loop if the channel write fails to send, indicated by 
> 0 being returned, the message is re-enqueued.  However the loop is not exited 
> and the same message is tried again.  For each failure to send the same 
> message over and over a new WriteRequest is added to the queue and the 
> message will be sent again for each WriteRequest.
> Even though the WriteRequest references the same IoBuffer, after each 
> successful write the IoBuffer is reset which enables each subsequent 
> WriteRequest in the queue to send it again.
> I have had instances where the kernel buffer is full and delays for up to 
> 500ms or so which resulted in ~ 300 duplicate messages being sent.
> Here is the block of code in question within the for ( ;; ) loop:
> {code}
> int localWrittenBytes = send( session, buf, destination );
> if ( ( localWrittenBytes == 0 ) || ( writtenBytes >= maxWrittenBytes ) )
> {
>    // Kernel buffer is full or wrote too much
>    setInterestedInWrite( session, true );
>    session.getWriteRequestQueue().offer( session, writeRequest );
>    scheduleFlush( session );
> }
> else
> {
>    setInterestedInWrite( session, false );
>    // Clear and fire event
>    session.setCurrentWriteRequest( null );
>    writtenBytes += localWrittenBytes;
>    buf.reset();
>    session.getFilterChain().fireMessageSent( writeRequest );
>    break;
> }
> {code}
> Possible fixes:
>  * adding a "break;" after the message has been re-queued would certainly 
> resolve this but then messages could be delivered out of order.
>  * don't re-queue the message and just loop back through trying to send it 
> again.
> Workaround:
>  * ensure that the SO_SNDBUF size is sufficiently large which could, 
> depending on the application, alleviate the issue altogether or make it less 
> likely to occur.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to