@Test(timeout = 15000L) public void completeDoesNotHang() throws Exception { WorkQueueProcessor<String> wq = WorkQueueProcessor.create(); wq.subscribe(); Assert.assertTrue(wq.downstreamCount() == 1); wq.onComplete(); while (wq.downstreamCount() != 0 && Thread.activeCount() > 2) { } }
@Test(timeout = 15000L) public void cancelDoesNotHang() throws Exception { WorkQueueProcessor<String> wq = WorkQueueProcessor.create(); Disposable d = wq.subscribe(); Assert.assertTrue(wq.downstreamCount() == 1); d.dispose(); while (wq.downstreamCount() != 0 && Thread.activeCount() > 2) { } }
@Test public void retryErrorPropagatedFromWorkQueueSubscriberCold() throws Exception { AtomicInteger errors = new AtomicInteger(3); WorkQueueProcessor<Integer> wq = WorkQueueProcessor.<Integer>builder().autoCancel(false).build(); AtomicInteger onNextSignals = new AtomicInteger(); wq.onNext(1); wq.onNext(2); wq.onNext(3); wq.onComplete(); StepVerifier.create(wq.log("wq", Level.FINE) .doOnNext(e -> onNextSignals.incrementAndGet()).<Integer>handle( (s1, sink) -> { if (errors.decrementAndGet() > 0) { sink.error(new RuntimeException()); } else { sink.next(s1); } }).retry()) .expectNext(1, 2, 3) .verifyComplete(); assertThat(onNextSignals.get(), equalTo(5)); while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) { } }
@Test public void retryErrorPropagatedFromWorkQueueSubscriberHot() throws Exception { AtomicInteger errors = new AtomicInteger(3); WorkQueueProcessor<Integer> wq = WorkQueueProcessor.<Integer>builder().autoCancel(false).build(); AtomicInteger onNextSignals = new AtomicInteger(); StepVerifier.create(wq.doOnNext(e -> onNextSignals.incrementAndGet()).<Integer>handle( (s1, sink) -> { if (errors.decrementAndGet() > 0) { sink.error(new RuntimeException("expected")); } else { sink.next(s1); } }).retry()) .then(() -> { wq.onNext(1); wq.onNext(2); wq.onNext(3); }) .expectNext(3) .thenCancel() .verify(); assertThat(onNextSignals.get(), equalTo(3)); while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) { } }
while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) {
@Test public void retryErrorPropagatedFromWorkQueueSubscriberHotPoisonSignal() throws Exception { WorkQueueProcessor<Integer> wq = WorkQueueProcessor.<Integer>builder().autoCancel(false).build(); AtomicInteger onNextSignals = new AtomicInteger(); StepVerifier.create(wq.doOnNext(e -> onNextSignals.incrementAndGet()).<Integer>handle( (s1, sink) -> { if (s1 == 1) { sink.error(new RuntimeException()); } else { sink.next(s1); } }).retry()) .then(() -> { wq.onNext(1); wq.onNext(2); wq.onNext(3); }) .expectNext(2, 3) .thenCancel() .verify(); assertThat(onNextSignals.get(), equalTo(3)); while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) { } }
while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) {
@Test public void retryErrorPropagatedFromWorkQueueSubscriberHotPoisonSignal2() throws Exception { WorkQueueProcessor<Integer> wq = WorkQueueProcessor.<Integer>builder().autoCancel(false).build(); AtomicInteger onNextSignals = new AtomicInteger(); StepVerifier.create(wq.log() .doOnNext(e -> onNextSignals.incrementAndGet()).<Integer>handle( (s1, sink) -> { if (s1 == 2) { sink.error(new RuntimeException()); } else { sink.next(s1); } }).retry()) .then(() -> { wq.onNext(1); wq.onNext(2); wq.onNext(3); }) .expectNext(1, 3) .thenCancel() .verify(); assertThat(onNextSignals.get(), equalTo(3)); while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) { } }
@Test() public void retryNoThreadLeak() throws Exception { WorkQueueProcessor<Integer> wq = WorkQueueProcessor.<Integer>builder().autoCancel(false).build(); wq.handle((integer, sink) -> sink.error(new RuntimeException())) .retry(10) .subscribe(); wq.onNext(1); wq.onNext(2); wq.onNext(3); wq.onComplete(); while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) { } }
@Test(timeout = 15000L) public void disposeSubscribeNoThreadLeak() throws Exception { WorkQueueProcessor<String> wq = WorkQueueProcessor.<String>builder().autoCancel(false).build(); Disposable d = wq.subscribe(); d.dispose(); d = wq.subscribe(); d.dispose(); d = wq.subscribe(); d.dispose(); while (wq.downstreamCount() != 0 && Thread.activeCount() > 2) { } }
while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) {
while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) {
while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) {
while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) {
while (wq.downstreamCount() != 0 && Thread.activeCount() > 1) {