@Test public void testProcessorRetriesOnTransientExceptionWhenLoadingToken() throws Exception { CountDownLatch countDownLatch = new CountDownLatch(1); doAnswer(invocation -> { countDownLatch.countDown(); return null; }).when(mockHandler).handle(any()); when(tokenStore.fetchToken("test", 0)).thenThrow(new RuntimeException("Faking a recoverable issue")) .thenCallRealMethod(); testSubject.start(); // give it a bit of time to start Thread.sleep(200); eventBus.publish(createEvent()); assertTrue("Expected Handler to have received published event", countDownLatch.await(5, TimeUnit.SECONDS)); assertTrue(testSubject.isRunning()); assertFalse(testSubject.isError()); assertEquals(Collections.singletonList(5000L), sleepInstructions); }
@Test public void testProcessorStopsOnNonTransientExceptionWhenLoadingToken() { when(tokenStore.fetchToken("test", 0)).thenThrow(new SerializationException("Faking a serialization issue")); testSubject.start(); assertWithin( 1, TimeUnit.SECONDS, () -> assertFalse("Expected processor to have stopped", testSubject.isRunning()) ); assertWithin( 1, TimeUnit.SECONDS, () -> assertTrue("Expected processor to set the error flag", testSubject.isError()) ); assertEquals(Collections.emptyList(), sleepInstructions); }
.setActiveThreads(processor.activeProcessorThreads()) .setAvailableThreads(processor.availableProcessorThreads()) .setRunning(processor.isRunning()) .setError(processor.isError()) .addAllEventTrackersInfo(trackers)
/** * Resets tokens to the given {@code startPosition}. This effectively causes a replay of events since that position. * <p> * Note that the new token must represent a position that is <em>before</em> the current position of the processor. * <p> * Before attempting to reset the tokens, the caller must stop this processor, as well as any instances of the * same logical processor that may be running in the cluster. Failure to do so will cause the reset to fail, * as a processor can only reset the tokens if it is able to claim them all. * * @param startPosition The token representing the position to reset the processor to. */ public void resetTokens(TrackingToken startPosition) { Assert.state(supportsReset(), () -> "The handlers assigned to this Processor do not support a reset"); Assert.state(!isRunning() && activeProcessorThreads() == 0, () -> "TrackingProcessor must be shut down before triggering a reset"); transactionManager.executeInTransaction(() -> { int[] segments = tokenStore.fetchSegments(getName()); TrackingToken[] tokens = new TrackingToken[segments.length]; for (int i = 0; i < segments.length; i++) { tokens[i] = tokenStore.fetchToken(getName(), segments[i]); } // we now have all tokens, hurray eventHandlerInvoker().performReset(); for (int i = 0; i < tokens.length; i++) { tokenStore.storeToken(ReplayToken.createReplayToken(tokens[i], startPosition), getName(), segments[i]); } }); }
.setActiveThreads(processor.activeProcessorThreads()) .setAvailableThreads(processor.availableProcessorThreads()) .setRunning(processor.isRunning()) .setError(processor.isError()) .addAllEventTrackersInfo(trackers)
/** * Resets tokens to the given {@code startPosition}. This effectively causes a replay of events since that position. * <p> * Note that the new token must represent a position that is <em>before</em> the current position of the processor. * <p> * Before attempting to reset the tokens, the caller must stop this processor, as well as any instances of the * same logical processor that may be running in the cluster. Failure to do so will cause the reset to fail, * as a processor can only reset the tokens if it is able to claim them all. * * @param startPosition The token representing the position to reset the processor to. */ public void resetTokens(TrackingToken startPosition) { Assert.state(supportsReset(), () -> "The handlers assigned to this Processor do not support a reset"); Assert.state(!isRunning() && activeProcessorThreads() == 0, () -> "TrackingProcessor must be shut down before triggering a reset"); transactionManager.executeInTransaction(() -> { int[] segments = tokenStore.fetchSegments(getName()); TrackingToken[] tokens = new TrackingToken[segments.length]; for (int i = 0; i < segments.length; i++) { tokens[i] = tokenStore.fetchToken(getName(), segments[i]); } // we now have all tokens, hurray eventHandlerInvoker().performReset(); for (int i = 0; i < tokens.length; i++) { tokenStore.storeToken(ReplayToken.createReplayToken(tokens[i], startPosition), getName(), segments[i]); } }); }
/** * Resets tokens to the given {@code startPosition}. This effectively causes a replay of events since that position. * <p> * Note that the new token must represent a position that is <em>before</em> the current position of the processor. * <p> * Before attempting to reset the tokens, the caller must stop this processor, as well as any instances of the * same logical processor that may be running in the cluster. Failure to do so will cause the reset to fail, * as a processor can only reset the tokens if it is able to claim them all. * * @param startPosition The token representing the position to reset the processor to. */ public void resetTokens(TrackingToken startPosition) { Assert.state(supportsReset(), () -> "The handlers assigned to this Processor do not support a reset"); Assert.state(!isRunning() && activeProcessorThreads() == 0, () -> "TrackingProcessor must be shut down before triggering a reset"); transactionManager.executeInTransaction(() -> { int[] segments = tokenStore.fetchSegments(getName()); TrackingToken[] tokens = new TrackingToken[segments.length]; for (int i = 0; i < segments.length; i++) { tokens[i] = tokenStore.fetchToken(getName(), segments[i]); } // we now have all tokens, hurray eventHandlerInvoker().performReset(); for (int i = 0; i < tokens.length; i++) { tokenStore.storeToken(ReplayToken.createReplayToken(tokens[i], startPosition), getName(), segments[i]); } }); }