use of org.apache.activemq.artemis.utils.actors.ArtemisExecutor in project activemq-artemis by apache.
the class HangConsumerTest method testHangDuplicateQueues.
/**
* This would recreate the scenario where a queue was duplicated
*
* @throws Exception
*/
@Test
public void testHangDuplicateQueues() throws Exception {
final Semaphore blocked = new Semaphore(1);
final CountDownLatch latchDelete = new CountDownLatch(1);
class MyQueueWithBlocking extends QueueImpl {
/**
* @param id
* @param address
* @param name
* @param filter
* @param pageSubscription
* @param durable
* @param temporary
* @param scheduledExecutor
* @param postOffice
* @param storageManager
* @param addressSettingsRepository
* @param executor
*/
MyQueueWithBlocking(final long id, final SimpleString address, final SimpleString name, final Filter filter, final SimpleString user, final PageSubscription pageSubscription, final boolean durable, final boolean temporary, final boolean autoCreated, final RoutingType deliveryMode, final Integer maxConsumers, final Boolean purgeOnNoConsumers, final ScheduledExecutorService scheduledExecutor, final PostOffice postOffice, final StorageManager storageManager, final HierarchicalRepository<AddressSettings> addressSettingsRepository, final ArtemisExecutor executor, final ActiveMQServer server) {
super(id, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, deliveryMode, maxConsumers, purgeOnNoConsumers, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executor, server, null);
}
@Override
public synchronized int deleteMatchingReferences(final int flushLimit, final Filter filter) throws Exception {
latchDelete.countDown();
blocked.acquire();
blocked.release();
return super.deleteMatchingReferences(flushLimit, filter);
}
@Override
public void deliverScheduledMessages() {
}
}
class LocalFactory extends QueueFactoryImpl {
LocalFactory(final ExecutorFactory executorFactory, final ScheduledExecutorService scheduledExecutor, final HierarchicalRepository<AddressSettings> addressSettingsRepository, final StorageManager storageManager, final ActiveMQServer server) {
super(executorFactory, scheduledExecutor, addressSettingsRepository, storageManager, server);
}
@Override
public Queue createQueueWith(final QueueConfig config) {
queue = new MyQueueWithBlocking(config.id(), config.address(), config.name(), config.filter(), config.user(), config.pageSubscription(), config.isDurable(), config.isTemporary(), config.isAutoCreated(), config.deliveryMode(), config.maxConsumers(), config.isPurgeOnNoConsumers(), scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor(), server);
return queue;
}
@Deprecated
@Override
public Queue createQueue(final long persistenceID, final SimpleString address, final SimpleString name, final Filter filter, final PageSubscription pageSubscription, final SimpleString user, final boolean durable, final boolean temporary, final boolean autoCreated) {
queue = new MyQueueWithBlocking(persistenceID, address, name, filter, user, pageSubscription, durable, temporary, autoCreated, RoutingType.MULTICAST, null, null, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor(), server);
return queue;
}
}
LocalFactory queueFactory = new LocalFactory(server.getExecutorFactory(), server.getScheduledPool(), server.getAddressSettingsRepository(), server.getStorageManager(), server);
queueFactory.setPostOffice(server.getPostOffice());
((ActiveMQServerImpl) server).replaceQueueFactory(queueFactory);
queue = server.createQueue(QUEUE, RoutingType.ANYCAST, QUEUE, null, true, false);
blocked.acquire();
ClientSessionFactory factory = locator.createSessionFactory();
ClientSession session = factory.createSession(false, false, false);
ClientProducer producer = session.createProducer(QUEUE);
producer.send(session.createMessage(true));
session.commit();
Thread tDelete = new Thread() {
@Override
public void run() {
try {
server.destroyQueue(QUEUE);
} catch (Exception e) {
e.printStackTrace();
}
}
};
tDelete.start();
Assert.assertTrue(latchDelete.await(10, TimeUnit.SECONDS));
try {
server.createQueue(QUEUE, RoutingType.ANYCAST, QUEUE, null, true, false);
} catch (Exception expected) {
}
blocked.release();
server.stop();
tDelete.join();
session.close();
// a duplicate binding would impede the server from starting
server.start();
waitForServerToStart(server);
server.stop();
}
use of org.apache.activemq.artemis.utils.actors.ArtemisExecutor in project activemq-artemis by apache.
the class InterruptedLargeMessageTest method testRestartBeforeDelete.
@Test
public void testRestartBeforeDelete() throws Exception {
class NoPostACKQueue extends QueueImpl {
NoPostACKQueue(long id, SimpleString address, SimpleString name, Filter filter, SimpleString user, PageSubscription pageSubscription, boolean durable, boolean temporary, boolean autoCreated, ScheduledExecutorService scheduledExecutor, PostOffice postOffice, StorageManager storageManager, HierarchicalRepository<AddressSettings> addressSettingsRepository, ArtemisExecutor executor) {
super(id, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executor, null, null);
}
@Override
public void postAcknowledge(final MessageReference ref) {
System.out.println("Ignoring postACK on message " + ref);
}
@Override
public void deliverScheduledMessages() {
}
}
final class NoPostACKQueueFactory implements QueueFactory {
final StorageManager storageManager;
final PostOffice postOffice;
final ScheduledExecutorService scheduledExecutor;
final HierarchicalRepository<AddressSettings> addressSettingsRepository;
final ExecutorFactory execFactory;
NoPostACKQueueFactory(StorageManager storageManager, PostOffice postOffice, ScheduledExecutorService scheduledExecutor, HierarchicalRepository<AddressSettings> addressSettingsRepository, final ExecutorFactory execFactory) {
this.storageManager = storageManager;
this.postOffice = postOffice;
this.scheduledExecutor = scheduledExecutor;
this.addressSettingsRepository = addressSettingsRepository;
this.execFactory = execFactory;
}
@Override
public Queue createQueueWith(final QueueConfig config) {
return new NoPostACKQueue(config.id(), config.address(), config.name(), config.filter(), config.user(), config.pageSubscription(), config.isDurable(), config.isTemporary(), config.isAutoCreated(), scheduledExecutor, postOffice, storageManager, addressSettingsRepository, execFactory.getExecutor());
}
@Deprecated
@Override
public Queue createQueue(long persistenceID, SimpleString address, SimpleString name, Filter filter, PageSubscription pageSubscription, SimpleString user, boolean durable, boolean temporary, boolean autoCreated) {
return new NoPostACKQueue(persistenceID, address, name, filter, user, pageSubscription, durable, temporary, autoCreated, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, execFactory.getExecutor());
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.server.QueueFactory#setPostOffice(org.apache.activemq.artemis.core.postoffice.PostOffice)
*/
@Override
public void setPostOffice(PostOffice postOffice) {
}
}
ClientSession session = null;
LargeMessageTestInterceptorIgnoreLastPacket.disableInterrupt();
ActiveMQServer server = createServer(true, isNetty());
server.start();
QueueFactory original = server.getQueueFactory();
((ActiveMQServerImpl) server).replaceQueueFactory(new NoPostACKQueueFactory(server.getStorageManager(), server.getPostOffice(), server.getScheduledPool(), server.getAddressSettingsRepository(), server.getExecutorFactory()));
locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true);
ClientSessionFactory sf = createSessionFactory(locator);
session = sf.createSession(false, true, true);
session.createQueue(ADDRESS, ADDRESS, true);
ClientProducer producer = session.createProducer(ADDRESS);
for (int i = 0; i < 10; i++) {
Message clientFile = createLargeClientMessageStreaming(session, LARGE_MESSAGE_SIZE, true);
producer.send(clientFile);
}
session.commit();
session.close();
session = sf.createSession(false, false);
ClientConsumer cons = session.createConsumer(ADDRESS);
session.start();
for (int i = 0; i < 10; i++) {
ClientMessage msg = cons.receive(5000);
Assert.assertNotNull(msg);
msg.saveToOutputStream(new java.io.OutputStream() {
@Override
public void write(int b) throws IOException {
}
});
msg.acknowledge();
session.commit();
}
((ActiveMQServerImpl) server).replaceQueueFactory(original);
server.fail(false);
server.start();
server.stop();
validateNoFilesOnLargeDir();
}
use of org.apache.activemq.artemis.utils.actors.ArtemisExecutor in project activemq-artemis by apache.
the class PagingTest method testRestartWithComplete.
// The pages are complete, and this is simulating a scenario where the server crashed before deleting the pages.
@Test
public void testRestartWithComplete() throws Exception {
clearDataRecreateServerDirs();
Configuration config = createDefaultInVMConfig();
final AtomicBoolean mainCleanup = new AtomicBoolean(true);
class InterruptedCursorProvider extends PageCursorProviderImpl {
InterruptedCursorProvider(PagingStore pagingStore, StorageManager storageManager, ArtemisExecutor executor, int maxCacheSize) {
super(pagingStore, storageManager, executor, maxCacheSize);
}
@Override
public void cleanup() {
if (mainCleanup.get()) {
super.cleanup();
} else {
try {
pagingStore.unlock();
} catch (Throwable ignored) {
}
}
}
}
server = new ActiveMQServerImpl(config, ManagementFactory.getPlatformMBeanServer(), new ActiveMQSecurityManagerImpl()) {
@Override
protected PagingStoreFactoryNIO getPagingStoreFactory() {
return new PagingStoreFactoryNIO(this.getStorageManager(), this.getConfiguration().getPagingLocation(), this.getConfiguration().getJournalBufferTimeout_NIO(), this.getScheduledPool(), this.getExecutorFactory(), this.getConfiguration().isJournalSyncNonTransactional(), null) {
@Override
public PageCursorProvider newCursorProvider(PagingStore store, StorageManager storageManager, AddressSettings addressSettings, ArtemisExecutor executor) {
return new InterruptedCursorProvider(store, storageManager, executor, addressSettings.getPageCacheMaxSize());
}
};
}
};
addServer(server);
AddressSettings defaultSetting = new AddressSettings().setPageSizeBytes(PagingTest.PAGE_SIZE).setMaxSizeBytes(PagingTest.PAGE_MAX).setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
server.getAddressSettingsRepository().addMatch("#", defaultSetting);
server.start();
locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
sf = createSessionFactory(locator);
ClientSession session = sf.createSession(true, true, 0);
session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
Queue queue = server.locateQueue(ADDRESS);
queue.getPageSubscription().getPagingStore().startPaging();
ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
ClientMessage message;
for (int i = 0; i < 20; i++) {
message = session.createMessage(true);
ActiveMQBuffer bodyLocal = message.getBodyBuffer();
bodyLocal.writeBytes(new byte[100 * 4]);
message.putIntProperty(new SimpleString("idi"), i);
producer.send(message);
session.commit();
if (i < 19) {
queue.getPageSubscription().getPagingStore().forceAnotherPage();
}
}
Assert.assertEquals(20, queue.getPageSubscription().getPagingStore().getCurrentWritingPage());
// This will force a scenario where the pages are cleaned up. When restarting we need to check if the current page is complete
// if it is complete we must move to another page avoiding races on cleanup
// which could happen during a crash / restart
long tx = server.getStorageManager().generateID();
for (int i = 1; i <= 20; i++) {
server.getStorageManager().storePageCompleteTransactional(tx, queue.getID(), new PagePositionImpl(i, 1));
}
server.getStorageManager().commit(tx);
session.close();
sf.close();
server.stop();
mainCleanup.set(false);
logger.trace("Server restart");
server.start();
queue = server.locateQueue(ADDRESS);
locator = createInVMNonHALocator();
sf = createSessionFactory(locator);
session = sf.createSession(null, null, false, false, true, false, 0);
producer = session.createProducer(PagingTest.ADDRESS);
for (int i = 0; i < 10; i++) {
message = session.createMessage(true);
ActiveMQBuffer bodyLocal = message.getBodyBuffer();
bodyLocal.writeBytes(new byte[100 * 4]);
message.putIntProperty(new SimpleString("newid"), i);
producer.send(message);
session.commit();
if (i == 5) {
queue.getPageSubscription().getPagingStore().forceAnotherPage();
}
}
mainCleanup.set(true);
queue = server.locateQueue(ADDRESS);
queue.getPageSubscription().cleanupEntries(false);
queue.getPageSubscription().getPagingStore().getCursorProvider().cleanup();
ClientConsumer consumer = session.createConsumer(ADDRESS);
session.start();
for (int i = 0; i < 10; i++) {
message = consumer.receive(5000);
Assert.assertNotNull(message);
Assert.assertEquals(i, message.getIntProperty("newid").intValue());
message.acknowledge();
}
server.stop();
// Thread.sleep(5000);
}
use of org.apache.activemq.artemis.utils.actors.ArtemisExecutor in project activemq-artemis by apache.
the class JournalTptBenchmark method main.
public static void main(String[] args) throws Exception {
final boolean useDefaultIoExecutor = true;
final int fileSize = 10 * 1024 * 1024;
final boolean dataSync = false;
final Type type = Type.Mapped;
final int tests = 10;
final int warmup = 20_000;
final int measurements = 100_000;
final int msgSize = 100;
final byte[] msgContent = new byte[msgSize];
Arrays.fill(msgContent, (byte) 1);
final int totalMessages = (measurements * tests + warmup);
final File tmpDirectory = new File("./");
// using the default configuration when the broker starts!
final SequentialFileFactory factory;
switch(type) {
case Mapped:
factory = new MappedSequentialFileFactory(tmpDirectory, fileSize, true, ArtemisConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO, ArtemisConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO, null).setDatasync(dataSync);
break;
case Nio:
factory = new NIOSequentialFileFactory(tmpDirectory, true, ArtemisConstants.DEFAULT_JOURNAL_BUFFER_SIZE_NIO, ArtemisConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_NIO, 1, false, null, null).setDatasync(dataSync);
break;
case Aio:
factory = new AIOSequentialFileFactory(tmpDirectory, ArtemisConstants.DEFAULT_JOURNAL_BUFFER_SIZE_AIO, ArtemisConstants.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO, 500, false, null, null).setDatasync(dataSync);
// disable it when using directly the same buffer: ((AIOSequentialFileFactory)factory).disableBufferReuse();
if (!LibaioContext.isLoaded()) {
throw new IllegalStateException("lib AIO not loaded!");
}
break;
default:
throw new AssertionError("unsupported case");
}
int numFiles = (int) (totalMessages * factory.calculateBlockSize(msgSize)) / fileSize;
if (numFiles < 2) {
numFiles = 2;
}
ExecutorService service = null;
final Journal journal;
if (useDefaultIoExecutor) {
journal = new JournalImpl(fileSize, numFiles, numFiles, Integer.MAX_VALUE, 100, factory, "activemq-data", "amq", factory.getMaxIO());
journal.start();
} else {
final ArrayList<MpscArrayQueue<Runnable>> tasks = new ArrayList<>();
service = Executors.newSingleThreadExecutor();
journal = new JournalImpl(() -> new ArtemisExecutor() {
private final MpscArrayQueue<Runnable> taskQueue = new MpscArrayQueue<>(1024);
{
tasks.add(taskQueue);
}
@Override
public void execute(Runnable command) {
while (!taskQueue.offer(command)) {
LockSupport.parkNanos(1L);
}
}
}, fileSize, numFiles, numFiles, Integer.MAX_VALUE, 100, factory, "activemq-data", "amq", factory.getMaxIO(), 0);
journal.start();
service.execute(() -> {
final int size = tasks.size();
final int capacity = 1024;
while (!Thread.currentThread().isInterrupted()) {
for (int i = 0; i < size; i++) {
final MpscArrayQueue<Runnable> runnables = tasks.get(i);
for (int j = 0; j < capacity; j++) {
final Runnable task = runnables.poll();
if (task == null) {
break;
}
try {
task.run();
} catch (Throwable t) {
System.err.println(t);
}
}
}
}
});
}
try {
journal.load(new ArrayList<RecordInfo>(), null, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
try {
final EncodingSupport encodingSupport = new EncodingSupport() {
@Override
public int getEncodeSize() {
return msgSize;
}
@Override
public void encode(ActiveMQBuffer buffer) {
final int writerIndex = buffer.writerIndex();
buffer.setBytes(writerIndex, msgContent);
buffer.writerIndex(writerIndex + msgSize);
}
@Override
public void decode(ActiveMQBuffer buffer) {
}
};
long id = 1;
{
final long elapsed = writeMeasurements(id, journal, encodingSupport, warmup);
id += warmup;
System.out.println("warmup:" + (measurements * 1000_000_000L) / elapsed + " ops/sec");
}
for (int t = 0; t < tests; t++) {
final long elapsed = writeMeasurements(id, journal, encodingSupport, measurements);
System.out.println((measurements * 1000_000_000L) / elapsed + " ops/sec");
id += warmup;
}
} finally {
journal.stop();
if (service != null) {
service.shutdown();
}
final File[] fileToDeletes = tmpDirectory.listFiles();
System.out.println("Files to deletes" + Arrays.toString(fileToDeletes));
Stream.of(fileToDeletes).forEach(File::delete);
}
}
Aggregations