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

Erich Duda resolved ARTEMIS-1506.
---------------------------------
       Resolution: Fixed
    Fix Version/s: 2.5.0

> Synchronization issue during failover in ClientSessionImpl
> ----------------------------------------------------------
>
>                 Key: ARTEMIS-1506
>                 URL: https://issues.apache.org/jira/browse/ARTEMIS-1506
>             Project: ActiveMQ Artemis
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 2.3.0
>            Reporter: Erich Duda
>             Fix For: 2.5.0
>
>
> This issue was hit in test {{MultiThreadRandomReattachTest}}. There are 
> several client's threads doing some work, while connection fail is simulated. 
> The test expects that all threads finish without exceptions.
> This issue causes that some client's threads sometime fail with an exception 
> {{AMQ119014: Timed out after waiting 30,000 ms for response when sending 
> packet XXX}}.
> I found out that the mentioned exception is caused by temporary deadlock 
> during doing failover on client's side. These two threads block each other.
> {code}
> "Thread-7" Id=29 TIMED_WAITING on 
> java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@1d03220
>       at sun.misc.Unsafe.park(Native Method)
>       -  waiting on 
> java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@1d03220
>       at 
> java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
>       at 
> java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2163)
>       at 
> org.apache.activemq.artemis.utils.ConcurrentUtil.await(ConcurrentUtil.java:37)
>       at 
> org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.waitForFailOver(ChannelImpl.java:256)
>       at 
> org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.send(ChannelImpl.java:283)
>       -  locked java.lang.Object@938196
>       at 
> org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.send(ChannelImpl.java:229)
>       at 
> org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext.sendProducerCreditsMessage(ActiveMQSessionContext.java:421)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.sendProducerCreditsMessage(ClientSessionImpl.java:1342)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientProducerCreditsImpl.requestCredits(ClientProducerCreditsImpl.java:209)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientProducerCreditsImpl.checkCredits(ClientProducerCreditsImpl.java:204)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientProducerCreditsImpl.init(ClientProducerCreditsImpl.java:71)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientProducerCreditManagerImpl.getCredits(ClientProducerCreditManagerImpl.java:79)
>       -  locked 
> org.apache.activemq.artemis.core.client.impl.ClientProducerCreditManagerImpl@f7a5dc
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.getCredits(ClientSessionImpl.java:1347)
>       -  locked 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl@10867c8
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientProducerImpl.<init>(ClientProducerImpl.java:102)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.internalCreateProducer(ClientSessionImpl.java:1817)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.createProducer(ClientSessionImpl.java:740)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.createProducer(ClientSessionImpl.java:730)
>       at 
> org.apache.activemq.artemis.tests.integration.cluster.reattach.MultiThreadRandomReattachTestBase.doTestB(MultiThreadRandomReattachTestBase.java:398)
>       at 
> org.apache.activemq.artemis.tests.integration.cluster.reattach.MultiThreadRandomReattachTestBase$2.run(MultiThreadRandomReattachTestBase.java:84)
>       at 
> org.apache.activemq.artemis.tests.integration.cluster.reattach.MultiThreadReattachSupportTestBase$1Runner.run(MultiThreadReattachSupportTestBase.java:104)
> {code}
> {code}
> "Timer-0" Id=9 BLOCKED on 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl@10867c8 owned 
> by "Thread-7" Id=29
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.handleFailover(ClientSessionImpl.java:1206)
>       -  blocked on 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl@10867c8
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.reconnectSessions(ClientSessionFactoryImpl.java:771)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.failoverOrReconnect(ClientSessionFactoryImpl.java:614)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.handleConnectionFailure(ClientSessionFactoryImpl.java:504)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.access$600(ClientSessionFactoryImpl.java:72)
>       at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl$DelegatingFailureListener.connectionFailed(ClientSessionFactoryImpl.java:1175)
>       at 
> org.apache.activemq.artemis.spi.core.protocol.AbstractRemotingConnection.callFailureListeners(AbstractRemotingConnection.java:70)
>       at 
> org.apache.activemq.artemis.core.protocol.core.impl.RemotingConnectionImpl.fail(RemotingConnectionImpl.java:209)
>       at 
> org.apache.activemq.artemis.spi.core.protocol.AbstractRemotingConnection.fail(AbstractRemotingConnection.java:213)
>       at 
> org.apache.activemq.artemis.tests.integration.cluster.reattach.MultiThreadReattachSupportTestBase$Failer.run(MultiThreadReattachSupportTestBase.java:220)
>       -  locked 
> org.apache.activemq.artemis.tests.integration.cluster.reattach.MultiThreadReattachSupportTestBase$Failer@16d859
>       at java.util.TimerThread.mainLoop(Timer.java:555)
>       at java.util.TimerThread.run(Timer.java:505)
>       Number of locked synchronizers = 1
>       - java.util.concurrent.locks.ReentrantLock$NonfairSync@1ac8dee
> {code}
> The first thread holds {{ClientSessionImpl}} lock in method {{getCredits}} 
> which tries to send a packet and thus it waits until the connection is 
> reconnected or do failover to backup.
> {code:java}
> public final class ClientSessionImpl implements ClientSessionInternal, 
> FailureListener {
>    @Override
>    public synchronized ClientProducerCredits getCredits(final SimpleString 
> address, final boolean anon) {
>       ClientProducerCredits credits = 
> producerCreditManager.getCredits(address, anon, sessionContext);
>       return credits;
>    }
> }
> {code}
> The second thread is responsible for handling the connection failure and 
> doing the  re-connection or failover. However it is blocked by the first 
> thread because it requires {{ClientSessionImpl}} lock.
> {code:java}
> public final class ClientSessionImpl implements ClientSessionInternal, 
> FailureListener {
>    @Override
>    public void handleFailover(final RemotingConnection backupConnection, 
> ActiveMQException cause) {
>       synchronized (this) {
>          if (closed) {
>             return;
>          }
>          ...
>    }
> }
> {code}
> This situation lasts until some other thread throws an exception because it 
> doesn't receive response for its blocking packet, as the the connection was 
> not reconnected.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to