@Override public Void inTransaction(final QueueSqlDao<T> transactional, final TransactionStatus status) throws Exception { moveEntryToHistoryFromTransaction(transactional, entry); return null; } });
@Override public Void inTransaction(final QueueSqlDao<T> transactional, final TransactionStatus status) throws Exception { insertEntryFromTransaction(transactional, entry); return null; } });
public DefaultNotificationQueue(final String svcName, final String queueName, final NotificationQueueHandler handler, final DBBackedQueue<NotificationEventModelDao> dao, final NotificationQueueService notificationQueueService, final Clock clock, final NotificationQueueConfig config) { this(svcName, queueName, handler, dao, notificationQueueService, clock, config, QueueObjectMapper.get()); }
@Test(groups = "slow") public void testMultipleWritersMultipleReaders() throws InterruptedException { final PersistentBusConfig config = createConfig(7, 100, 10); queue = new DBBackedQueue<BusEventModelDao>(clock, sqlDao, config, "default-bus_event", metricRegistry); queue.initialize(); final Thread[] readers = new Thread[3]; writers[0] = new Thread(new WriterRunnable(0, 1000, queue)); writers[1] = new Thread(new WriterRunnable(1, 1000, queue)); readers[0] = new Thread(new ReaderRunnable(0, consumed, 2000, queue)); readers[1] = new Thread(new ReaderRunnable(1, consumed, 2000, queue)); readers[2] = new Thread(new ReaderRunnable(2, consumed, 2000, queue)); writers[1].start(); while (queue.isQueueOpenForWrite()) { try { Thread.sleep(10); assertEquals(ready.size(), 0); log.info("Got inflightProcessed = " + queue.getTotalInflightProcessed() + "/1000, inflightWritten = " + queue.getTotalInflightWritten() + "/1000"); assertEquals(queue.getTotalWritten(), 2000);
@Override public void removeNotification(final Long recordId) { final NotificationEventModelDao existing = dao.getSqlDao().getByRecordId(recordId, config.getTableName()); final NotificationEventModelDao removedEntry = new NotificationEventModelDao(existing, Hostname.get(), clock.getUTCNow(), PersistentQueueEntryLifecycleState.REMOVED); dao.moveEntryToHistory(removedEntry); }
@Override public void run() { int remaining = nbToWrite; do { final long search1 = (nbToWrite * writerId) + (remaining - 1); final BusEventModelDao entry = createEntry(new Long(search1)); queue.insertEntry(entry); maybeSleep(); remaining--; } while (remaining > 0); }
private void clearFailedNotification(final NotificationEventModelDao cleared) { NotificationEventModelDao processedEntry = new NotificationEventModelDao(cleared, Hostname.get(), clock.getUTCNow(), PersistentQueueEntryLifecycleState.FAILED); dao.moveEntryToHistory(processedEntry); }
@Override public void start() { if (isStarted.compareAndSet(false, true)) { dao.initialize(); startQueue(); } }
private List<NotificationEventModelDao> getReadyNotifications() { final List<NotificationEventModelDao> input = dao.getReadyEntries(); final List<NotificationEventModelDao> claimedNotifications = new ArrayList<NotificationEventModelDao>(); for (final NotificationEventModelDao cur : input) { // Skip non active queues... final NotificationQueue queue = queues.get(cur.getQueueName()); if (queue == null || !queue.isStarted()) { continue; } claimedNotifications.add(cur); } return claimedNotifications; }
private <T extends NotificationEvent> List<NotificationEventWithMetadata<T>> getFutureNotificationsInternal(final Class<T> typeX, final NotificationSqlDao transactionalDao, final String searchKey, final Long searchKeyValue) { final List<NotificationEventWithMetadata<T>> result = new LinkedList<NotificationEventWithMetadata<T>>(); final List<NotificationEventModelDao> entries = transactionalDao.getReadyQueueEntriesForSearchKey(getFullQName(), searchKeyValue, config.getTableName(), searchKey); for (NotificationEventModelDao cur : entries) { final T event = (T) DefaultQueueLifecycle.deserializeEvent(cur.getClassName(), objectMapper, cur.getEventJson()); final NotificationEventWithMetadata<T> foo = new NotificationEventWithMetadata<T>(cur.getRecordId(), cur.getUserToken(), cur.getCreatedDate(), cur.getSearchKey1(), cur.getSearchKey2(), event, cur.getFutureUserToken(), cur.getEffectiveDate(), cur.getQueueName()); result.add(foo); } return result; }
@Override public <T extends NotificationEvent> List<NotificationEventWithMetadata<T>> getFutureNotificationForSearchKey2(final Class<T> type, final Long searchKey2) { return getFutureNotificationsInternal(type, (NotificationSqlDao) dao.getSqlDao(), "search_key2", searchKey2); }
private void maybeSleep() { while (!queue.isQueueOpenForWrite()) { try { //log.info("Writer " + writerId + "sleeping for until queue becomes open for write"); Thread.sleep(10); } catch (InterruptedException e) { } } } }
@BeforeClass(groups = "slow") public void beforeClass() throws Exception { super.beforeClass(); sqlDao = getDBI().onDemand(PersistentBusSqlDao.class); }
@Test(groups = "slow") public void testWithOneReaderOneWriter() throws InterruptedException { final PersistentBusConfig config = createConfig(7, 100, 10); queue = new DBBackedQueue<BusEventModelDao>(clock, sqlDao, config, "default-bus_event", metricRegistry); queue.initialize(); Thread writer = new Thread(new WriterRunnable(0, 1000, queue)); final AtomicLong consumed = new AtomicLong(0); final ReaderRunnable readerRunnable = new ReaderRunnable(0, consumed, 1000, queue); final Thread reader = new Thread(readerRunnable); while (queue.isQueueOpenForWrite()) { try { Thread.sleep(10); assertEquals(ready.size(), 0); log.info("Got inflightProcessed = " + queue.getTotalInflightProcessed() + "/1000, inflightWritten = " + queue.getTotalInflightWritten() + "/1000"); assertEquals(queue.getTotalWritten(), 1000L); for (Long cur : readerRunnable.getSearch1()) { assertEquals(cur.longValue(), expected); expected--;
private void clearNotification(final NotificationEventModelDao cleared) { NotificationEventModelDao processedEntry = new NotificationEventModelDao(cleared, Hostname.get(), clock.getUTCNow(), PersistentQueueEntryLifecycleState.PROCESSED); dao.moveEntryToHistory(processedEntry); }
@Override public <T extends NotificationEvent> List<NotificationEventWithMetadata<T>> getFutureNotificationForSearchKey1(final Class<T> type, final Long searchKey1) { return getFutureNotificationsInternal(type, (NotificationSqlDao) dao.getSqlDao(), "search_key1", searchKey1); }
@Override public void removeNotificationFromTransaction(final Transmogrifier transmogrifier, final Long recordId) { final NotificationSqlDao transactional = transmogrifier.become(NotificationSqlDao.class); final NotificationEventModelDao existing = transactional.getByRecordId(recordId, config.getTableName()); final NotificationEventModelDao removedEntry = new NotificationEventModelDao(existing, Hostname.get(), clock.getUTCNow(), PersistentQueueEntryLifecycleState.REMOVED); dao.moveEntryToHistoryFromTransaction(transactional, removedEntry); }
public DefaultQueueLifecycle(final String svcQName, final Executor executor, final int nbThreads, final PersistentQueueConfig config) { this(svcQName, executor, nbThreads, config, QueueObjectMapper.get()); }
@Override public int getReadyNotificationEntriesForSearchKey1(Long searchKey1) { return ((NotificationSqlDao) dao.getSqlDao()).getCountReadyEntries(searchKey1, clock.getUTCNow().toDate(), config.getTableName(), "search_key1"); }
@Override public int getReadyNotificationEntriesForSearchKey2(Long searchKey2) { return ((NotificationSqlDao) dao.getSqlDao()).getCountReadyEntries(searchKey2, clock.getUTCNow().toDate(), config.getTableName(), "search_key2"); }