|
15 | 15 |
|
16 | 16 | import java.util.*; |
17 | 17 | import java.util.concurrent.*; |
| 18 | +import java.util.concurrent.Flow.*; |
18 | 19 | import java.util.stream.*; |
19 | 20 |
|
20 | | -import static java.util.concurrent.Flow.*; |
21 | | - |
22 | 21 | import io.reactivex.rxjava4.annotations.*; |
23 | 22 | import io.reactivex.rxjava4.disposables.*; |
24 | 23 | import io.reactivex.rxjava4.exceptions.*; |
|
34 | 33 | import io.reactivex.rxjava4.internal.schedulers.ImmediateThinScheduler; |
35 | 34 | import io.reactivex.rxjava4.internal.subscribers.*; |
36 | 35 | import io.reactivex.rxjava4.internal.util.*; |
| 36 | +import io.reactivex.rxjava4.internal.virtual.*; |
37 | 37 | import io.reactivex.rxjava4.operators.ScalarSupplier; |
38 | 38 | import io.reactivex.rxjava4.parallel.ParallelFlowable; |
39 | 39 | import io.reactivex.rxjava4.plugins.RxJavaPlugins; |
@@ -20896,4 +20896,122 @@ public final Stream<T> blockingStream(int prefetch) { |
20896 | 20896 | ObjectHelper.verifyPositive(prefetch, "prefetch"); |
20897 | 20897 | return RxJavaPlugins.onAssembly(new FlowableFlatMapStream<>(this, mapper, prefetch)); |
20898 | 20898 | } |
| 20899 | + |
| 20900 | + /** |
| 20901 | + * Construct a {@code Flowable} and use the given {@code generator} |
| 20902 | + * to generate items on demand while running on the given {@link ExecutorService}. |
| 20903 | + * <p> |
| 20904 | + * <dl> |
| 20905 | + * <dt><b>Backpressure:</b></dt> |
| 20906 | + * <dd>This operator honors backpressure from downstream and blocks the emitter if |
| 20907 | + * the downstream is not ready. |
| 20908 | + * </dd> |
| 20909 | + * <dt><b>Scheduler:</b></dt> |
| 20910 | + * <dd>You specify which {@link Scheduler} this operator will use.</dd> |
| 20911 | + * </dl> |
| 20912 | + * <p> |
| 20913 | + * Note that backpressure is handled via blocking so it is recommended the provided |
| 20914 | + * {@code ExecutorService} uses virtual threads, such as the one returned by |
| 20915 | + * {@link Executors#newVirtualThreadPerTaskExecutor()}. |
| 20916 | + * <p> |
| 20917 | + * Examples: |
| 20918 | + * <pre><code> |
| 20919 | + * try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { |
| 20920 | + * Flowable.<Integer>virtualCreate(emitter -> { |
| 20921 | + * for (int i = 0; i < 10; i++) { |
| 20922 | + * Thread.sleep(1000); |
| 20923 | + * emitter.emit(i); |
| 20924 | + * } |
| 20925 | + * }, executor) |
| 20926 | + * .subscribe( |
| 20927 | + * System.out::println, |
| 20928 | + * Throwable::printStackTrace, |
| 20929 | + * () -> System.out.println("Done") |
| 20930 | + * ); |
| 20931 | + * } |
| 20932 | + * </code></pre> |
| 20933 | + * @param <T> the element type to emit |
| 20934 | + * @param generator the callback used to generate items on demand by the downstream |
| 20935 | + * @param executor the target {@code ExecutorService} to use for running the callback |
| 20936 | + * @return the new {@code Flowable} instance |
| 20937 | + * @throws NullPointerException if {@code generator} or {@code executor} is {@code null} |
| 20938 | + * @since 4.0.0 |
| 20939 | + */ |
| 20940 | + @CheckReturnValue |
| 20941 | + @BackpressureSupport(BackpressureKind.FULL) |
| 20942 | + @SchedulerSupport(SchedulerSupport.NONE) |
| 20943 | + @NonNull |
| 20944 | + public static <@NonNull T> Flowable<T> virtualCreate(@NonNull VirtualGenerator<T> generator, @NonNull ExecutorService executor) { |
| 20945 | + Objects.requireNonNull(generator, "generator is null"); |
| 20946 | + Objects.requireNonNull(executor, "executor is null"); |
| 20947 | + return RxJavaPlugins.onAssembly(new FlowableVirtualCreateExecutor<>(generator, executor)); |
| 20948 | + } |
| 20949 | + |
| 20950 | + /** |
| 20951 | + * Returns a {@code Flowable} that turns an upstream item an upstream item into |
| 20952 | + * zero or more downstream values by running on the given {@link ExecutorService}. |
| 20953 | + * <p> |
| 20954 | + * <dl> |
| 20955 | + * <dt><b>Backpressure:</b></dt> |
| 20956 | + * <dd>This operator honors backpressure from downstream and blocks the emitter if |
| 20957 | + * the downstream is not ready. |
| 20958 | + * </dd> |
| 20959 | + * <dt><b>Scheduler:</b></dt> |
| 20960 | + * <dd>You specify which {@link Scheduler} this operator will use.</dd> |
| 20961 | + * </dl> |
| 20962 | + * <p> |
| 20963 | + * Note that backpressure is handled via blocking so it is recommended the provided |
| 20964 | + * {@code ExecutorService} uses virtual threads, such as the one returned by |
| 20965 | + * {@link Executors#newVirtualThreadPerTaskExecutor()}. |
| 20966 | + * @param <R> the downstream element type |
| 20967 | + * @param transformer the callback whose {@link VirtualTransformer#transform(Object, VirtualEmitter)} is invoked for each upstream item |
| 20968 | + * @param executor the target {@code ExecutorService} to use for running the callback |
| 20969 | + * @return the new {@code Flowable} instance |
| 20970 | + * @throws NullPointerException if {@code transformer} or {@code executor} is {@code null} |
| 20971 | + * @since 4.0.0 |
| 20972 | + */ |
| 20973 | + @CheckReturnValue |
| 20974 | + @BackpressureSupport(BackpressureKind.FULL) |
| 20975 | + @SchedulerSupport(SchedulerSupport.NONE) |
| 20976 | + @NonNull |
| 20977 | + public final <@NonNull R> Flowable<R> virtualTransform(@NonNull VirtualTransformer<T, R> transformer, @NonNull ExecutorService executor) { |
| 20978 | + return virtualTransform(transformer, executor, Flowable.bufferSize()); |
| 20979 | + } |
| 20980 | + |
| 20981 | + /** |
| 20982 | + * Returns a {@code Flowable} that turns an upstream item into zero or more downstream |
| 20983 | + * values by running on the given {@link ExecutorService}. |
| 20984 | + * <p> |
| 20985 | + * <dl> |
| 20986 | + * <dt><b>Backpressure:</b></dt> |
| 20987 | + * <dd>This operator honors backpressure from downstream and blocks the emitter if |
| 20988 | + * the downstream is not ready. |
| 20989 | + * </dd> |
| 20990 | + * <dt><b>Scheduler:</b></dt> |
| 20991 | + * <dd>You specify which {@link Scheduler} this operator will use.</dd> |
| 20992 | + * </dl> |
| 20993 | + * <p> |
| 20994 | + * Note that backpressure is handled via blocking so it is recommended the provided |
| 20995 | + * {@code ExecutorService} uses virtual threads, such as the one returned by |
| 20996 | + * {@link Executors#newVirtualThreadPerTaskExecutor()}. |
| 20997 | + * @param <R> the downstream element type |
| 20998 | + * @param transformer the callback whose {@link VirtualTransformer#transform(Object, VirtualEmitter)} is invoked for each upstream item |
| 20999 | + * @param executor the target {@code ExecutorService} to use for running the callback |
| 21000 | + * @param prefetch the number of items to fetch from the upstream. |
| 21001 | + * @return the new {@code Flowable} instance |
| 21002 | + * @throws NullPointerException if {@code transformer} or {@code executor} is {@code null} |
| 21003 | + * @throws IllegalArgumentException if {@code prefetch} is non-positive |
| 21004 | + * @since 4.0.0 |
| 21005 | + */ |
| 21006 | + @CheckReturnValue |
| 21007 | + @BackpressureSupport(BackpressureKind.FULL) |
| 21008 | + @SchedulerSupport(SchedulerSupport.NONE) |
| 21009 | + @NonNull |
| 21010 | + public final <@NonNull R> Flowable<R> virtualTransform(@NonNull VirtualTransformer<T, R> transformer, @NonNull ExecutorService executor, int prefetch) { |
| 21011 | + Objects.requireNonNull(transformer, "transformer is null"); |
| 21012 | + Objects.requireNonNull(executor, "executor is null"); |
| 21013 | + ObjectHelper.verifyPositive(prefetch, "prefetch"); |
| 21014 | + return new FlowableVirtualTransformExecutor<>(this, transformer, executor, prefetch); |
| 21015 | + } |
| 21016 | + |
20899 | 21017 | } |
0 commit comments