james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Samant Maharaj (JIRA)" <server-...@james.apache.org>
Subject [jira] [Commented] (JAMES-1436) APPEND IMAP command can result in JAMES IMAP waiting indefinitely for data
Date Tue, 27 Nov 2012 02:47:59 GMT

    [ https://issues.apache.org/jira/browse/JAMES-1436?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13504321#comment-13504321

Samant Maharaj commented on JAMES-1436:

Eric, I couldn't think of a way to write a test case that would reliably reproduce the issue.
As you note, it needs the producer / consumer relationship between the Netty socket IO thread
pools and the JAMES IMAP processor pool to have the correct bias to trigger the bug. 

I reproduced by manually debugging until I could isolate the issue. In the end I confirmed
that the exact number of bytes that the append decoder was waiting for was always the same
as that contained in the decoder that had been removed from the pipeline.

The introduction of SwitchableDelimiterBasedFrameDecoder was based on the realisation that
when the ImapRequestFrameDecoder removed the DelimiterBasedFrameDecoder there might still
be residual data in the cumulation buffer. It seemed that a safer approach would be to empty
the cumulation buffer and switch the decoder into a pass-through mode until the entire APPEND
completed decoding. This avoids the possibility of data in the pipeline being reordered if
we had tried the approach of removing the decoder from the pipeline but still flushing any
residual data.

I introduced the synchronization in order to prevent any new messages entering the decoder
from being processed if a disableFraming() was in progress. This was to prevent data reordering.
Some of the methods, notably createCumulationDynamicBuffer() don't require synchronization
and this can be removed.

In regards to performance, I agree that there is a potential problem here since the dispatch
to the rest of the pipeline from messageReceived() and disableFraming() will be done while
holding the monitor. Ideally this should be removed. I can look into a better construction
in order to avoid this issue.

Finally, I'm uncomfortable with the dependency on SwitchableDelimiterBasedFrameDecoder in
ImapRequestFrameDecoder as it feels like this breaks the encapsulation in the design of the
pipeline. Ideally another mechanism should be used that preserves the independence of the
elements in the pipeline. 

> APPEND IMAP command can result in JAMES IMAP waiting indefinitely for data
> --------------------------------------------------------------------------
>                 Key: JAMES-1436
>                 URL: https://issues.apache.org/jira/browse/JAMES-1436
>             Project: James Server
>          Issue Type: Bug
>          Components: IMAPServer
>    Affects Versions: Trunk, 3.0-beta4, 3.0-beta5
>         Environment: Ubuntu 12.04 x86_64
>            Reporter: Samant Maharaj
>         Attachments: JAMES-1436.patch
> When processing an IMAP APPEND command, the Netty stack in JAMES IMAP can get into a
state where the ImapRequestFrameDecoder will wait for a number message bytes that will never
> This has the effect of causing the IMAP client to also block indefinitely waiting for
a response from the server.
> Root Cause:
> This is due to a race condition when the DelimiterBasedFrameDecoder is removed from the
Netty pipeline by the ImapRequestFrameDecoder.
> If the DelimiterBasedFrameDecoder still contains less than one line of data in its buffer,
that data will never be flushed and forwarded down the pipeline. The effect of this is that
a small number of bytes, typically from the early part of the message are omitted and the
final byte count does not match the value calculated from the APPEND command. This results
in the APPEND command never being completely decoded and hence no append actually takes place
nor does a response get sent to the client.
> In order to reliably trigger this bug, JAMES was configured to accept a remote debugging
connection and a conditional breakpoint set at org.jboss.netty.handler.codec.frame.FrameDecoder:439.
The condition was set to 'Thread.sleep(200l); false'. This results in introducing a 200ms
delay on each frame decoding loop without actually hitting the breakpoint. The effect of this
is to allow the threadpool running ImapRequestFrameDecoder time to consume the individual
frames and remove the DelimiterBasedFrameDecoder from the pipeline.

This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org

View raw message