public void cleanup() { ArrayList<Page> depagedPages = new ArrayList<Page>(); while (true) { if (pagingStore.lock(100)) { break; } if (!pagingStore.isStarted()) return; } synchronized (this) { try { if (!pagingStore.isStarted()) { return; } if (pagingStore.getNumberOfPages() == 0) { return; } if (log.isDebugEnabled()) { log.debug("Asserting cleanup for address " + this.pagingStore.getAddress()); } ArrayList<PageSubscription> cursorList = new ArrayList<PageSubscription>(); cursorList.addAll(activeCursors.values()); long minPage = checkMinPage(cursorList); if (minPage == pagingStore.getCurrentWritingPage() && pagingStore.getCurrentPage().getNumberOfMessages() > 0) { boolean complete = true; for (PageSubscription cursor : cursorList) { if (!cursor.isComplete(minPage)) { if (log.isDebugEnabled()) { log.debug("Cursor " + cursor + " was considered incomplete at page " + minPage); } complete = false; break; } else { if (log.isDebugEnabled()) { log.debug("Cursor " + cursor + "was considered **complete** at page " + minPage); } } } if (!pagingStore.isStarted()) { return; } if (complete) { if (log.isDebugEnabled()) { log.debug( "Address " + pagingStore.getAddress() + " is leaving page mode as all messages are consumed and acknowledged from the page store"); } pagingStore.forceAnotherPage(); Page currentPage = pagingStore.getCurrentPage(); storePositions(cursorList, currentPage); pagingStore.stopPaging(); // This has to be called after we stopped paging for (PageSubscription cursor : cursorList) { cursor.scheduleCleanupCheck(); } } } for (long i = pagingStore.getFirstPage(); i < minPage; i++) { Page page = pagingStore.depage(); if (page == null) { break; } depagedPages.add(page); } if (pagingStore.getNumberOfPages() == 0 || pagingStore.getNumberOfPages() == 1 && pagingStore.getCurrentPage().getNumberOfMessages() == 0) { pagingStore.stopPaging(); } else { if (log.isTraceEnabled()) { log.trace( "Couldn't cleanup page on address " + this.pagingStore.getAddress() + " as numberOfPages == " + pagingStore.getNumberOfPages() + " and currentPage.numberOfMessages = " + pagingStore.getCurrentPage().getNumberOfMessages()); } } } catch (Exception ex) { log.warn("Couldn't complete cleanup on paging", ex); return; } finally { pagingStore.unlock(); } } try { for (Page depagedPage : depagedPages) { PageCache cache; PagedMessage[] pgdMessages; synchronized (softCache) { cache = softCache.get((long) depagedPage.getPageId()); } if (isTrace) { log.trace("Removing page " + depagedPage.getPageId() + " from page-cache"); } if (cache == null) { // The page is not on cache any more // We need to read the page-file before deleting it // to make sure we remove any large-messages pending storageManager.beforePageRead(); List<PagedMessage> pgdMessagesList = null; try { depagedPage.open(); pgdMessagesList = depagedPage.read(storageManager); } finally { try { depagedPage.close(); } catch (Exception e) { } storageManager.afterPageRead(); } depagedPage.close(); pgdMessages = pgdMessagesList.toArray(new PagedMessage[pgdMessagesList.size()]); } else { pgdMessages = cache.getMessages(); } depagedPage.delete(pgdMessages); synchronized (softCache) { softCache.remove((long) depagedPage.getPageId()); } } } catch (Exception ex) { log.warn("Couldn't complete cleanup on paging", ex); return; } }
@Test public void testSendPackets() throws Exception { setupServer(true); StorageManager storage = getStorage(); manager = liveServer.getReplicationManager(); waitForComponent(manager); Journal replicatedJournal = new ReplicatedJournal((byte) 1, new FakeJournal(), manager); replicatedJournal.appendPrepareRecord(1, new FakeData(), false); replicatedJournal.appendAddRecord(1, (byte) 1, new FakeData(), false); replicatedJournal.appendUpdateRecord(1, (byte) 2, new FakeData(), false); replicatedJournal.appendDeleteRecord(1, false); replicatedJournal.appendAddRecordTransactional(2, 2, (byte) 1, new FakeData()); replicatedJournal.appendUpdateRecordTransactional(2, 2, (byte) 2, new FakeData()); replicatedJournal.appendCommitRecord(2, false); replicatedJournal.appendDeleteRecordTransactional(3, 4, new FakeData()); replicatedJournal.appendPrepareRecord(3, new FakeData(), false); replicatedJournal.appendRollbackRecord(3, false); blockOnReplication(storage, manager); Assert.assertTrue( "Expecting no active tokens:" + manager.getActiveTokens(), manager.getActiveTokens().isEmpty()); ServerMessage msg = new ServerMessageImpl(1, 1024); SimpleString dummy = new SimpleString("dummy"); msg.setAddress(dummy); replicatedJournal.appendAddRecordTransactional(23, 24, (byte) 1, new FakeData()); PagedMessage pgmsg = new PagedMessageImpl(msg, new long[0]); manager.pageWrite(pgmsg, 1); manager.pageWrite(pgmsg, 2); manager.pageWrite(pgmsg, 3); manager.pageWrite(pgmsg, 4); blockOnReplication(storage, manager); PagingManager pagingManager = createPageManager( backupServer.getStorageManager(), backupServer.getConfiguration(), backupServer.getExecutorFactory(), backupServer.getAddressSettingsRepository()); PagingStore store = pagingManager.getPageStore(dummy); store.start(); Assert.assertEquals(4, store.getNumberOfPages()); store.stop(); manager.pageDeleted(dummy, 1); manager.pageDeleted(dummy, 2); manager.pageDeleted(dummy, 3); manager.pageDeleted(dummy, 4); manager.pageDeleted(dummy, 5); manager.pageDeleted(dummy, 6); blockOnReplication(storage, manager); ServerMessageImpl serverMsg = new ServerMessageImpl(); serverMsg.setMessageID(500); serverMsg.setAddress(new SimpleString("tttt")); HornetQBuffer buffer = HornetQBuffers.dynamicBuffer(100); serverMsg.encodeHeadersAndProperties(buffer); manager.largeMessageBegin(500); manager.largeMessageWrite(500, new byte[1024]); manager.largeMessageDelete(Long.valueOf(500)); blockOnReplication(storage, manager); store.start(); Assert.assertEquals(0, store.getNumberOfPages()); }
public void cleanup() { ArrayList<Page> depagedPages = new ArrayList<Page>(); while (true) { if (pagingStore.lock(100)) { break; } if (!pagingStore.isStarted()) return; } synchronized (this) { try { if (!pagingStore.isStarted()) { return; } if (pagingStore.getNumberOfPages() == 0) { return; } if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug( "Asserting cleanup for address " + this.pagingStore.getAddress()); } ArrayList<PageSubscription> cursorList = cloneSubscriptions(); long minPage = checkMinPage(cursorList); // if the current page is being written... // on that case we need to move to verify it in a different way if (minPage == pagingStore.getCurrentWritingPage() && pagingStore.getCurrentPage().getNumberOfMessages() > 0) { boolean complete = true; for (PageSubscription cursor : cursorList) { if (!cursor.isComplete(minPage)) { if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug( "Cursor " + cursor + " was considered incomplete at page " + minPage); } complete = false; break; } else { if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug( "Cursor " + cursor + "was considered **complete** at page " + minPage); } } } if (!pagingStore.isStarted()) { return; } // All the pages on the cursor are complete.. so we will cleanup everything and store a // bookmark if (complete) { if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug( "Address " + pagingStore.getAddress() + " is leaving page mode as all messages are consumed and acknowledged from the page store"); } pagingStore.forceAnotherPage(); Page currentPage = pagingStore.getCurrentPage(); storeBookmark(cursorList, currentPage); pagingStore.stopPaging(); } } for (long i = pagingStore.getFirstPage(); i < minPage; i++) { Page page = pagingStore.depage(); if (page == null) { break; } depagedPages.add(page); } if (pagingStore.getNumberOfPages() == 0 || pagingStore.getNumberOfPages() == 1 && pagingStore.getCurrentPage().getNumberOfMessages() == 0) { pagingStore.stopPaging(); } else { if (HornetQServerLogger.LOGGER.isTraceEnabled()) { HornetQServerLogger.LOGGER.trace( "Couldn't cleanup page on address " + this.pagingStore.getAddress() + " as numberOfPages == " + pagingStore.getNumberOfPages() + " and currentPage.numberOfMessages = " + pagingStore.getCurrentPage().getNumberOfMessages()); } } } catch (Exception ex) { HornetQServerLogger.LOGGER.problemCleaningPageAddress(ex, pagingStore.getAddress()); return; } finally { pagingStore.unlock(); } } try { for (Page depagedPage : depagedPages) { PageCache cache; PagedMessage[] pgdMessages; synchronized (softCache) { cache = softCache.get((long) depagedPage.getPageId()); } if (isTrace) { HornetQServerLogger.LOGGER.trace( "Removing page " + depagedPage.getPageId() + " from page-cache"); } if (cache == null) { // The page is not on cache any more // We need to read the page-file before deleting it // to make sure we remove any large-messages pending storageManager.beforePageRead(); List<PagedMessage> pgdMessagesList = null; try { depagedPage.open(); pgdMessagesList = depagedPage.read(storageManager); } finally { try { depagedPage.close(); } catch (Exception e) { } storageManager.afterPageRead(); } depagedPage.close(); pgdMessages = pgdMessagesList.toArray(new PagedMessage[pgdMessagesList.size()]); } else { pgdMessages = cache.getMessages(); } depagedPage.delete(pgdMessages); onDeletePage(depagedPage); synchronized (softCache) { softCache.remove((long) depagedPage.getPageId()); } } } catch (Exception ex) { HornetQServerLogger.LOGGER.problemCleaningPageAddress(ex, pagingStore.getAddress()); return; } }