use of reactor.core.Disposable in project reactor-core by reactor.
the class BoundedElasticSchedulerTest method taskPutInPendingQueueCanBeRemovedOnCancel.
@Test
public void taskPutInPendingQueueCanBeRemovedOnCancel() throws InterruptedException {
BoundedElasticScheduler boundedElasticScheduler = afterTest.autoDispose(new BoundedElasticScheduler(1, 1, Thread::new, 10));
boundedElasticScheduler.start();
Worker worker = afterTest.autoDispose(boundedElasticScheduler.createWorker());
AtomicBoolean ranTask = new AtomicBoolean();
CountDownLatch latch = new CountDownLatch(1);
// block worker
worker.schedule(() -> {
try {
latch.await(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// small window to start the first task
Thread.sleep(10);
// enqueue task on worker
Disposable task = worker.schedule(() -> ranTask.set(true));
assertThat(ranTask).as("is pending execution").isFalse();
Awaitility.with().pollInterval(50, TimeUnit.MILLISECONDS).await().atMost(100, TimeUnit.MILLISECONDS).untilAsserted(() -> assertThat(boundedElasticScheduler.estimateRemainingTaskCapacity()).as("queue full").isZero());
task.dispose();
Awaitility.with().pollInterval(50, TimeUnit.MILLISECONDS).await().atMost(100, TimeUnit.MILLISECONDS).untilAsserted(() -> assertThat(boundedElasticScheduler.estimateRemainingTaskCapacity()).as("queue cleared").isOne());
latch.countDown();
Thread.sleep(100);
assertThat(ranTask).as("not executed after latch countdown").isFalse();
}
use of reactor.core.Disposable in project reactor-core by reactor.
the class BoundedElasticSchedulerTest method testGh1973.
// gh-1973 smoke test
@Test
@Tag("slow")
public void testGh1973() throws InterruptedException {
Scheduler scheduler = afterTest.autoDispose(Schedulers.newBoundedElastic(3, 100000, "subscriberElastic", 600, true));
LinkedList<MonoSink<String>> listeners = new LinkedList<>();
List<Disposable> scheduled = new LinkedList<>();
ExecutorService producer = startProducer(listeners);
Consumer<MonoSink<String>> addListener = sink -> {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
LOGGER.trace("listener cancelled");
}
listeners.add(sink);
sink.onDispose(() -> listeners.remove(sink));
};
for (int i = 0; i < 50; i++) {
scheduled.add(Mono.create(addListener).subscribeOn(scheduler).subscribe(LOGGER::info));
}
Thread.sleep(1000);
scheduled.forEach(Disposable::dispose);
Thread.sleep(1000);
Mono.<String>create(sink -> {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
LOGGER.warn("last listener improperly cancelled");
}
listeners.add(sink);
sink.onDispose(() -> listeners.remove(sink));
}).subscribeOn(scheduler).map(res -> res + " the end").doOnNext(LOGGER::info).as(StepVerifier::create).assertNext(n -> assertThat(n).endsWith(" the end")).expectComplete().verify(Duration.ofSeconds(5));
}
use of reactor.core.Disposable in project reactor-core by reactor.
the class FluxTests method shouldCorrectlyDispatchComplexFlow.
@Test
public void shouldCorrectlyDispatchComplexFlow() throws InterruptedException {
Sinks.Many<Integer> globalFeed = Sinks.many().multicast().onBackpressureBuffer();
CountDownLatch afterSubscribe = new CountDownLatch(1);
CountDownLatch latch = new CountDownLatch(4);
Flux<Integer> s = Flux.just("2222").map(Integer::parseInt).flatMap(l -> Flux.merge(globalFeed.asFlux().publishOn(asyncGroup), Flux.just(1111, l, 3333, 4444, 5555, 6666)).log("merged").publishOn(asyncGroup).log("dispatched").doOnSubscribe(x -> afterSubscribe.countDown()).filter(nearbyLoc -> 3333 >= nearbyLoc).filter(nearbyLoc -> 2222 <= nearbyLoc));
/*Disposable action = */
s.limitRate(1).subscribe(integer -> {
latch.countDown();
System.out.println(integer);
});
afterSubscribe.await(5, TimeUnit.SECONDS);
globalFeed.emitNext(2223, FAIL_FAST);
globalFeed.emitNext(2224, FAIL_FAST);
latch.await(5, TimeUnit.SECONDS);
assertThat(latch.getCount()).as("latch count").isEqualTo(0);
}
use of reactor.core.Disposable in project reactor-core by reactor.
the class AbstractSchedulerTest method directScheduleAndDisposePeriod.
@Test
@Timeout(10)
public final void directScheduleAndDisposePeriod() throws Exception {
Scheduler s = schedulerNotCached();
try {
assertThat(s.isDisposed()).isFalse();
if (!shouldCheckDirectTimeScheduling()) {
assertThatExceptionOfType(RejectedExecutionException.class).isThrownBy(() -> s.schedule(() -> {
}, 10, TimeUnit.MILLISECONDS)).as("Scheduler marked as not supporting time scheduling").isSameAs(Exceptions.failWithRejectedNotTimeCapable());
return;
}
CountDownLatch latch = new CountDownLatch(2);
CountDownLatch latch2 = new CountDownLatch(1);
Disposable d = s.schedulePeriodically(() -> {
try {
latch.countDown();
if (latch.getCount() == 0) {
latch2.await(10, TimeUnit.SECONDS);
}
} catch (InterruptedException e) {
}
}, 10, 10, TimeUnit.MILLISECONDS);
// will throw if rejected
assertThat(d.isDisposed()).isFalse();
latch.await();
d.dispose();
Thread.yield();
latch2.countDown();
s.dispose();
assertThat(s.isDisposed()).isTrue();
assertThatExceptionOfType(RejectedExecutionException.class).isThrownBy(() -> s.schedule(() -> {
}));
} finally {
s.dispose();
}
}
use of reactor.core.Disposable in project reactor-core by reactor.
the class AbstractSchedulerTest method directScheduleAndDispose.
@Test
@Timeout(10)
public final void directScheduleAndDispose() throws Exception {
Scheduler s = schedulerNotCached();
try {
assertThat(s.isDisposed()).isFalse();
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch latch2 = shouldCheckDisposeTask() ? new CountDownLatch(1) : null;
try {
Disposable d = s.schedule(() -> {
try {
latch.countDown();
if (latch2 != null && !latch2.await(10, TimeUnit.SECONDS) && shouldCheckInterrupted()) {
fail("Should have interrupted");
}
} catch (InterruptedException e) {
}
});
latch.await();
if (shouldCheckDisposeTask()) {
assertThat(d.isDisposed()).isFalse();
} else {
// noop
d.isDisposed();
}
d.dispose();
// noop
d.dispose();
} catch (Throwable schedulingError) {
fail("unexpected scheduling error", schedulingError);
}
Thread.yield();
if (latch2 != null) {
latch2.countDown();
}
s.dispose();
// noop
s.dispose();
if (s == ImmediateScheduler.instance()) {
return;
}
assertThat(s.isDisposed()).isTrue();
try {
Disposable d = s.schedule(() -> {
if (shouldCheckInterrupted()) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
d.dispose();
assertThat(d.isDisposed()).isTrue();
} catch (Throwable schedulingError) {
assertThat(schedulingError).isInstanceOf(RejectedExecutionException.class);
}
} finally {
s.dispose();
// noop
s.dispose();
}
}
Aggregations