@Override public void completed(Integer read, DataBuffer dataBuffer) { if (read != -1) { long pos = this.position.addAndGet(read); dataBuffer.writePosition(read); this.sink.next(dataBuffer); if (!this.disposed.get()) { DataBuffer newDataBuffer = this.dataBufferFactory.allocateBuffer(this.bufferSize); ByteBuffer newByteBuffer = newDataBuffer.asByteBuffer(0, this.bufferSize); this.channel.read(newByteBuffer, pos, newDataBuffer, this); } } else { release(dataBuffer); this.sink.complete(); } }
@Override protected void hookOnNext(DataBuffer dataBuffer) { try { ByteBuffer byteBuffer = dataBuffer.asByteBuffer(); while (byteBuffer.hasRemaining()) { this.channel.write(byteBuffer); } this.sink.next(dataBuffer); request(1); } catch (IOException ex) { this.sink.next(dataBuffer); this.sink.error(ex); } }
@Override public FluxSink<T> onDispose(Disposable d) { sink.onDispose(d); return this; }
@Test public void fluxCreateSerializedCancelled() { AtomicInteger onDispose = new AtomicInteger(); AtomicInteger onCancel = new AtomicInteger(); Flux<String> created = Flux.create(s -> { s.onDispose(onDispose::getAndIncrement) .onCancel(onCancel::getAndIncrement); s.next("test1"); s.next("test2"); s.next("test3"); assertThat(s.isCancelled()).isTrue(); s.complete(); }); StepVerifier.create(created) .expectNext("test1", "test2", "test3") .thenCancel() .verify(); assertThat(onDispose.get()).isEqualTo(1); assertThat(onCancel.get()).isEqualTo(1); }
@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(); }
@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); }
e.next(1); cancelled.set(e.isCancelled()); e.next(2); e.next(3); e.complete();
@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); }
@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 gh870() throws Exception { CountDownLatch cancelled = new CountDownLatch(1); StepVerifier.create(Flux.<Integer>create(sink -> { int i = 0; sink.onCancel(cancelled::countDown); try { while (true) { sink.next(i++); Thread.sleep(1); if (sink.isCancelled()) { break; } } } catch (InterruptedException e) { sink.error(e); } }) // .doOnCancel(() -> System.out.println("cancel 2")) .publish(Function.identity()) // .doOnCancel(() -> System.out.println("cancel 1")) .take(5)) .expectNextCount(5) .verifyComplete(); if (!cancelled.await(5, TimeUnit.SECONDS)) { fail("Flux.create() did not receive cancellation signal"); } } }
private void sinkDataBuffer() { DataBuffer dataBuffer = this.dataBuffer.get(); Assert.state(dataBuffer != null, "DataBuffer should not be null"); this.sink.next(dataBuffer); this.dataBuffer.set(null); } }
@Override protected void hookOnError(Throwable throwable) { this.sink.error(throwable); }
@Override protected void hookOnComplete() { this.sink.complete(); } }
public void pushToSink() { while (sink.requestedFromDownstream() > 0) { Integer item = queue.poll(); if (item != null) { sink.next(item); } else { break; } } }
@Test public void normalBuffered() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); Flux<Integer> source = Flux.<Signal<Integer>>create(e -> { e.next(Signal.next(1)); e.next(Signal.next(2)); e.next(Signal.next(3)); e.next(Signal.complete()); System.out.println(e.isCancelled()); System.out.println(e.requestedFromDownstream()); }).dematerialize(); source.subscribe(ts); ts.assertValues(1, 2, 3) .assertNoError() .assertComplete(); }
/** * 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 contextTestPush() { StepVerifier.create(Flux.push(s -> IntStream.range(0, 10).forEach(i -> s.next(s .currentContext() .get(AtomicInteger.class) .incrementAndGet()))) .take(10) .subscriberContext(ctx -> ctx.put(AtomicInteger.class, new AtomicInteger()))) .expectNext(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) .verifyComplete(); }
@Test(timeout = 1000) public void name() throws Exception { Flux<Integer> f1 = Flux.<Integer>create(sink -> { int i =0 ; while(!sink.isCancelled()) { sink.next(i++); } }) .subscribeOn(SCHEDULER1); Flux<Integer> f2 = Flux.<Integer>create(sink -> { int i =0 ; while(!sink.isCancelled()) { sink.next(i--); } }) .subscribeOn(SCHEDULER2); Flux.merge(f1,f2) .take(1000) .blockLast(); } }