use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.
the class ScaleDownHandler method scaleDownRegularMessages.
public long scaleDownRegularMessages(final SimpleString address, final Set<Queue> queues, final ClientSession clientSession, final ClientProducer producer) throws Exception {
logger.debug("Scaling down messages on address " + address);
long messageCount = 0;
final HashMap<Queue, QueuesXRefInnerManager> controls = new HashMap<>();
PagingStore pageStore = pagingManager.getPageStore(address);
Transaction tx = new TransactionImpl(storageManager);
pageStore.disableCleanup();
try {
for (Queue queue : queues) {
controls.put(queue, new QueuesXRefInnerManager(clientSession, queue, pageStore));
}
// compile a list of all the relevant queues and queue iterators for this address
for (Queue loopQueue : queues) {
logger.debug("Scaling down messages on address " + address + " / performing loop on queue " + loopQueue);
try (LinkedListIterator<MessageReference> messagesIterator = loopQueue.browserIterator()) {
while (messagesIterator.hasNext()) {
MessageReference messageReference = messagesIterator.next();
Message message = messageReference.getMessage().copy();
logger.debug("Reading message " + message + " from queue " + loopQueue);
Set<QueuesXRefInnerManager> queuesFound = new HashSet<>();
for (Map.Entry<Queue, QueuesXRefInnerManager> controlEntry : controls.entrySet()) {
if (controlEntry.getKey() == loopQueue) {
// no need to lookup on itself, we just add it
queuesFound.add(controlEntry.getValue());
} else if (controlEntry.getValue().lookup(messageReference)) {
logger.debug("Message existed on queue " + controlEntry.getKey().getID() + " removeID=" + controlEntry.getValue().getQueueID());
queuesFound.add(controlEntry.getValue());
}
}
// get the ID for every queue that contains the message
ByteBuffer buffer = ByteBuffer.allocate(queuesFound.size() * 8);
for (QueuesXRefInnerManager control : queuesFound) {
long queueID = control.getQueueID();
buffer.putLong(queueID);
}
message.putBytesProperty(Message.HDR_ROUTE_TO_IDS.toString(), buffer.array());
if (logger.isDebugEnabled()) {
if (messageReference.isPaged()) {
logger.debug("*********************<<<<< Scaling down pdgmessage " + message);
} else {
logger.debug("*********************<<<<< Scaling down message " + message);
}
}
producer.send(address, message);
messageCount++;
messagesIterator.remove();
// We need to perform the ack / removal after sending, otherwise the message could been removed before the send is finished
for (QueuesXRefInnerManager queueFound : queuesFound) {
ackMessageOnQueue(tx, queueFound.getQueue(), messageReference);
}
}
} catch (NoSuchElementException ignored) {
// this could happen through paging browsing
}
}
tx.commit();
for (QueuesXRefInnerManager controlRemoved : controls.values()) {
controlRemoved.close();
}
return messageCount;
} finally {
pageStore.enableCleanup();
pageStore.getCursorProvider().scheduleCleanup();
}
}
use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.
the class ServerConsumerImpl method individualAcknowledge.
@Override
public synchronized void individualAcknowledge(Transaction tx, final long messageID) throws Exception {
if (browseOnly) {
return;
}
boolean startedTransaction = false;
if (logger.isTraceEnabled()) {
logger.trace("individualACK messageID=" + messageID);
}
if (tx == null) {
if (logger.isTraceEnabled()) {
logger.trace("individualACK starting new TX");
}
startedTransaction = true;
tx = new TransactionImpl(storageManager);
}
try {
MessageReference ref;
ref = removeReferenceByID(messageID);
if (logger.isTraceEnabled()) {
logger.trace("ACKing ref " + ref + " on tx= " + tx + ", consumer=" + this);
}
if (ref == null) {
ActiveMQIllegalStateException ils = new ActiveMQIllegalStateException("Cannot find ref to ack " + messageID);
tx.markAsRollbackOnly(ils);
throw ils;
}
ref.acknowledge(tx);
acks++;
if (startedTransaction) {
tx.commit();
}
} catch (ActiveMQException e) {
if (startedTransaction) {
tx.rollback();
} else {
tx.markAsRollbackOnly(e);
}
throw e;
} catch (Throwable e) {
ActiveMQServerLogger.LOGGER.errorAckingMessage((Exception) e);
ActiveMQIllegalStateException hqex = new ActiveMQIllegalStateException(e.getMessage());
if (startedTransaction) {
tx.rollback();
} else {
tx.markAsRollbackOnly(hqex);
}
throw hqex;
}
}
use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.
the class RefsOperation method afterRollback.
@Override
public void afterRollback(final Transaction tx) {
Map<QueueImpl, LinkedList<MessageReference>> queueMap = new HashMap<>();
long timeBase = System.currentTimeMillis();
// add any already acked refs, this means that they have been transferred via a producer.send() and have no
// previous state persisted.
List<MessageReference> ackedRefs = new ArrayList<>();
for (MessageReference ref : refsToAck) {
ref.emptyConsumerID();
if (logger.isTraceEnabled()) {
logger.trace("rolling back " + ref);
}
try {
if (ref.isAlreadyAcked()) {
ackedRefs.add(ref);
}
rollbackRedelivery(tx, ref, timeBase, queueMap);
} catch (Exception e) {
ActiveMQServerLogger.LOGGER.errorCheckingDLQ(e);
}
}
for (Map.Entry<QueueImpl, LinkedList<MessageReference>> entry : queueMap.entrySet()) {
LinkedList<MessageReference> refs = entry.getValue();
QueueImpl queue = entry.getKey();
synchronized (queue) {
queue.postRollback(refs);
}
}
if (!ackedRefs.isEmpty()) {
// message references
try {
Transaction ackedTX = new TransactionImpl(storageManager);
for (MessageReference ref : ackedRefs) {
Message message = ref.getMessage();
if (message.isDurable()) {
int durableRefCount = message.incrementDurableRefCount();
if (durableRefCount == 1) {
storageManager.storeMessageTransactional(ackedTX.getID(), message);
}
Queue queue = ref.getQueue();
storageManager.storeReferenceTransactional(ackedTX.getID(), queue.getID(), message.getMessageID());
ackedTX.setContainsPersistent();
}
message.incrementRefCount();
}
ackedTX.commit(true);
} catch (Exception e) {
ActiveMQServerLogger.LOGGER.failedToProcessMessageReferenceAfterRollback(e);
}
}
}
use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.
the class PagingCounterTest method testCleanupCounter.
@Test
public void testCleanupCounter() throws Exception {
ClientSessionFactory sf = createSessionFactory(sl);
ClientSession session = sf.createSession();
try {
server.addAddressInfo(new AddressInfo(new SimpleString("A1"), RoutingType.ANYCAST));
Queue queue = server.createQueue(new SimpleString("A1"), RoutingType.ANYCAST, new SimpleString("A1"), null, true, false);
PageSubscriptionCounter counter = locateCounter(queue);
StorageManager storage = server.getStorageManager();
Transaction tx = new TransactionImpl(server.getStorageManager());
for (int i = 0; i < 2100; i++) {
counter.increment(tx, 1, 1000);
if (i % 200 == 0) {
tx.commit();
storage.waitOnOperations();
assertEquals(i + 1, counter.getValue());
assertEquals((i + 1) * 1000, counter.getPersistentSize());
tx = new TransactionImpl(server.getStorageManager());
}
}
tx.commit();
storage.waitOnOperations();
assertEquals(2100, counter.getValue());
assertEquals(2100 * 1000, counter.getPersistentSize());
server.stop();
server = newActiveMQServer();
server.start();
queue = server.locateQueue(new SimpleString("A1"));
assertNotNull(queue);
counter = locateCounter(queue);
assertEquals(2100, counter.getValue());
assertEquals(2100 * 1000, counter.getPersistentSize());
} finally {
sf.close();
session.close();
}
}
use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.
the class PagingCounterTest method testRestartCounter.
@Test
public void testRestartCounter() throws Exception {
server.addAddressInfo(new AddressInfo(new SimpleString("A1"), RoutingType.ANYCAST));
Queue queue = server.createQueue(new SimpleString("A1"), RoutingType.ANYCAST, new SimpleString("A1"), null, true, false);
PageSubscriptionCounter counter = locateCounter(queue);
StorageManager storage = server.getStorageManager();
Transaction tx = new TransactionImpl(server.getStorageManager());
counter.increment(tx, 1, 1000);
assertEquals(0, counter.getValue());
assertEquals(0, counter.getPersistentSize());
tx.commit();
storage.waitOnOperations();
assertEquals(1, counter.getValue());
assertEquals(1000, counter.getPersistentSize());
sl.close();
server.stop();
server = newActiveMQServer();
server.start();
queue = server.locateQueue(new SimpleString("A1"));
assertNotNull(queue);
counter = locateCounter(queue);
assertEquals(1, counter.getValue());
assertEquals(1000, counter.getPersistentSize());
}
Aggregations