/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.activemq.artemis.tests.performance.paging; import java.util.HashMap; import java.util.concurrent.CountDownLatch; import org.apache.activemq.artemis.api.core.ActiveMQException; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.junit.Test; public class MeasurePagingMultiThreadTest extends ActiveMQTestBase { @Test public void testPagingMultipleSenders() throws Throwable { final int NUMBER_OF_THREADS = 18; final int NUMBER_OF_MESSAGES = 50000; final int SIZE_OF_MESSAGE = 1024; HashMap<String, AddressSettings> settings = new HashMap<>(); ActiveMQServer messagingService = createServer(true, createDefaultInVMConfig(), 10 * 1024, 20 * 1024, settings); messagingService.start(); ServerLocator locator = createInVMNonHALocator(); try { final ClientSessionFactory factory = createSessionFactory(locator); final SimpleString adr = new SimpleString("test-adr"); createDestination(factory, adr); // Send some messages to make sure the destination is in page mode before we measure // And that will also help with VM optimizations sendInitialBatch(adr, NUMBER_OF_MESSAGES, SIZE_OF_MESSAGE, factory); final CountDownLatch latchAlign = new CountDownLatch(NUMBER_OF_THREADS); final CountDownLatch latchStart = new CountDownLatch(1); class Sender extends Thread { private final ClientSession session; private final ClientProducer producer; private final ClientMessage msg; Throwable e; Sender() throws Exception { session = factory.createSession(false, true, true); producer = session.createProducer(adr); msg = session.createMessage(true); msg.getBodyBuffer().writeBytes(new byte[SIZE_OF_MESSAGE]); } // run is not going to close sessions or anything, as we don't want to measure that time // so this will be done in a second time public void cleanUp() throws Exception { session.close(); } @Override public void run() { try { latchAlign.countDown(); ActiveMQTestBase.waitForLatch(latchStart); long start = System.currentTimeMillis(); sendMessages(NUMBER_OF_MESSAGES, producer, msg); long end = System.currentTimeMillis(); System.out.println("Thread " + Thread.currentThread().getName() + " finished sending in " + (end - start) + " milliseconds"); } catch (Throwable e) { this.e = e; } } } Sender[] senders = new Sender[NUMBER_OF_THREADS]; for (int i = 0; i < NUMBER_OF_THREADS; i++) { senders[i] = new Sender(); senders[i].start(); } ActiveMQTestBase.waitForLatch(latchAlign); long timeStart = System.currentTimeMillis(); latchStart.countDown(); for (Thread t : senders) { t.join(); } long timeEnd = System.currentTimeMillis(); System.out.println("Total Time: " + (timeEnd - timeStart) + " milliseconds what represented " + NUMBER_OF_MESSAGES * NUMBER_OF_THREADS * 1000 / (timeEnd - timeStart) + " per second"); for (Sender s : senders) { if (s.e != null) { throw s.e; } s.cleanUp(); } } finally { locator.close(); messagingService.stop(); } } // Package protected --------------------------------------------- // Protected ----------------------------------------------------- // Private ------------------------------------------------------- /** * @param adr * @param nMessages * @param messageSize * @param factory * @throws ActiveMQException */ private void sendInitialBatch(final SimpleString adr, final int nMessages, final int messageSize, final ClientSessionFactory factory) throws ActiveMQException { ClientSession session = factory.createSession(false, true, true); ClientProducer producer = session.createProducer(adr); ClientMessage msg = session.createMessage(true); msg.getBodyBuffer().writeBytes(new byte[messageSize]); sendMessages(nMessages, producer, msg); } /** * @param nMessages * @param producer * @param msg * @throws ActiveMQException */ private void sendMessages(final int nMessages, final ClientProducer producer, final ClientMessage msg) throws ActiveMQException { for (int i = 0; i < nMessages; i++) { producer.send(msg); } } /** * @param factory * @param adr * @throws ActiveMQException */ private void createDestination(final ClientSessionFactory factory, final SimpleString adr) throws ActiveMQException { { ClientSession session = factory.createSession(false, false, false); session.createQueue(adr, adr, null, true); session.close(); } } // Inner classes ------------------------------------------------- }