@Override public FluxSink<T> onRequest(LongConsumer consumer) { if (serializedSink == null) { serializedSink = new SerializedSink<>(baseSink); sink = serializedSink; } return sink.onRequest(consumer); }
/** * Register cancel and onDemand callbacks. */ public void register() { this.sink.onRequest(this::onDemand); this.sink.onCancel(this::canceled); }
/** * Creates a {@link Publisher} emitting {@link DataBuffer}s by reading binary chunks from {@link AsyncInputStream}. * Closes the {@link AsyncInputStream} once the {@link Publisher} terminates. * * @param inputStream must not be {@literal null}. * @param dataBufferFactory must not be {@literal null}. * @return the resulting {@link Publisher}. */ static Flux<DataBuffer> createBinaryStream(AsyncInputStream inputStream, DataBufferFactory dataBufferFactory) { State state = new State(inputStream, dataBufferFactory); return Flux.usingWhen(Mono.just(inputStream), it -> { return Flux.<DataBuffer> create((sink) -> { sink.onDispose(state::close); sink.onCancel(state::close); sink.onRequest(n -> { state.request(sink, n); }); }); }, AsyncInputStream::close, AsyncInputStream::close, AsyncInputStream::close) // .concatMap(Flux::just, 1); }
@Test public void serializedSinkSingleProducer() throws Exception { WorkQueueProcessor<Integer> queueProcessor = WorkQueueProcessor.<Integer>builder() .share(false).build(); FluxSink<Integer> sink = queueProcessor.sink(); Assertions.assertThat(sink).isInstanceOf(SerializedSink.class); sink = sink.next(1); Assertions.assertThat(sink).isInstanceOf(SerializedSink.class); sink = sink.onRequest(n -> {}); Assertions.assertThat(sink).isInstanceOf(SerializedSink.class); }
@Test public void serializedSinkSingleProducer() throws Exception { TopicProcessor<Integer> processor = TopicProcessor.<Integer>builder() .share(false) .build(); FluxSink<Integer> sink = processor.sink(); assertThat(sink).isInstanceOf(SerializedSink.class); sink = sink.next(1); assertThat(sink).isInstanceOf(SerializedSink.class); sink = sink.onRequest(n -> {}); assertThat(sink).isInstanceOf(SerializedSink.class); }
s.onDispose(() -> onDispose.incrementAndGet()); s.onCancel(() -> onCancel.incrementAndGet()); s.onRequest(emitter::emit); }); StepVerifier.create(flux1, count) Flux<Integer> flux2 = Flux.create(s -> { Emitter emitter = new Emitter(s); s.onRequest(emitter::emit); s.onDispose(() -> onDispose.incrementAndGet()); s.onCancel(() -> onCancel.incrementAndGet());
@Test public void serializedSinkMultiProducerWithOnRequest() throws Exception { int count = 1000; WorkQueueProcessor<Integer> queueProcessor = WorkQueueProcessor.<Integer>builder() .share(true) .build(); TestSubscriber subscriber = new TestSubscriber(count); queueProcessor.subscribe(subscriber); FluxSink<Integer> sink = queueProcessor.sink(); AtomicInteger next = new AtomicInteger(); FluxSink<Integer> serializedSink = sink.onRequest(n -> { for (int i = 0; i < n; i++) { synchronized (s) { // to ensure that elements are in order for testing FluxSink<Integer> retSink = sink.next(next.getAndIncrement()); Assertions.assertThat(retSink).isInstanceOf(SerializedSink.class); } } }); Assertions.assertThat(serializedSink).isInstanceOf(SerializedSink.class); subscriber.await(Duration.ofSeconds(5)); sink.complete(); assertNull("Unexpected exception in subscriber", subscriber.failure); }
@Test public void fluxPushOnRequest() { AtomicInteger index = new AtomicInteger(1); AtomicInteger onRequest = new AtomicInteger(); Flux<Integer> created = Flux.push(s -> { s.onRequest(n -> { onRequest.incrementAndGet(); assertThat(n).isEqualTo(Long.MAX_VALUE); for (int i = 0; i < 5; i++) { s.next(index.getAndIncrement()); } s.complete(); }); }, OverflowStrategy.BUFFER); StepVerifier.create(created, 0) .expectSubscription() .thenAwait() .thenRequest(1) .expectNext(1) .thenRequest(2) .expectNext(2, 3) .thenRequest(2) .expectNext(4, 5) .expectComplete() .verify(); assertThat(onRequest.get()).isEqualTo(1); }
@Test public void fluxCreateGenerateOnRequest() { AtomicInteger index = new AtomicInteger(1); Flux<Integer> created = Flux.create(s -> { s.onRequest(n -> { for (int i = 0; i < n; i++) { s.next(index.getAndIncrement()); } }); }); StepVerifier.create(created, 0) .expectSubscription() .thenAwait() .thenRequest(1) .expectNext(1) .thenRequest(2) .expectNext(2, 3) .thenCancel() .verify(); }
@Test public void serializedSinkMultiProducerWithOnRequest() throws Exception { TopicProcessor<Integer> processor = TopicProcessor.<Integer>builder() .share(true) .build(); FluxSink<Integer> sink = processor.sink(); FluxSink<Integer> serializedSink = sink.onRequest(n -> { FluxSink<Integer> s = sink.next(1); assertThat(s).isInstanceOf(SerializedSink.class); s.next(2); }); assertThat(serializedSink).isInstanceOf(SerializedSink.class); StepVerifier.create(processor) .thenRequest(5) .expectNext(1, 2) .thenCancel() .verify(); } }
@Override @SuppressWarnings("unchecked") public void subscribe(Subscriber<? super Message<T>> subscriber) { Flux .<Message<T>>create(sink -> sink.onRequest(n -> { Message<?> m; while (!sink.isCancelled() && n-- > 0 && (m = this.channel.receive()) != null) { sink.next((Message<T>) m); } }), FluxSink.OverflowStrategy.IGNORE) .subscribeOn(Schedulers.elastic()) .subscribe(subscriber); }
@Override public void accept(FluxSink<V> emitter) { emitter.onRequest(new LongConsumer() {
/** * Register cancel and onDemand callbacks. */ public void register() { this.sink.onRequest(this::onDemand); this.sink.onCancel(this::canceled); }
@Override public FluxSink<T> onRequest(LongConsumer consumer) { if (serializedSink == null) { serializedSink = new SerializedSink<>(baseSink); sink = serializedSink; } return sink.onRequest(consumer); }
@Bean Flux<ServerSentEvent<Map>> processor(final List<FluxSink<ServerSentEvent<Map>>> subscribers) { return Flux.create( fluxSink -> subscribers.add( fluxSink.onCancel(() -> subscribers.remove(fluxSink)) .onDispose(() -> log.debug("disposing...")) .onRequest(i -> log.debug("{} subscribers on request", subscribers.size())))); }
public static <V> Flux<V> takeElements(Callable<RFuture<V>> callable) { return Flux.<V>create(emitter -> { emitter.onRequest(n -> { AtomicLong counter = new AtomicLong(n); AtomicReference<RFuture<V>> futureRef = new AtomicReference<RFuture<V>>(); take(callable, emitter, counter, futureRef); emitter.onDispose(() -> { futureRef.get().cancel(true); }); }); }); }
public <M> Flux<M> getMessages(Class<M> type) { return Flux.<M>create(emitter -> { emitter.onRequest(n -> { AtomicLong counter = new AtomicLong(n); RFuture<Integer> t = topic.addListenerAsync(type, new MessageListener<M>() { @Override public void onMessage(CharSequence channel, M msg) { emitter.next(msg); if (counter.decrementAndGet() == 0) { topic.removeListenerAsync(this); emitter.complete(); } } }); t.whenComplete((id, e) -> { if (e != null) { emitter.error(e); return; } emitter.onDispose(() -> { topic.removeListenerAsync(id); }); }); }); }); }
@Override @SuppressWarnings("unchecked") public void subscribe(Subscriber<? super Message<T>> subscriber) { Flux.<Message<T>>create(sink -> sink.onRequest(n -> { Message<?> m; while (!sink.isCancelled() && n-- > 0 && (m = this.channel.receive()) != null) { sink.next((Message<T>) m); } }), FluxSink.OverflowStrategy.IGNORE).subscribeOn(Schedulers.elastic()) .subscribe(subscriber); }
@Override public <R> Mono<R> reactive(Supplier<RFuture<R>> supplier) { return Flux.<R>create(emitter -> { emitter.onRequest(n -> { RFuture<R> future = supplier.get(); future.whenComplete((v, e) -> { if (e != null) { emitter.error(e); return; } emitter.onDispose(() -> { future.cancel(true); }); if (v != null) { emitter.next(v); } emitter.complete(); }); }); }).next(); }
@Override @SuppressWarnings("unchecked") public void subscribe(Subscriber<? super Message<T>> subscriber) { Flux .<Message<T>>create(sink -> sink.onRequest(n -> { Message<?> m; while (!sink.isCancelled() && n-- > 0 && (m = this.channel.receive()) != null) { sink.next((Message<T>) m); } }), FluxSink.OverflowStrategy.IGNORE) .subscribeOn(Schedulers.elastic()) .subscribe(subscriber); }