mirror of https://github.com/apache/activemq.git
[AMQ-6614] fix up jmx blockedSendsCount and producer view blocking flag for async send case. fix and test
This commit is contained in:
parent
eab9a0d057
commit
e67d48680f
|
@ -43,7 +43,7 @@ public class ProducerBrokerExchange {
|
||||||
private boolean auditProducerSequenceIds;
|
private boolean auditProducerSequenceIds;
|
||||||
private boolean isNetworkProducer;
|
private boolean isNetworkProducer;
|
||||||
private BrokerService brokerService;
|
private BrokerService brokerService;
|
||||||
private final FlowControlInfo flowControlInfo = new FlowControlInfo();
|
private FlowControlInfo flowControlInfo = new FlowControlInfo();
|
||||||
|
|
||||||
public ProducerBrokerExchange() {
|
public ProducerBrokerExchange() {
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ public class ProducerBrokerExchange {
|
||||||
rc.region = region;
|
rc.region = region;
|
||||||
rc.producerState = producerState;
|
rc.producerState = producerState;
|
||||||
rc.mutable = mutable;
|
rc.mutable = mutable;
|
||||||
|
rc.flowControlInfo = flowControlInfo;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -689,10 +689,15 @@ public class Queue extends BaseDestination implements Task, UsageListener, Index
|
||||||
} else {
|
} else {
|
||||||
LOG.debug("unexpected exception on deferred send of: {}", message, e);
|
LOG.debug("unexpected exception on deferred send of: {}", message, e);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
getDestinationStatistics().getBlockedSends().decrement();
|
||||||
|
producerExchangeCopy.blockingOnFlowControl(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
getDestinationStatistics().getBlockedSends().increment();
|
||||||
|
producerExchange.blockingOnFlowControl(true);
|
||||||
if (!context.isNetworkConnection() && systemUsage.getSendFailIfNoSpaceAfterTimeout() != 0) {
|
if (!context.isNetworkConnection() && systemUsage.getSendFailIfNoSpaceAfterTimeout() != 0) {
|
||||||
flowControlTimeoutMessages.add(new TimeoutMessage(message, context, systemUsage
|
flowControlTimeoutMessages.add(new TimeoutMessage(message, context, systemUsage
|
||||||
.getSendFailIfNoSpaceAfterTimeout()));
|
.getSendFailIfNoSpaceAfterTimeout()));
|
||||||
|
|
|
@ -19,9 +19,9 @@ package org.apache.activemq.transport.nio;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import org.apache.activemq.ActiveMQConnection;
|
import org.apache.activemq.ActiveMQConnection;
|
||||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||||
import org.apache.activemq.TestSupport;
|
|
||||||
import org.apache.activemq.broker.BrokerService;
|
import org.apache.activemq.broker.BrokerService;
|
||||||
import org.apache.activemq.broker.jmx.DestinationView;
|
import org.apache.activemq.broker.jmx.DestinationView;
|
||||||
|
import org.apache.activemq.broker.jmx.ProducerViewMBean;
|
||||||
import org.apache.activemq.broker.jmx.QueueView;
|
import org.apache.activemq.broker.jmx.QueueView;
|
||||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||||
|
@ -109,7 +109,7 @@ public class NIOAsyncSendWithPFCTest extends TestCase {
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sendMessagesAsync(1, DESTINATION_TWO);
|
sendMessages(1, DESTINATION_TWO, false);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.error("Ex on send new connection", ex);
|
LOG.error("Ex on send new connection", ex);
|
||||||
fail("*** received the following exception when creating addition producer new connection:" + ex);
|
fail("*** received the following exception when creating addition producer new connection:" + ex);
|
||||||
|
@ -148,6 +148,7 @@ public class NIOAsyncSendWithPFCTest extends TestCase {
|
||||||
|
|
||||||
//wait till producer follow control kicks in
|
//wait till producer follow control kicks in
|
||||||
waitForProducerFlowControl(broker, queueView);
|
waitForProducerFlowControl(broker, queueView);
|
||||||
|
assertTrue("Producer view blocked", getProducerView(broker, DESTINATION_ONE).isProducerBlocked());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Session producerSession = exisitngConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
Session producerSession = exisitngConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||||
|
@ -164,6 +165,34 @@ public class NIOAsyncSendWithPFCTest extends TestCase {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSyncSendPFCExistingConnection() throws Exception {
|
||||||
|
|
||||||
|
BrokerService broker = createBroker();
|
||||||
|
broker.waitUntilStarted();
|
||||||
|
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_PRODUCERS);
|
||||||
|
QueueView queueView = getQueueView(broker, DESTINATION_ONE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
for (int i = 0; i < NUMBER_OF_PRODUCERS; i++) {
|
||||||
|
|
||||||
|
executorService.submit(new ProducerTask(true));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//wait till producer follow control kicks in
|
||||||
|
waitForProducerFlowControl(broker, queueView);
|
||||||
|
assertTrue("Producer view blocked", getProducerView(broker, DESTINATION_ONE).isProducerBlocked());
|
||||||
|
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
broker.stop();
|
||||||
|
broker.waitUntilStopped();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForProducerFlowControl(BrokerService broker, QueueView queueView) throws Exception {
|
private void waitForProducerFlowControl(BrokerService broker, QueueView queueView) throws Exception {
|
||||||
|
@ -171,20 +200,30 @@ public class NIOAsyncSendWithPFCTest extends TestCase {
|
||||||
|
|
||||||
boolean blockingAllSends;
|
boolean blockingAllSends;
|
||||||
do {
|
do {
|
||||||
blockingAllSends = queueView.getBlockedSends() > 10;
|
blockingAllSends = queueView.getBlockedSends() >= 10;
|
||||||
|
LOG.info("Blocking all sends:" + queueView.getBlockedSends());
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
|
||||||
} while (!blockingAllSends);
|
} while (!blockingAllSends);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProducerTask implements Runnable {
|
class ProducerTask implements Runnable {
|
||||||
|
boolean sync = false;
|
||||||
|
|
||||||
|
ProducerTask() {
|
||||||
|
this(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProducerTask(boolean sync) {
|
||||||
|
this.sync = sync;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
//send X messages
|
//send X messages
|
||||||
sendMessagesAsync(MESSAGES_TO_SEND, DESTINATION_ONE);
|
sendMessages(MESSAGES_TO_SEND, DESTINATION_ONE, sync);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -192,7 +231,7 @@ public class NIOAsyncSendWithPFCTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Long sendMessagesAsync(int messageCount, String destination) throws Exception {
|
private Long sendMessages(int messageCount, String destination, boolean sync) throws Exception {
|
||||||
|
|
||||||
long numberOfMessageSent = 0;
|
long numberOfMessageSent = 0;
|
||||||
|
|
||||||
|
@ -201,7 +240,12 @@ public class NIOAsyncSendWithPFCTest extends TestCase {
|
||||||
|
|
||||||
|
|
||||||
ActiveMQConnection connection = (ActiveMQConnection) connectionFactory.createConnection();
|
ActiveMQConnection connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||||
|
if (sync) {
|
||||||
|
connection.setUseAsyncSend(false);
|
||||||
|
connection.setAlwaysSyncSend(true);
|
||||||
|
} else {
|
||||||
connection.setUseAsyncSend(true);
|
connection.setUseAsyncSend(true);
|
||||||
|
}
|
||||||
connection.start();
|
connection.start();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -221,16 +265,16 @@ public class NIOAsyncSendWithPFCTest extends TestCase {
|
||||||
LOG.info(" Finished after producing : " + numberOfMessageSent);
|
LOG.info(" Finished after producing : " + numberOfMessageSent);
|
||||||
return numberOfMessageSent;
|
return numberOfMessageSent;
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (JMSException expected) {
|
||||||
LOG.info("Exception received producing ", ex);
|
LOG.debug("Exception received producing ", expected);
|
||||||
LOG.info("finishing after exception :" + numberOfMessageSent);
|
|
||||||
return numberOfMessageSent;
|
|
||||||
} finally {
|
} finally {
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
|
try {
|
||||||
connection.close();
|
connection.close();
|
||||||
|
} catch (JMSException ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return numberOfMessageSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextMessage createTextMessage(Session session) throws JMSException {
|
private TextMessage createTextMessage(Session session) throws JMSException {
|
||||||
|
@ -264,5 +308,20 @@ public class NIOAsyncSendWithPFCTest extends TestCase {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ProducerViewMBean getProducerView(BrokerService broker, String qName) throws Exception {
|
||||||
|
ObjectName[] qProducers = broker.getAdminView().getQueueProducers();
|
||||||
|
for (ObjectName name : qProducers) {
|
||||||
|
ProducerViewMBean proxy = (ProducerViewMBean) broker.getManagementContext()
|
||||||
|
.newProxyInstance(name, ProducerViewMBean.class, true);
|
||||||
|
|
||||||
|
LOG.info("" + proxy.getProducerId() + ", dest: " + proxy.getDestinationName() + ", blocked: " + proxy.isProducerBlocked());
|
||||||
|
|
||||||
|
if (proxy.getDestinationName().contains(qName)) {
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue