@Test public void testProcessorWorkerCount() { testSubject.start(); // give it some time to split segments from the store and submit to executor service. assertWithin(1, SECONDS, () -> assertThat(testSubject.activeProcessorThreads(), is(2))); assertThat(testSubject.processingStatus().size(), is(2)); assertTrue(testSubject.processingStatus().containsKey(0)); assertTrue(testSubject.processingStatus().containsKey(1)); assertWithin(1, SECONDS, () -> assertTrue(testSubject.processingStatus().get(0).isCaughtUp())); assertWithin(1, SECONDS, () -> assertTrue(testSubject.processingStatus().get(1).isCaughtUp())); }
@Test public void testBlacklistingSegmentWillHaveProcessorClaimAnotherOne() { tokenStore.storeToken(new GlobalSequenceTrackingToken(1L), "test", 0); tokenStore.storeToken(new GlobalSequenceTrackingToken(2L), "test", 1); tokenStore.storeToken(new GlobalSequenceTrackingToken(2L), "test", 2); testSubject.start(); assertWithin(1, SECONDS, () -> assertEquals(0, testSubject.availableProcessorThreads())); assertEquals(new HashSet<>(asList(0, 1)), testSubject.processingStatus().keySet()); testSubject.releaseSegment(0); assertWithin(5, SECONDS, () -> assertTrue(testSubject.processingStatus().containsKey(2))); assertEquals(new HashSet<>(asList(2, 1)), testSubject.processingStatus().keySet()); assertWithin(2, SECONDS, () -> assertEquals(0, testSubject.availableProcessorThreads())); }
@Test public void testProcessorWorkerCountWithMultipleSegments() { tokenStore.storeToken(new GlobalSequenceTrackingToken(1L), "test", 0); tokenStore.storeToken(new GlobalSequenceTrackingToken(2L), "test", 1); testSubject.start(); assertWithin(20, SECONDS, () -> assertThat(testSubject.activeProcessorThreads(), is(2))); assertThat(testSubject.processingStatus().size(), is(2)); assertTrue(testSubject.processingStatus().containsKey(0)); assertTrue(testSubject.processingStatus().containsKey(1)); assertWithin( 10, MILLISECONDS, () -> assertEquals(new GlobalSequenceTrackingToken(1L), testSubject.processingStatus().get(0).getTrackingToken()) ); assertWithin( 10, MILLISECONDS, () -> assertEquals(new GlobalSequenceTrackingToken(2L), testSubject.processingStatus().get(1).getTrackingToken()) ); }
@Test public void testResetToPositionCausesCertainEventsToBeReplayed() throws Exception { when(mockHandler.supportsReset()).thenReturn(true); final List<String> handled = new CopyOnWriteArrayList<>(); final List<String> handledInRedelivery = new CopyOnWriteArrayList<>(); //noinspection Duplicates doAnswer(i -> { EventMessage message = i.getArgument(0); handled.add(message.getIdentifier()); if (ReplayToken.isReplay(message)) { handledInRedelivery.add(message.getIdentifier()); } return null; }).when(mockHandler).handle(any()); eventBus.publish(createEvents(4)); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(4, handled.size())); testSubject.shutDown(); testSubject.resetTokens(source -> new GlobalSequenceTrackingToken(1L)); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(6, handled.size())); assertFalse(handledInRedelivery.contains(handled.get(0))); assertFalse(handledInRedelivery.contains(handled.get(1))); assertEquals(handled.subList(2, 4), handled.subList(4, 6)); assertEquals(handled.subList(4, 6), handledInRedelivery); assertTrue(testSubject.processingStatus().get(0).isReplaying()); eventBus.publish(createEvents(1)); assertWithin(1, TimeUnit.SECONDS, () -> assertFalse(testSubject.processingStatus().get(0).isReplaying())); }
@Override public PlatformInboundInstruction instruction() { Map<Integer, EventTrackerStatus> statusMap = processor.processingStatus();
@Test public void testResetBeforeStartingPerformsANormalRun() throws Exception { when(mockHandler.supportsReset()).thenReturn(true); final List<String> handled = new CopyOnWriteArrayList<>(); final List<String> handledInRedelivery = new CopyOnWriteArrayList<>(); //noinspection Duplicates doAnswer(i -> { EventMessage message = i.getArgument(0); handled.add(message.getIdentifier()); if (ReplayToken.isReplay(message)) { handledInRedelivery.add(message.getIdentifier()); } return null; }).when(mockHandler).handle(any()); testSubject.start(); testSubject.shutDown(); testSubject.resetTokens(); testSubject.start(); eventBus.publish(createEvents(4)); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(4, handled.size())); assertEquals(0, handledInRedelivery.size()); assertFalse(testSubject.processingStatus().get(0).isReplaying()); }
@Test public void testUpdateActiveSegmentsWhenBatchIsEmpty() throws Exception { StreamableMessageSource<TrackedEventMessage<?>> stubSource = mock(StreamableMessageSource.class); testSubject = TrackingEventProcessor.builder() .name("test") .eventHandlerInvoker(eventHandlerInvoker) .messageSource(stubSource) .tokenStore(tokenStore) .transactionManager(NoTransactionManager.INSTANCE).build(); when(stubSource.openStream(any())).thenReturn(new StubTrackingEventStream(0, 1, 2, 5)); doReturn(true, false).when(eventHandlerInvoker).canHandle(any(), any()); List<TrackingToken> trackingTokens = new CopyOnWriteArrayList<>(); doAnswer(i -> { trackingTokens.add(i.<TrackedEventMessage>getArgument(0).trackingToken()); return null; }).when(eventHandlerInvoker).handle(any(), any()); testSubject.start(); // give it a bit of time to start Thread.sleep(200); EventTrackerStatus eventTrackerStatus = testSubject.processingStatus().get(0); assertTrue(eventTrackerStatus.isCaughtUp()); GapAwareTrackingToken expectedToken = GapAwareTrackingToken.newInstance(5, asList(3L, 4L)); TrackingToken lastToken = eventTrackerStatus.getTrackingToken(); assertTrue(lastToken.covers(expectedToken)); }
@Test public void testResetCausesEventsToBeReplayed() throws Exception { when(mockHandler.supportsReset()).thenReturn(true); final List<String> handled = new CopyOnWriteArrayList<>(); final List<String> handledInRedelivery = new CopyOnWriteArrayList<>(); //noinspection Duplicates doAnswer(i -> { EventMessage message = i.getArgument(0); handled.add(message.getIdentifier()); if (ReplayToken.isReplay(message)) { handledInRedelivery.add(message.getIdentifier()); } return null; }).when(mockHandler).handle(any()); eventBus.publish(createEvents(4)); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(4, handled.size())); testSubject.shutDown(); testSubject.resetTokens(); // Resetting twice caused problems (see issue #559) testSubject.resetTokens(); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(8, handled.size())); assertEquals(handled.subList(0, 4), handled.subList(4, 8)); assertEquals(handled.subList(4, 8), handledInRedelivery); assertTrue(testSubject.processingStatus().get(0).isReplaying()); eventBus.publish(createEvents(1)); assertWithin(1, TimeUnit.SECONDS, () -> assertFalse(testSubject.processingStatus().get(0).isReplaying())); }
assertEquals(handled.subList(0, 2), handled.subList(2, 4)); assertEquals(handled.subList(2, 4), handledInRedelivery); assertTrue(testSubject.processingStatus().get(0).isReplaying()); eventBus.publish(createEvents(1)); assertWithin(1, TimeUnit.SECONDS, () -> assertFalse(testSubject.processingStatus().get(0).isReplaying()));
@Override public PlatformInboundInstruction instruction() { Map<Integer, EventTrackerStatus> statusMap = processor.processingStatus();