use of org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal in project activemq-artemis by apache.
the class ConsumerWindowSizeTest method internalTestSlowConsumerNoBuffer.
private void internalTestSlowConsumerNoBuffer(final boolean largeMessages) throws Exception {
ActiveMQServer server = createServer(false, isNetty());
ClientSession sessionB = null;
ClientSession session = null;
try {
final int numberOfMessages = 100;
server.start();
locator.setConsumerWindowSize(0);
if (largeMessages) {
locator.setMinLargeMessageSize(100);
}
ClientSessionFactory sf = createSessionFactory(locator);
session = sf.createSession(false, true, true);
SimpleString ADDRESS = addressA;
session.createQueue(ADDRESS, ADDRESS, true);
sessionB = sf.createSession(false, true, true);
sessionB.start();
session.start();
ClientConsumerInternal consNeverUsed = (ClientConsumerInternal) sessionB.createConsumer(ADDRESS);
ClientProducer prod = session.createProducer(ADDRESS);
// This will force a credit to be sent, but if the message wasn't received we need to take out that credit from
// the server
// or the client will be buffering messages
Assert.assertNull(consNeverUsed.receive(1));
ClientMessage msg = createTextMessage(session, "This one will expire");
if (largeMessages) {
msg.getBodyBuffer().writeBytes(new byte[600]);
}
msg.setExpiration(System.currentTimeMillis() + 100);
prod.send(msg);
msg = createTextMessage(session, "First-on-non-buffered");
prod.send(msg);
Thread.sleep(110);
// It will be able to receive another message, but it shouldn't send a credit again, as the credit was already
// sent
msg = consNeverUsed.receive(TIMEOUT * 1000);
Assert.assertNotNull(msg);
Assert.assertEquals("First-on-non-buffered", getTextMessage(msg));
msg.acknowledge();
ClientConsumer cons1 = session.createConsumer(ADDRESS);
for (int i = 0; i < numberOfMessages; i++) {
msg = createTextMessage(session, "Msg" + i);
if (largeMessages) {
msg.getBodyBuffer().writeBytes(new byte[600]);
}
prod.send(msg);
}
for (int i = 0; i < numberOfMessages; i++) {
msg = cons1.receive(1000);
Assert.assertNotNull("expected message at i = " + i, msg);
Assert.assertEquals("Msg" + i, getTextMessage(msg));
msg.acknowledge();
}
Assert.assertEquals(0, consNeverUsed.getBufferSize());
session.close();
session = null;
sessionB.close();
sessionB = null;
Assert.assertEquals(0, getMessageCount(server, ADDRESS.toString()));
} finally {
try {
if (session != null) {
session.close();
}
if (sessionB != null) {
sessionB.close();
}
} catch (Exception ignored) {
}
}
}
use of org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal in project activemq-artemis by apache.
the class ConsumerWindowSizeTest method internalTestSlowConsumerNoBuffer2.
private void internalTestSlowConsumerNoBuffer2(final boolean largeMessages) throws Exception {
ActiveMQServer server = createServer(false, isNetty());
ClientSession session1 = null;
ClientSession session2 = null;
try {
final int numberOfMessages = 10;
server.start();
locator.setConsumerWindowSize(0);
if (largeMessages) {
locator.setMinLargeMessageSize(100);
}
ClientSessionFactory sf = createSessionFactory(locator);
session1 = sf.createSession(false, true, true);
session2 = sf.createSession(false, true, true);
session1.start();
session2.start();
SimpleString ADDRESS = new SimpleString("some-queue");
session1.createQueue(ADDRESS, ADDRESS, true);
ClientConsumerInternal cons1 = (ClientConsumerInternal) session1.createConsumer(ADDRESS);
// Note we make sure we send the messages *before* cons2 is created
ClientProducer prod = session1.createProducer(ADDRESS);
for (int i = 0; i < numberOfMessages; i++) {
ClientMessage msg = createTextMessage(session1, "Msg" + i);
if (largeMessages) {
msg.getBodyBuffer().writeBytes(new byte[600]);
}
prod.send(msg);
}
ClientConsumerInternal cons2 = (ClientConsumerInternal) session2.createConsumer(ADDRESS);
for (int i = 0; i < numberOfMessages / 2; i++) {
ClientMessage msg = cons1.receive(1000);
Assert.assertNotNull("expected message at i = " + i, msg);
String str = getTextMessage(msg);
Assert.assertEquals("Msg" + i, str);
log.info("got msg " + str);
msg.acknowledge();
Assert.assertEquals("A slow consumer shouldn't buffer anything on the client side!", 0, cons1.getBufferSize());
}
for (int i = numberOfMessages / 2; i < numberOfMessages; i++) {
ClientMessage msg = cons2.receive(1000);
Assert.assertNotNull("expected message at i = " + i, msg);
String str = getTextMessage(msg);
log.info("got msg " + str);
Assert.assertEquals("Msg" + i, str);
msg.acknowledge();
Assert.assertEquals("A slow consumer shouldn't buffer anything on the client side!", 0, cons2.getBufferSize());
}
// just to make sure everything is flushed and no pending packets on the sending buffer, or
session1.close();
// the getMessageCount would fail
session2.close();
session1 = sf.createSession(false, true, true);
session1.start();
session2 = sf.createSession(false, true, true);
session2.start();
prod = session1.createProducer(ADDRESS);
Assert.assertEquals(0, getMessageCount(server, ADDRESS.toString()));
// This should also work the other way around
cons1.close();
cons2.close();
cons1 = (ClientConsumerInternal) session1.createConsumer(ADDRESS);
for (int i = 0; i < numberOfMessages; i++) {
ClientMessage msg = createTextMessage(session1, "Msg" + i);
if (largeMessages) {
msg.getBodyBuffer().writeBytes(new byte[600]);
}
prod.send(msg);
}
cons2 = (ClientConsumerInternal) session2.createConsumer(ADDRESS);
for (int i = 0; i < numberOfMessages / 2; i++) {
ClientMessage msg = cons2.receive(1000);
Assert.assertNotNull("expected message at i = " + i, msg);
Assert.assertEquals("Msg" + i, msg.getBodyBuffer().readString());
msg.acknowledge();
Assert.assertEquals("A slow consumer shouldn't buffer anything on the client side!", 0, cons2.getBufferSize());
}
for (int i = numberOfMessages / 2; i < numberOfMessages; i++) {
ClientMessage msg = cons1.receive(1000);
Assert.assertNotNull("expected message at i = " + i, msg);
Assert.assertEquals("Msg" + i, msg.getBodyBuffer().readString());
msg.acknowledge();
Assert.assertEquals("A slow consumer shouldn't buffer anything on the client side!", 0, cons1.getBufferSize());
}
session1.close();
session1 = null;
session2.close();
session2 = null;
Assert.assertEquals(0, getMessageCount(server, ADDRESS.toString()));
} finally {
try {
if (session1 != null) {
session1.close();
}
if (session2 != null) {
session2.close();
}
} catch (Exception ignored) {
}
}
}
use of org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal in project activemq-artemis by apache.
the class ConsumerWindowSizeTest method testNoWindowRoundRobin.
private void testNoWindowRoundRobin(final boolean largeMessages) throws Exception {
ActiveMQServer server = createServer(false, isNetty());
ClientSession sessionA = null;
ClientSession sessionB = null;
try {
final int numberOfMessages = 100;
server.start();
locator.setConsumerWindowSize(-1);
if (largeMessages) {
locator.setMinLargeMessageSize(100);
}
ClientSessionFactory sf = createSessionFactory(locator);
sessionA = sf.createSession(false, true, true);
SimpleString ADDRESS = new SimpleString("some-queue");
sessionA.createQueue(ADDRESS, ADDRESS, true);
sessionB = sf.createSession(false, true, true);
sessionA.start();
sessionB.start();
ClientConsumerInternal consA = (ClientConsumerInternal) sessionA.createConsumer(ADDRESS);
ClientConsumerInternal consB = (ClientConsumerInternal) sessionB.createConsumer(ADDRESS);
{
// We can only guarantee round robing with WindowSize = -1, after the ServerConsumer object received
// SessionConsumerFlowCreditMessage(-1)
// Since that is done asynchronously we verify that the information was received before we proceed on
// sending messages or else the distribution won't be
// even as expected by the test
Bindings bindings = server.getPostOffice().getBindingsForAddress(ADDRESS);
Assert.assertEquals(1, bindings.getBindings().size());
for (Binding binding : bindings.getBindings()) {
Collection<Consumer> consumers = ((QueueBinding) binding).getQueue().getConsumers();
for (Consumer consumer : consumers) {
ServerConsumerImpl consumerImpl = (ServerConsumerImpl) consumer;
long timeout = System.currentTimeMillis() + 5000;
while (timeout > System.currentTimeMillis() && consumerImpl.getAvailableCredits() != null) {
Thread.sleep(10);
}
Assert.assertNull(consumerImpl.getAvailableCredits());
}
}
}
ClientProducer prod = sessionA.createProducer(ADDRESS);
for (int i = 0; i < numberOfMessages; i++) {
ClientMessage msg = createTextMessage(sessionA, "Msg" + i);
if (largeMessages) {
msg.getBodyBuffer().writeBytes(new byte[600]);
}
prod.send(msg);
}
long timeout = System.currentTimeMillis() + TIMEOUT * 1000;
boolean foundA = false;
boolean foundB = false;
do {
foundA = consA.getBufferSize() == numberOfMessages / 2;
foundB = consB.getBufferSize() == numberOfMessages / 2;
Thread.sleep(10);
} while ((!foundA || !foundB) && System.currentTimeMillis() < timeout);
Assert.assertTrue("ConsumerA didn't receive the expected number of messages on buffer (consA=" + consA.getBufferSize() + ", consB=" + consB.getBufferSize() + ") foundA = " + foundA + " foundB = " + foundB, foundA);
Assert.assertTrue("ConsumerB didn't receive the expected number of messages on buffer (consA=" + consA.getBufferSize() + ", consB=" + consB.getBufferSize() + ") foundA = " + foundA + " foundB = " + foundB, foundB);
} finally {
try {
if (sessionA != null) {
sessionA.close();
}
if (sessionB != null) {
sessionB.close();
}
} catch (Exception ignored) {
}
}
}
use of org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal in project activemq-artemis by apache.
the class ConsumerWindowSizeTest method internalTestSlowConsumerOnMessageHandlerNoBuffers.
public void internalTestSlowConsumerOnMessageHandlerNoBuffers(final boolean largeMessages) throws Exception {
ActiveMQServer server = createServer(false, isNetty());
ClientSession sessionB = null;
ClientSession session = null;
try {
final int numberOfMessages = 100;
server.start();
locator.setConsumerWindowSize(0);
if (largeMessages) {
locator.setMinLargeMessageSize(100);
}
ClientSessionFactory sf = createSessionFactory(locator);
session = sf.createSession(false, true, true);
SimpleString ADDRESS = new SimpleString("some-queue");
session.createQueue(ADDRESS, ADDRESS, true);
sessionB = sf.createSession(false, true, true);
sessionB.start();
session.start();
ClientConsumerInternal consReceiveOneAndHold = (ClientConsumerInternal) sessionB.createConsumer(ADDRESS);
final CountDownLatch latchReceived = new CountDownLatch(2);
final CountDownLatch latchDone = new CountDownLatch(1);
// It can't close the session while the large message is being read
final CountDownLatch latchRead = new CountDownLatch(1);
// It should receive two messages and then give up
class LocalHandler implements MessageHandler {
boolean failed = false;
int count = 0;
/* (non-Javadoc)
* @see MessageHandler#onMessage(ClientMessage)
*/
@Override
public synchronized void onMessage(final ClientMessage message) {
try {
String str = getTextMessage(message);
failed = failed || !str.equals("Msg" + count);
message.acknowledge();
latchReceived.countDown();
if (count++ == 1) {
// it will hold here for a while
if (!latchDone.await(TIMEOUT, TimeUnit.SECONDS)) {
// a timed wait, so if the test fails, one less thread around
new Exception("ClientConsuemrWindowSizeTest Handler couldn't receive signal in less than 5 seconds").printStackTrace();
failed = true;
}
if (largeMessages) {
message.getBodyBuffer().readBytes(new byte[600]);
}
latchRead.countDown();
}
} catch (Exception e) {
// Hudson / JUnit report
e.printStackTrace();
failed = true;
}
}
}
LocalHandler handler = new LocalHandler();
ClientConsumer cons1 = session.createConsumer(ADDRESS);
ClientProducer prod = session.createProducer(ADDRESS);
for (int i = 0; i < numberOfMessages; i++) {
ClientMessage msg = createTextMessage(session, "Msg" + i);
if (largeMessages) {
msg.getBodyBuffer().writeBytes(new byte[600]);
}
prod.send(msg);
}
consReceiveOneAndHold.setMessageHandler(handler);
Assert.assertTrue(latchReceived.await(TIMEOUT, TimeUnit.SECONDS));
Assert.assertEquals(0, consReceiveOneAndHold.getBufferSize());
for (int i = 2; i < numberOfMessages; i++) {
ClientMessage msg = cons1.receive(1000);
Assert.assertNotNull("expected message at i = " + i, msg);
Assert.assertEquals("Msg" + i, getTextMessage(msg));
msg.acknowledge();
}
Assert.assertEquals(0, consReceiveOneAndHold.getBufferSize());
latchDone.countDown();
// The test can' t close the session while the message is still being read, or it could interrupt the data
Assert.assertTrue(latchRead.await(10, TimeUnit.SECONDS));
session.close();
session = null;
sessionB.close();
sessionB = null;
Assert.assertEquals(0, getMessageCount(server, ADDRESS.toString()));
Assert.assertFalse("MessageHandler received a failure", handler.failed);
} finally {
try {
if (session != null) {
session.close();
}
if (sessionB != null) {
sessionB.close();
}
} catch (Exception ignored) {
}
}
}
use of org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal in project activemq-artemis by apache.
the class ConsumerWindowSizeTest method internalTestFlowControlOnRollback.
private void internalTestFlowControlOnRollback(final boolean isLargeMessage) throws Exception {
ActiveMQServer server = createServer(false, isNetty());
AddressSettings settings = new AddressSettings().setMaxDeliveryAttempts(-1);
server.getAddressSettingsRepository().addMatch("#", settings);
ClientSession session = null;
try {
final int numberOfMessages = 100;
server.start();
locator.setConsumerWindowSize(300000);
if (isLargeMessage) {
// something to ensure we are using large messages
locator.setMinLargeMessageSize(100);
} else {
// To make sure large messages won't kick in, we set anything large
locator.setMinLargeMessageSize(Integer.MAX_VALUE);
}
ClientSessionFactory sf = createSessionFactory(locator);
session = sf.createSession(false, false, false);
SimpleString ADDRESS = new SimpleString("some-queue");
session.createQueue(ADDRESS, ADDRESS, true);
ClientProducer producer = session.createProducer(ADDRESS);
for (int i = 0; i < numberOfMessages; i++) {
ClientMessage msg = session.createMessage(true);
msg.putIntProperty("count", i);
msg.getBodyBuffer().writeBytes(new byte[1024]);
producer.send(msg);
}
session.commit();
ClientConsumerInternal consumer = (ClientConsumerInternal) session.createConsumer(ADDRESS);
session.start();
for (int repeat = 0; repeat < 100; repeat++) {
long timeout = System.currentTimeMillis() + 2000;
// At least 10 messages on the buffer
while (timeout > System.currentTimeMillis() && consumer.getBufferSize() <= 10) {
Thread.sleep(10);
}
Assert.assertTrue(consumer.getBufferSize() >= 10);
ClientMessage msg = consumer.receive(500);
msg.getBodyBuffer().readByte();
Assert.assertNotNull(msg);
msg.acknowledge();
session.rollback();
}
for (int i = 0; i < numberOfMessages; i++) {
ClientMessage msg = consumer.receive(5000);
Assert.assertNotNull(msg);
msg.getBodyBuffer().readByte();
msg.acknowledge();
session.commit();
}
} finally {
try {
if (session != null) {
session.close();
}
} catch (Exception ignored) {
}
}
}
Aggregations