qpid-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Rajith Attapattu (JIRA)" <j...@apache.org>
Subject [jira] [Issue Comment Edited] (QPID-3462) Failover is not transparent when using CLIENT_ACK mode
Date Fri, 16 Sep 2011 22:35:09 GMT

    [ https://issues.apache.org/jira/browse/QPID-3462?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13106874#comment-13106874
] 

Rajith Attapattu edited comment on QPID-3462 at 9/16/11 10:35 PM:
------------------------------------------------------------------

When considering Failover with respect to CLIENT_ACKNOWLEDGE we need to
consider the following 3 cases,

1. The last acknowledgement is in doubt after failover.

{code}
Message m = consumer.receive();
m.acknowledge();
// client fails over due to broker crash

Message m2 = consumer.receive();
m2.acknowledge();
{code}

2. Calling acknowledge() on a message received prior to failover.
{code}
Message m = consumer.receive();

// The application does some work while the JMS client fails over.

m.acknowledge();
{code}

3. Calling acknowledge on a message received after failover, but implicitly
acknowledging messages received prior to failover.
{code}
Message m = consumer.receive();
// client fails over due to broker crash

Message m2 = consumer.receive();
m2.acknowledge();
{code}

In the first case, 
If m.acknowlege() returns the JMS client lib needs to ensure that any messages
upto that point will not be replayed. So the acknowlege() method needs to be
synchronous (in 0-10 terms call sync()).

If it doesn't return before failover, then it means the application needs to be
ready to handle duplicates for all unacked messages.
The acknowledge method needs to throw an exception to signal the app that it
failed.
The JMS client + broker will redeliver all unacked messages in the same order.

In the second case, the client needs to throw a JMS exception. 
And the next time the application tries to receive a message it will be the one
after the oldest acked messages.

In the 3rd case, the JMS client lib needs to ensure, that "m" (the last message
before failover) is redelivered again.
i.e. 'm2' is the same as 'm'.

And when acknowledge is called on m2, the JMS client lib should throw a JMS
exception.

And the next time the application tries to receive a message it will be the one
after the oldest acked message.

Simply calling recover will not provide a sufficient solution to this problem.
Besides there are subtle issues with the current recover implementation within
a JCA contexnt.

Therefore we need to carefully consider all options before attempting a fix.
The changes required needs to be carefully tested and evaluated. 

I recommend we de-scope this JIRA from MRG 2.0.3 errata.

      was (Author: rajith):
    When considering Failover with respect to CLIENT_ACKNOWLEDGE we need to
consider the following 3 cases,

1. The last acknowledgement is in doubt after failover.

<code>
Message m = consumer.receive();
m.acknowledge();
// client fails over due to broker crash

Message m2 = consumer.receive();
m2.acknowledge();
</code>

2. Calling acknowledge() on a message received prior to failover.
<code>
Message m = consumer.receive();

// The application does some work while the JMS client fails over.

m.acknowledge();
</code>

3. Calling acknowledge on a message received after failover, but implicitly
acknowledging messages received prior to failover.
<code>
Message m = consumer.receive();
// client fails over due to broker crash

Message m2 = consumer.receive();
m2.acknowledge();
</code>

In the first case, 
If m.acknowlege() returns the JMS client lib needs to ensure that any messages
upto that point will not be replayed. So the acknowlege() method needs to be
synchronous (in 0-10 terms call sync()).

If it doesn't return before failover, then it means the application needs to be
ready to handle duplicates for all unacked messages.
The acknowledge method needs to throw an exception to signal the app that it
failed.
The JMS client + broker will redeliver all unacked messages in the same order.

In the second case, the client needs to throw a JMS exception. 
And the next time the application tries to receive a message it will be the one
after the oldest acked messages.

In the 3rd case, the JMS client lib needs to ensure, that "m" (the last message
before failover) is redelivered again.
i.e. 'm2' is the same as 'm'.

And when acknowledge is called on m2, the JMS client lib should throw a JMS
exception.

And the next time the application tries to receive a message it will be the one
after the oldest acked message.

Simply calling recover will not provide a sufficient solution to this problem.
Besides there are subtle issues with the current recover implementation within
a JCA contexnt.

Therefore we need to carefully consider all options before attempting a fix.
The changes required needs to be carefully tested and evaluated. 

I recommend we de-scope this JIRA from MRG 2.0.3 errata.
  
> Failover is not transparent when using CLIENT_ACK mode
> ------------------------------------------------------
>
>                 Key: QPID-3462
>                 URL: https://issues.apache.org/jira/browse/QPID-3462
>             Project: Qpid
>          Issue Type: Bug
>          Components: Java Client
>    Affects Versions: 0.10, 0.12
>            Reporter: Rajith Attapattu
>            Assignee: Rajith Attapattu
>             Fix For: 0.14
>
>
> If a session is using CLIENT_ACK mode fails over to another broker, and calls acknowledge
on a message it received before failover, the client throws an IllegalStateException.
> The JMS spec states, that the IllegalStateException should only be thrown if the session
is closed. When failover happens the JMS session (or the JMS Connection) is not closed, instead
we transparently reconnect and create a new AMQP session and allow the application to continue
as nothing happens. Therefore throwing the above exception is incorrect.
> We have three options for handling this case.
> 1. Throw a JMSException notifying the application that this message was received in the
previous session. This notifies the application that the acknowledge didn't succeed and the
message is going to be redelivered.
> 2. Not throw an exception at all. The application is anyhow prepared to handle duplicates,
so this would not be an issue at all. With JMS the last acked message is always in doubt.
If the application is using CLIENT_ACK and acknowledging after 'n' messages, then it should
be prepared to handle 'n' duplicates in the event of a failover.
> 2. The client library can make it totally transparent by not throwing an exception at
all. 
> Instead it can look up this messages (along with all the other unacked messages upto
that point) in it's dispatch queue received after failover. The messages can be identified
using the message ID (and they will also be marked re-delivered by the broker).
> It can then call acknowledge on these messages and remove them from the dispatch queue.
i.e they will not be redelivered to the application at all.
> What do you think is the best option?
> Regards,
> Rajith

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:dev-subscribe@qpid.apache.org


Mime
View raw message