@Test public void testCounter() throws Exception { ClientSessionFactory sf = createSessionFactory(sl); ClientSession session = sf.createSession(); try { Queue queue = server.createQueue(new SimpleString("A1"), new SimpleString("A1"), null, true, false); PageSubscriptionCounter counter = locateCounter(queue); StorageManager storage = server.getStorageManager(); Transaction tx = new TransactionImpl(server.getStorageManager()); counter.increment(tx, 1); assertEquals(0, counter.getValue()); tx.commit(); storage.waitOnOperations(); assertEquals(1, counter.getValue()); } finally { sf.close(); session.close(); } }
@Test public void testCleanupCounterNonPersistent() throws Exception { ClientSessionFactory sf = createSessionFactory(sl); ClientSession session = sf.createSession(); try { Queue queue = server.createQueue(new SimpleString("A1"), new SimpleString("A1"), null, true, false); PageSubscriptionCounter counter = locateCounter(queue); ((PageSubscriptionCounterImpl) counter).setPersistent(false); StorageManager storage = server.getStorageManager(); Transaction tx = new TransactionImpl(server.getStorageManager()); for (int i = 0; i < 2100; i++) { counter.increment(tx, 1); if (i % 200 == 0) { tx.commit(); storage.waitOnOperations(); assertEquals(i + 1, counter.getValue()); tx = new TransactionImpl(server.getStorageManager()); } } tx.commit(); storage.waitOnOperations(); assertEquals(2100, counter.getValue()); server.stop(); server = newActiveMQServer(); server.start(); queue = server.locateQueue(new SimpleString("A1")); assertNotNull(queue); counter = locateCounter(queue); assertEquals(0, counter.getValue()); } finally { sf.close(); session.close(); } }
@Test public void testRestartCounter() throws Exception { Queue queue = server.createQueue(new SimpleString("A1"), new SimpleString("A1"), null, true, false); PageSubscriptionCounter counter = locateCounter(queue); StorageManager storage = server.getStorageManager(); Transaction tx = new TransactionImpl(server.getStorageManager()); counter.increment(tx, 1); assertEquals(0, counter.getValue()); tx.commit(); storage.waitOnOperations(); assertEquals(1, counter.getValue()); sl.close(); server.stop(); server = newActiveMQServer(); server.start(); queue = server.locateQueue(new SimpleString("A1")); assertNotNull(queue); counter = locateCounter(queue); assertEquals(1, counter.getValue()); }
@Test public void testPrepareCounter() throws Exception { Xid xid = newXID(); Queue queue = server.createQueue(new SimpleString("A1"), new SimpleString("A1"), null, true, false); PageSubscriptionCounter counter = locateCounter(queue); StorageManager storage = server.getStorageManager(); Transaction tx = new TransactionImpl(xid, server.getStorageManager(), 300); for (int i = 0; i < 2000; i++) { counter.increment(tx, 1); } assertEquals(0, counter.getValue()); tx.prepare(); storage.waitOnOperations(); assertEquals(0, counter.getValue()); server.stop(); server = newActiveMQServer(); server.start(); storage = server.getStorageManager(); queue = server.locateQueue(new SimpleString("A1")); assertNotNull(queue); counter = locateCounter(queue); tx = server.getResourceManager().removeTransaction(xid); assertNotNull(tx); assertEquals(0, counter.getValue()); tx.commit(false); storage.waitOnOperations(); assertEquals(2000, counter.getValue()); }
/** * This method will recover the counters after failures making sure the page counter doesn't get * out of sync * * @param pendingNonTXPageCounter * @throws Exception */ @Override public void recoverPendingPageCounters(List<PageCountPending> pendingNonTXPageCounter) throws Exception { // We need a structure of the following // Address -> PageID -> QueueID -> List<PageCountPending> // The following loop will sort the records according to the hierarchy we need Transaction txRecoverCounter = new TransactionImpl(storageManager); Map<SimpleString, Map<Long, Map<Long, List<PageCountPending>>>> perAddressMap = generateMapsOnPendingCount(queues, pendingNonTXPageCounter, txRecoverCounter); for (SimpleString address : perAddressMap.keySet()) { PagingStore store = pagingManager.getPageStore(address); Map<Long, Map<Long, List<PageCountPending>>> perPageMap = perAddressMap.get(address); // We have already generated this before, so it can't be null assert (perPageMap != null); for (Long pageId : perPageMap.keySet()) { Map<Long, List<PageCountPending>> perQueue = perPageMap.get(pageId); // This can't be true! assert (perQueue != null); if (store.checkPageFileExists(pageId.intValue())) { // on this case we need to recalculate the records Page pg = store.createPage(pageId.intValue()); pg.open(); List<PagedMessage> pgMessages = pg.read(storageManager); Map<Long, AtomicInteger> countsPerQueueOnPage = new HashMap<>(); for (PagedMessage pgd : pgMessages) { if (pgd.getTransactionID() <= 0) { for (long q : pgd.getQueueIDs()) { AtomicInteger countQ = countsPerQueueOnPage.get(q); if (countQ == null) { countQ = new AtomicInteger(0); countsPerQueueOnPage.put(q, countQ); } countQ.incrementAndGet(); } } } for (Map.Entry<Long, List<PageCountPending>> entry : perQueue.entrySet()) { for (PageCountPending record : entry.getValue()) { logger.debug("Deleting pg tempCount " + record.getID()); storageManager.deletePendingPageCounter(txRecoverCounter.getID(), record.getID()); } PageSubscriptionCounter counter = store.getCursorProvider().getSubscription(entry.getKey()).getCounter(); AtomicInteger value = countsPerQueueOnPage.get(entry.getKey()); if (value == null) { logger.debug("Page " + entry.getKey() + " wasn't open, so we will just ignore"); } else { logger.debug("Replacing counter " + value.get()); counter.increment(txRecoverCounter, value.get()); } } } else { // on this case the page file didn't exist, we just remove all the records since the page // is already gone logger.debug( "Page " + pageId + " didn't exist on address " + address + ", so we are just removing records"); for (List<PageCountPending> records : perQueue.values()) { for (PageCountPending record : records) { logger.debug("Removing pending page counter " + record.getID()); storageManager.deletePendingPageCounter(txRecoverCounter.getID(), record.getID()); txRecoverCounter.setContainsPersistent(); } } } } } txRecoverCounter.commit(); }