public DefaultEventBus(Scheduler scheduler) { this.bus = TopicProcessor.create(); this.scheduler = scheduler; }
/** * Create a new TopicProcessor using {@link Queues#SMALL_BUFFER_SIZE} backlog size, * blockingWait Strategy and auto-cancel. <p> A new Cached ThreadExecutorPool will be * implicitly created. * @param <E> Type of processed signals * @return a fresh processor */ public static <E> TopicProcessor<E> create() { return TopicProcessor.<E>builder().build(); }
/** * Creates a new {@link TopicProcessor} using the properties * of this builder. * @return a fresh processor */ public TopicProcessor<T> build() { this.name = this.name != null ? this.name : TopicProcessor.class.getSimpleName(); this.waitStrategy = this.waitStrategy != null ? this.waitStrategy : WaitStrategy.phasedOffLiteLock(200, 100, TimeUnit.MILLISECONDS); ThreadFactory threadFactory = this.executor != null ? null : new EventLoopFactory(name, autoCancel); ExecutorService requestTaskExecutor = this.requestTaskExecutor != null ? this.requestTaskExecutor : defaultRequestTaskExecutor(defaultName(threadFactory, TopicProcessor.class)); return new TopicProcessor<>( threadFactory, executor, requestTaskExecutor, bufferSize, waitStrategy, share, autoCancel, signalSupplier); } }
@Test public void scanProcessor() { TopicProcessor<String> test = TopicProcessor.create("name", 16); Subscription subscription = Operators.emptySubscription(); test.onSubscribe(subscription); assertThat(test.scan(Scannable.Attr.PARENT)).isEqualTo(subscription); assertThat(test.scan(Scannable.Attr.CAPACITY)).isEqualTo(16); assertThat(test.scan(Scannable.Attr.TERMINATED)).isFalse(); assertThat(test.scan(Scannable.Attr.ERROR)).isNull(); test.onError(new IllegalStateException("boom")); assertThat(test.scan(Scannable.Attr.ERROR)).hasMessage("boom"); assertThat(test.scan(Scannable.Attr.TERMINATED)).isTrue(); }
Objects.requireNonNull(actual, "subscribe"); if (!alive()) { coldSource(ringBuffer, null, error, minimum).subscribe(actual); return; if (incrementSubscribers()) { decrementSubscribers(); if (!alive() && RejectedExecutionException.class.isAssignableFrom(t.getClass())){ coldSource(ringBuffer, t, error, minimum).subscribe(actual);
@Test public void drainTest() throws Exception { final TopicProcessor<Integer> sink = TopicProcessor.<Integer>builder().name("topic").build(); sink.onNext(1); sink.onNext(2); sink.onNext(3); sink.forceShutdown() .subscribeWith(AssertSubscriber.create()) .assertComplete() .assertValues(1, 2, 3); }
@Test public void testForceShutdownAfterShutdown() throws InterruptedException { TopicProcessor<String> processor = TopicProcessor.<String>builder().name("processor").bufferSize(4).build(); Publisher<String> publisher = Flux.fromArray(new String[] { "1", "2", "3", "4", "5" }); publisher.subscribe(processor); AssertSubscriber<String> subscriber = AssertSubscriber.create(0); processor.subscribe(subscriber); subscriber.request(1); Thread.sleep(250); processor.shutdown(); assertFalse(processor.awaitAndShutdown(Duration.ofMillis(400))); processor.forceShutdown(); assertTrue(processor.awaitAndShutdown(Duration.ofMillis(400))); }
@Test public void konamiCode() throws InterruptedException { final TopicProcessor<Integer> keyboardStream = TopicProcessor.create(); .skipWhile(key -> KeyEvent.VK_UP != key) .buffer(10, 1) .map(keys -> keys.size() == 10 && .collectList(); keyboardStream.onNext(KeyEvent.VK_UP); keyboardStream.onNext(KeyEvent.VK_UP); keyboardStream.onNext(KeyEvent.VK_UP); keyboardStream.onNext(KeyEvent.VK_DOWN); keyboardStream.onNext(KeyEvent.VK_DOWN); keyboardStream.onNext(KeyEvent.VK_LEFT); keyboardStream.onNext(KeyEvent.VK_RIGHT); keyboardStream.onNext(KeyEvent.VK_LEFT); keyboardStream.onNext(KeyEvent.VK_RIGHT); keyboardStream.onNext(KeyEvent.VK_B); keyboardStream.onNext(KeyEvent.VK_A); keyboardStream.onNext(KeyEvent.VK_C); keyboardStream.onComplete();
@Test public void testDefaultRequestTaskThreadName() { String mainName = "topicProcessorRequestTask"; String expectedName = mainName + "[request-task]"; TopicProcessor<Object> processor = TopicProcessor.builder().name(mainName).bufferSize(8).build(); processor.requestTask(Operators.cancelledSubscription()); Thread[] threads = new Thread[Thread.activeCount()]; Thread.enumerate(threads); //cleanup to avoid visibility in other tests processor.forceShutdown(); Condition<Thread> defaultRequestTaskThread = new Condition<>( thread -> thread != null && expectedName.equals(thread.getName()), "a thread named \"%s\"", expectedName); Assertions.assertThat(threads) .haveExactly(1, defaultRequestTaskThread); }
@Test public void simpleTest() throws Exception { final TopicProcessor<Integer> sink = TopicProcessor.<Integer>builder().name("topic").build(); final WorkQueueProcessor<Integer> processor = WorkQueueProcessor.<Integer>builder().name("queue").build(); sink.subscribe(processor); for (int i = 0; i < elems; i++) { sink.onNext(i); if (i % 1000 == 0) { processor.log("wqp.fail2").subscribe(d -> { sink.onComplete(); Assert.assertTrue("Latch is " + latch.getCount(), latch.getCount() <= 1);
@Test public void nonSerializedSinkMultiProducer() throws Exception { TopicProcessor<Integer> processor = TopicProcessor.<Integer>builder() .share(true) .build(); FluxSink<Integer> sink = processor.sink(); assertThat(sink).isNotInstanceOf(SerializedSink.class); assertThat(sink.next(1)).isNotInstanceOf(SerializedSink.class); }
TopicProcessor<String> ring = TopicProcessor.<String>builder().name("test").bufferSize(1024).build(); .zipWith(Mono.fromCallable(System::currentTimeMillis).repeat(), (t1, t2) -> String.format("%s : %s", t1, t2)); if (curr % 5 == 0 && curr % 3 == 0) ring.onNext("FizBuz"+curr); else if (curr % 3 == 0) ring.onNext("Fiz"+curr); else if (curr % 5 == 0) ring.onNext("Buz"+curr); else ring.onNext(String.valueOf(curr));
@Test(timeout = 5_000) public void testBufferSize1Created() throws Exception { TopicProcessor<String> broadcast = TopicProcessor.<String>builder().name("share-name").bufferSize(1).autoCancel(true).build(); int simultaneousSubscribers = 3000; CountDownLatch latch = new CountDownLatch(simultaneousSubscribers); Scheduler scheduler = Schedulers.single(); FluxSink<String> sink = broadcast.sink(); Flux<String> flux = broadcast.filter(Objects::nonNull) .publishOn(scheduler) .cache(1); for (int i = 0; i < simultaneousSubscribers; i++) { flux.subscribe(s -> latch.countDown()); } sink.next("data"); assertThat(latch.await(4, TimeUnit.SECONDS)) .overridingErrorMessage("Data not received") .isTrue(); }
@Test public void testTopicProcessorGetters() { final int TEST_BUFFER_SIZE = 16; TopicProcessor<Object> processor = TopicProcessor.builder().name("testProcessor").bufferSize(TEST_BUFFER_SIZE).build(); assertEquals(TEST_BUFFER_SIZE, processor.getAvailableCapacity()); processor.awaitAndShutdown(); }
@Test public void testShutdown() { for (int i = 0; i < 1000; i++) { TopicProcessor<?> dispatcher = TopicProcessor.<String>builder().name("rb-test-dispose").bufferSize(16).build(); dispatcher.awaitAndShutdown(); } }
@Test public void chainedTopicProcessor() throws Exception{ ExecutorService es = Executors.newFixedThreadPool(2); try { TopicProcessor<String> bc = TopicProcessor.<String>builder().executor(es).bufferSize(16).build(); int elems = 100; CountDownLatch latch = new CountDownLatch(elems); bc.subscribe(sub("spec1", latch)); Flux.range(0, elems) .map(s -> "hello " + s) .subscribe(bc); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); } finally { es.shutdown(); } }
0) { if(!running.get() || processor.isTerminated()){ WaitStrategy.alert(); processor.decrementSubscribers(); running.set(false); processor.readWait.signalAllWhenBlocking();
.log("begin-persistence"); final TopicProcessor<Integer> computationEmitterProcessor = TopicProcessor.<Integer>builder() .name("computation") .bufferSize(BACKLOG) .build(); final Flux<String> computationStream = computationEmitterProcessor .map(i -> Integer.toString(i)); final TopicProcessor<Integer> persistenceEmitterProcessor = TopicProcessor.<Integer>builder() .name("persistence") .bufferSize(BACKLOG) .build(); final Flux<String> persistenceStream = persistenceEmitterProcessor .map(i -> "done " + i);
@Override public Processor<Long, Long> createIdentityProcessor(int bufferSize) { Flux<String> otherStream = Flux.just("test", "test2", "test3"); // System.out.println("Providing new downstream"); FluxProcessor<Long, Long> p = WorkQueueProcessor.<Long>builder().name("fluxion-raw-fork").bufferSize(bufferSize).build(); cumulated.set(0); cumulatedJoin.set(0); BiFunction<Long, String, Long> combinator = (t1, t2) -> t1; return FluxProcessor.wrap(p, p.groupBy(k -> k % 2 == 0) .flatMap(stream -> stream.scan((prev, next) -> next) .map(integer -> -integer) .filter(integer -> integer <= 0) .map(integer -> -integer) .bufferTimeout(1024, Duration.ofMillis(50)) .flatMap(Flux::fromIterable) .doOnNext(array -> cumulated.getAndIncrement()) .flatMap(i -> Flux.zip(Flux.just(i), otherStream, combinator))) .doOnNext(array -> cumulatedJoin.getAndIncrement()) .subscribeWith(TopicProcessor.<Long>builder().name("fluxion-raw-join").bufferSize(bufferSize).build()) .doOnError(Throwable::printStackTrace)); }