Index: 3rdParty_sources/reactor/reactor/core/Exceptions.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/Exceptions.java (.../Exceptions.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/Exceptions.java (.../Exceptions.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2024 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import java.util.Objects; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.function.Consumer; import reactor.core.publisher.Flux; import reactor.util.Logger; @@ -34,6 +35,7 @@ * Global Reactor Core Exception handling and utils to operate on. * * @author Stephane Maldini + * @author Injae Kim * @see Reactive-Streams-Commons */ public abstract class Exceptions { @@ -861,4 +863,16 @@ } } + /** + * A general-purpose {@link Consumer} that closes {@link AutoCloseable} resource. + * If exception is thrown during closing the resource, it will be propagated by {@link Exceptions#propagate(Throwable)}. + */ + public static final Consumer AUTO_CLOSE = resource -> { + try { + resource.close(); + } catch (Throwable t) { + throw Exceptions.propagate(t); + } + }; + } Index: 3rdParty_sources/reactor/reactor/core/Scannable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/Scannable.java (.../Scannable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/Scannable.java (.../Scannable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2017-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,14 +18,12 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.Spliterators; import java.util.function.Function; import java.util.regex.Pattern; @@ -38,7 +36,6 @@ import reactor.core.scheduler.Scheduler.Worker; import reactor.util.annotation.Nullable; import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; /** * A Scannable component exposes state in a non strictly memory consistent way and @@ -211,7 +208,7 @@ public static final Attr TERMINATED = new Attr<>(false); /** - * A {@link Stream} of {@link Tuple2} representing key/value + * A {@link Stream} of {@link reactor.util.function.Tuple2} representing key/value * pairs for tagged components. Defaults to {@literal null}. */ public static final Attr>> TAGS = new Attr<>(null); @@ -636,4 +633,4 @@ (s1, s2) -> s2, LinkedHashMap::new)); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/BaseSubscriber.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/BaseSubscriber.java (.../BaseSubscriber.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/BaseSubscriber.java (.../BaseSubscriber.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -131,7 +131,7 @@ * cancel). The hook is executed in addition to and after {@link #hookOnError(Throwable)}, * {@link #hookOnComplete()} and {@link #hookOnCancel()} hooks, even if these callbacks * fail. Defaults to doing nothing. A failure of the callback will be caught by - * {@link Operators#onErrorDropped(Throwable, Context)}. + * {@link Operators#onErrorDropped(Throwable, reactor.util.context.Context)}. * * @param type the type of termination event that triggered the hook * ({@link SignalType#ON_ERROR}, {@link SignalType#ON_COMPLETE} or @@ -251,4 +251,4 @@ public String toString() { return getClass().getSimpleName(); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/BlockingOptionalMonoSubscriber.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/BlockingOptionalMonoSubscriber.java (.../BlockingOptionalMonoSubscriber.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/BlockingOptionalMonoSubscriber.java (.../BlockingOptionalMonoSubscriber.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2024 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.reactivestreams.Subscription; import reactor.core.Disposable; @@ -148,7 +149,8 @@ try { if (!await(timeout, unit)) { dispose(); - throw new IllegalStateException("Timeout on blocking read for " + timeout + " " + unit); + String errorMessage = "Timeout on blocking read for " + timeout + " " + unit; + throw new IllegalStateException(errorMessage, new TimeoutException(errorMessage)); } } catch (InterruptedException ex) { Index: 3rdParty_sources/reactor/reactor/core/publisher/BlockingSingleSubscriber.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/BlockingSingleSubscriber.java (.../BlockingSingleSubscriber.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/BlockingSingleSubscriber.java (.../BlockingSingleSubscriber.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2024 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.reactivestreams.Subscription; import reactor.core.Disposable; @@ -124,7 +125,8 @@ try { if (!await(timeout, unit)) { dispose(); - throw new IllegalStateException("Timeout on blocking read for " + timeout + " " + unit); + String errorMessage = "Timeout on blocking read for " + timeout + " " + unit; + throw new IllegalStateException(errorMessage, new TimeoutException(errorMessage)); } } catch (InterruptedException ex) { Index: 3rdParty_sources/reactor/reactor/core/publisher/CallSiteSupplierFactory.java =================================================================== diff -u --- 3rdParty_sources/reactor/reactor/core/publisher/CallSiteSupplierFactory.java (revision 0) +++ 3rdParty_sources/reactor/reactor/core/publisher/CallSiteSupplierFactory.java (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2023 VMware Inc. or its affiliates, All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package reactor.core.publisher; + +import java.util.function.Supplier; +import java.util.stream.Stream; + +import sun.misc.JavaLangAccess; +import sun.misc.SharedSecrets; + +import static reactor.core.publisher.Traces.full; +import static reactor.core.publisher.Traces.isUserCode; +import static reactor.core.publisher.Traces.shouldSanitize; + +/** + * Utility class for the call-site extracting on Java 8. + */ +class CallSiteSupplierFactory implements Supplier> { + + static final Supplier> supplier; + + static { + String[] strategyClasses = { + CallSiteSupplierFactory.class.getName() + "$SharedSecretsCallSiteSupplierFactory", + CallSiteSupplierFactory.class.getName() + "$ExceptionCallSiteSupplierFactory", + }; + // tries to use the stacktrace traversing approach via the + // sun.misc.JavaLangAccess.getStackTrace* or falls back to the default way of + // stacktrace retrieval via the java.lang.Throwable.getStackTrace method + supplier = Stream + .of(strategyClasses) + .flatMap(className -> { + try { + Class clazz = Class.forName(className); + @SuppressWarnings("unchecked") + Supplier> function = (Supplier) clazz.getDeclaredConstructor() + .newInstance(); + return Stream.of(function); + } + // explicitly catch LinkageError to support static code analysis + // tools detect the attempt at finding out jdk environment + catch (LinkageError e) { + return Stream.empty(); + } + catch (Throwable e) { + return Stream.empty(); + } + }) + .findFirst() + .orElseThrow(() -> new IllegalStateException("Valid strategy not found")); + } + + + + @Override + public Supplier get() { + return supplier.get(); + } + + @SuppressWarnings("unused") + static class SharedSecretsCallSiteSupplierFactory implements Supplier> { + + static { + SharedSecrets.getJavaLangAccess(); + } + + @Override + public Supplier get() { + return new TracingException(); + } + + static class TracingException extends Throwable implements Supplier { + + static final JavaLangAccess javaLangAccess = SharedSecrets.getJavaLangAccess(); + + @Override + public String get() { + int stackTraceDepth = javaLangAccess.getStackTraceDepth(this); + + StackTraceElement previousElement = null; + // Skip get() + for (int i = 4; i < stackTraceDepth; i++) { + StackTraceElement e = javaLangAccess.getStackTraceElement(this, i); + + String className = e.getClassName(); + if (isUserCode(className)) { + StringBuilder sb = new StringBuilder(); + + if (previousElement != null) { + sb.append("\t").append(previousElement.toString()).append("\n"); + } + sb.append("\t").append(e.toString()).append("\n"); + return sb.toString(); + } + else { + if (!full && e.getLineNumber() <= 1) { + continue; + } + + String classAndMethod = className + "." + e.getMethodName(); + if (!full && shouldSanitize(classAndMethod)) { + continue; + } + previousElement = e; + } + } + + return ""; + } + } + } + + @SuppressWarnings("unused") + static class ExceptionCallSiteSupplierFactory implements Supplier> { + + @Override + public Supplier get() { + return new TracingException(); + } + + static class TracingException extends Throwable implements Supplier { + + @Override + public String get() { + StackTraceElement previousElement = null; + StackTraceElement[] stackTrace = getStackTrace(); + // Skip get() + for (int i = 4; i < stackTrace.length; i++) { + StackTraceElement e = stackTrace[i]; + + String className = e.getClassName(); + if (isUserCode(className)) { + StringBuilder sb = new StringBuilder(); + + if (previousElement != null) { + sb.append("\t").append(previousElement.toString()).append("\n"); + } + sb.append("\t").append(e.toString()).append("\n"); + return sb.toString(); + } + else { + if (!full && e.getLineNumber() <= 1) { + continue; + } + + String classAndMethod = className + "." + e.getMethodName(); + if (!full && shouldSanitize(classAndMethod)) { + continue; + } + previousElement = e; + } + } + + return ""; + } + } + } + +} \ No newline at end of file Index: 3rdParty_sources/reactor/reactor/core/publisher/ConnectableFluxHide.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ConnectableFluxHide.java (.../ConnectableFluxHide.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ConnectableFluxHide.java (.../ConnectableFluxHide.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,7 @@ if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return super.scanUnsafe(key); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/ConnectableFluxOnAssembly.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ConnectableFluxOnAssembly.java (.../ConnectableFluxOnAssembly.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ConnectableFluxOnAssembly.java (.../ConnectableFluxOnAssembly.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ if (key == Attr.ACTUAL_METADATA) return !stacktrace.isCheckpoint; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return super.scanUnsafe(key); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/ConnectableLift.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ConnectableLift.java (.../ConnectableLift.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ConnectableLift.java (.../ConnectableLift.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,8 @@ if (key == Attr.PARENT) return source; if (key == Attr.RUN_STYLE) return Scannable.from(source).scanUnsafe(key); if (key == Attr.LIFTER) return liftFunction.name; - return null; + + return super.scanUnsafe(key); } @Override @@ -68,7 +69,7 @@ @Override public final CoreSubscriber subscribeOrReturn(CoreSubscriber actual) { CoreSubscriber input = - liftFunction.lifter.apply(source, actual); + liftFunction.lifter.apply(source, Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, actual)); Objects.requireNonNull(input, "Lifted subscriber MUST NOT be null"); Index: 3rdParty_sources/reactor/reactor/core/publisher/ConnectableLiftFuseable.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ConnectableLiftFuseable.java (.../ConnectableLiftFuseable.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ConnectableLiftFuseable.java (.../ConnectableLiftFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +56,8 @@ if (key == Attr.PARENT) return source; if (key == Attr.RUN_STYLE) return Scannable.from(source).scanUnsafe(key); if (key == Attr.LIFTER) return liftFunction.name; - return null; + + return super.scanUnsafe(key); } @Override @@ -70,7 +71,7 @@ @Override public final CoreSubscriber subscribeOrReturn(CoreSubscriber actual) { CoreSubscriber input = - liftFunction.lifter.apply(source, actual); + liftFunction.lifter.apply(source, Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, actual)); Objects.requireNonNull(input, "Lifted subscriber MUST NOT be null"); Index: 3rdParty_sources/reactor/reactor/core/publisher/ContextPropagation.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ContextPropagation.java (.../ContextPropagation.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ContextPropagation.java (.../ContextPropagation.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -60,6 +60,14 @@ } } + static Flux fluxRestoreThreadLocals(Flux flux) { + return new FluxContextWriteRestoringThreadLocals<>(flux, Function.identity()); + } + + static Mono monoRestoreThreadLocals(Mono mono) { + return new MonoContextWriteRestoringThreadLocals<>(mono, Function.identity()); + } + static void configureContextSnapshotFactory(boolean clearMissing) { if (ContextPropagationSupport.isContextPropagation103OnClasspath) { globalContextSnapshotFactory = ContextSnapshotFactory.builder() @@ -120,6 +128,8 @@ }; } + + /** * Create a support function that takes a snapshot of thread locals and merges them with the * provided {@link Context}, resulting in a new {@link Context} which includes entries Index: 3rdParty_sources/reactor/reactor/core/publisher/ContextPropagationSupport.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ContextPropagationSupport.java (.../ContextPropagationSupport.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ContextPropagationSupport.java (.../ContextPropagationSupport.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -16,6 +16,13 @@ package reactor.core.publisher; +import java.util.function.Function; + +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; +import reactor.core.CorePublisher; +import reactor.core.Fuseable; +import reactor.core.Scannable; import reactor.util.Logger; import reactor.util.Loggers; @@ -81,6 +88,11 @@ return isContextPropagationOnClasspath && propagateContextToThreadLocals; } + static boolean shouldWrapPublisher(Publisher publisher) { + return shouldPropagateContextToThreadLocals() && + !Scannable.from(publisher).scanOrDefault(InternalProducerAttr.INSTANCE, false); + } + static boolean shouldRestoreThreadLocalsInSomeOperators() { return isContextPropagationOnClasspath && !propagateContextToThreadLocals; } Index: 3rdParty_sources/reactor/reactor/core/publisher/DirectProcessor.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/DirectProcessor.java (.../DirectProcessor.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/DirectProcessor.java (.../DirectProcessor.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -137,7 +137,7 @@ @Override public void onComplete() { //no particular error condition handling for onComplete - @SuppressWarnings("unused") EmitResult emitResult = tryEmitComplete(); + @SuppressWarnings("unused") Sinks.EmitResult emitResult = tryEmitComplete(); } private void emitComplete() { @@ -165,13 +165,13 @@ } private void emitError(Throwable error) { - EmitResult result = tryEmitError(error); + Sinks.EmitResult result = tryEmitError(error); if (result == EmitResult.FAIL_TERMINATED) { Operators.onErrorDroppedMulticast(error, subscribers); } } - private EmitResult tryEmitError(Throwable t) { + private Sinks.EmitResult tryEmitError(Throwable t) { Objects.requireNonNull(t, "t"); @SuppressWarnings("unchecked") @@ -185,7 +185,7 @@ for (DirectInner s : inners) { s.emitError(t); } - return EmitResult.OK; + return Sinks.EmitResult.OK; } private void emitNext(T value) { @@ -226,13 +226,13 @@ return EmitResult.FAIL_TERMINATED; } if (inners == SinkManyBestEffort.EMPTY) { - return EmitResult.FAIL_ZERO_SUBSCRIBER; + return Sinks.EmitResult.FAIL_ZERO_SUBSCRIBER; } for (DirectInner s : inners) { s.directEmitNext(t); } - return EmitResult.OK; + return Sinks.EmitResult.OK; } @Override @@ -356,4 +356,4 @@ return null; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/Flux.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/Flux.java (.../Flux.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/Flux.java (.../Flux.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2024 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package reactor.core.publisher; +import java.io.File; +import java.lang.reflect.ParameterizedType; import java.time.Duration; import java.util.ArrayList; import java.util.Collection; @@ -44,6 +46,7 @@ import java.util.function.Supplier; import java.util.logging.Level; import java.util.stream.Collector; +import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -116,6 +119,7 @@ * @author Stephane Maldini * @author David Karnok * @author Simon Baslé + * @author Injae Kim * * @see Mono */ @@ -688,7 +692,7 @@ * available backpressure modes * @param emitter Consume the {@link FluxSink} provided per-subscriber by Reactor to generate signals. * @return a {@link Flux} - * @see #push(Consumer, OverflowStrategy) + * @see #push(Consumer, reactor.core.publisher.FluxSink.OverflowStrategy) */ public static Flux create(Consumer> emitter, OverflowStrategy backpressure) { return onAssembly(new FluxCreate<>(emitter, backpressure, FluxCreate.CreateMode.PUSH_PULL)); @@ -741,7 +745,7 @@ /** * Programmatically create a {@link Flux} with the capability of emitting multiple * elements from a single-threaded producer through the {@link FluxSink} API. For - * a multi-threaded capable alternative, see {@link #create(Consumer, OverflowStrategy)}. + * a multi-threaded capable alternative, see {@link #create(Consumer, reactor.core.publisher.FluxSink.OverflowStrategy)}. *

* *

@@ -780,7 +784,7 @@ * available backpressure modes * @param emitter Consume the {@link FluxSink} provided per-subscriber by Reactor to generate signals. * @return a {@link Flux} - * @see #create(Consumer, OverflowStrategy) + * @see #create(Consumer, reactor.core.publisher.FluxSink.OverflowStrategy) */ public static Flux push(Consumer> emitter, OverflowStrategy backpressure) { return onAssembly(new FluxCreate<>(emitter, backpressure, FluxCreate.CreateMode.PUSH_ONLY)); @@ -1060,7 +1064,7 @@ */ public static Flux from(Publisher source) { //duplicated in wrap, but necessary to detect early and thus avoid applying assembly - if (source instanceof Flux) { + if (source instanceof Flux && !ContextPropagationSupport.shouldWrapPublisher(source)) { @SuppressWarnings("unchecked") Flux casted = (Flux) source; return casted; @@ -2130,6 +2134,64 @@ } /** + * Uses an {@link AutoCloseable} resource, generated by a supplier for each individual Subscriber, + * while streaming the values from a Publisher derived from the same resource and makes sure + * the resource is released if the sequence terminates or the Subscriber cancels. + *

+ * Eager {@link AutoCloseable} resource cleanup happens just before the source termination and exceptions raised + * by the cleanup Consumer may override the terminal event. + *

+ * + *

+ * For an asynchronous version of the cleanup, with distinct path for onComplete, onError + * and cancel terminations, see {@link #usingWhen(Publisher, Function, Function, BiFunction, Function)}. + * + * @param resourceSupplier a {@link Callable} that is called on subscribe to generate the resource + * @param sourceSupplier a factory to derive a {@link Publisher} from the supplied resource + * @param emitted type + * @param resource type + * + * @return a new {@link Flux} built around a disposable resource + * @see #usingWhen(Publisher, Function, Function, BiFunction, Function) + * @see #usingWhen(Publisher, Function, Function) + */ + public static Flux using(Callable resourceSupplier, + Function> sourceSupplier) { + return using(resourceSupplier, sourceSupplier, true); + } + + /** + * Uses an {@link AutoCloseable} resource, generated by a supplier for each individual Subscriber, + * while streaming the values from a Publisher derived from the same resource and makes sure + * the resource is released if the sequence terminates or the Subscriber cancels. + *

+ *

    + *
  • Eager {@link AutoCloseable} resource cleanup happens just before the source termination and exceptions raised + * by the cleanup Consumer may override the terminal event.
  • + *
  • Non-eager cleanup will drop any exception.
  • + *
+ *

+ * + *

+ * For an asynchronous version of the cleanup, with distinct path for onComplete, onError + * and cancel terminations, see {@link #usingWhen(Publisher, Function, Function, BiFunction, Function)}. + * + * @param resourceSupplier a {@link Callable} that is called on subscribe to generate the resource + * @param sourceSupplier a factory to derive a {@link Publisher} from the supplied resource + * @param eager true to clean before terminating downstream subscribers + * @param emitted type + * @param resource type + * + * @return a new {@link Flux} built around a disposable resource + * @see #usingWhen(Publisher, Function, Function, BiFunction, Function) + * @see #usingWhen(Publisher, Function, Function) + */ + public static Flux using(Callable resourceSupplier, + Function> sourceSupplier, boolean eager) { + return using(resourceSupplier, sourceSupplier, Exceptions.AUTO_CLOSE, eager); + } + + /** * Uses a resource, generated by a {@link Publisher} for each individual {@link Subscriber}, * while streaming the values from a {@link Publisher} derived from the same resource. * Whenever the resulting sequence terminates, a provided {@link Function} generates @@ -2709,7 +2771,8 @@ * signals its first value, completes or a timeout expires. Returns that value, * or null if the Flux completes empty. In case the Flux errors, the original * exception is thrown (wrapped in a {@link RuntimeException} if it was a checked - * exception). If the provided timeout expires, a {@link RuntimeException} is thrown. + * exception). If the provided timeout expires, a {@link RuntimeException} is thrown + * with a {@link TimeoutException} as the cause. *

* Note that each blockFirst() will trigger a new subscription: in other words, * the result might miss signal from hot publishers. @@ -2718,6 +2781,7 @@ * * * @param timeout maximum time period to wait for before raising a {@link RuntimeException} + * with a {@link TimeoutException} as the cause * @return the first value or null */ @Nullable @@ -2759,7 +2823,8 @@ * signals its last value, completes or a timeout expires. Returns that value, * or null if the Flux completes empty. In case the Flux errors, the original * exception is thrown (wrapped in a {@link RuntimeException} if it was a checked - * exception). If the provided timeout expires, a {@link RuntimeException} is thrown. + * exception). If the provided timeout expires, a {@link RuntimeException} is thrown + * with a {@link TimeoutException} as the cause. *

* Note that each blockLast() will trigger a new subscription: in other words, * the result might miss signal from hot publishers. @@ -2768,6 +2833,7 @@ * * * @param timeout maximum time period to wait for before raising a {@link RuntimeException} + * with a {@link TimeoutException} as the cause * @return the last value or null */ @Nullable @@ -5054,7 +5120,7 @@ } /** - * Map this {@link Flux} into {@link Tuple2 Tuple2<Long, T>} + * Map this {@link Flux} into {@link reactor.util.function.Tuple2 Tuple2<Long, T>} * of timemillis and source data. The timemillis corresponds to the elapsed time * between each signal as measured by the {@link Schedulers#parallel() parallel} scheduler. * First duration is measured between the subscription and the first element. @@ -5071,7 +5137,7 @@ } /** - * Map this {@link Flux} into {@link Tuple2 Tuple2<Long, T>} + * Map this {@link Flux} into {@link reactor.util.function.Tuple2 Tuple2<Long, T>} * of timemillis and source data. The timemillis corresponds to the elapsed time * between each signal as measured by the provided {@link Scheduler}. * First duration is measured between the subscription and the first element. @@ -6670,7 +6736,7 @@ * The name serves as a prefix in the reported metrics names. In case no name has been provided, the default name "reactor" will be applied. *

* The {@link MeterRegistry} used by reactor can be configured via - * {@link Metrics.MicrometerConfiguration#useRegistry(MeterRegistry)} + * {@link reactor.util.Metrics.MicrometerConfiguration#useRegistry(MeterRegistry)} * prior to using this operator, the default being * {@link io.micrometer.core.instrument.Metrics#globalRegistry}. * @@ -7950,7 +8016,7 @@ * The companion is generated by the provided {@link Retry} instance, see {@link Retry#max(long)}, {@link Retry#maxInARow(long)} * and {@link Retry#backoff(long, Duration)} for readily available strategy builders. *

- * The operator generates a base for the companion, a {@link Flux} of {@link Retry.RetrySignal} + * The operator generates a base for the companion, a {@link Flux} of {@link reactor.util.retry.Retry.RetrySignal} * which each give metadata about each retryable failure whenever this {@link Flux} signals an error. The final companion * should be derived from that base companion and emit data in response to incoming onNext (although it can emit less * elements, or delay the emissions). @@ -7960,12 +8026,12 @@ *

* *

- * Note that the {@link Retry.RetrySignal} state can be + * Note that the {@link reactor.util.retry.Retry.RetrySignal} state can be * transient and change between each source * {@link org.reactivestreams.Subscriber#onError(Throwable) onError} or * {@link org.reactivestreams.Subscriber#onNext(Object) onNext}. If processed with a delay, * this could lead to the represented state being out of sync with the state at which the retry - * was evaluated. Map it to {@link Retry.RetrySignal#copy()} + * was evaluated. Map it to {@link reactor.util.retry.Retry.RetrySignal#copy()} * right away to mediate this. *

* Note that if the companion {@link Publisher} created by the {@code whenFactory} @@ -7990,12 +8056,12 @@ * * * @param retrySpec the {@link Retry} strategy that will generate the companion {@link Publisher}, - * given a {@link Flux} that signals each onError as a {@link Retry.RetrySignal}. + * given a {@link Flux} that signals each onError as a {@link reactor.util.retry.Retry.RetrySignal}. * * @return a {@link Flux} that retries on onError when a companion {@link Publisher} produces an onNext signal - * @see Retry#max(long) - * @see Retry#maxInARow(long) - * @see Retry#backoff(long, Duration) + * @see reactor.util.retry.Retry#max(long) + * @see reactor.util.retry.Retry#maxInARow(long) + * @see reactor.util.retry.Retry#backoff(long, Duration) */ public final Flux retryWhen(Retry retrySpec) { return onAssembly(new FluxRetryWhen<>(this, retrySpec)); @@ -8259,7 +8325,7 @@ /** * Expect and emit a single item from this {@link Flux} source or signal - * {@link NoSuchElementException} for an empty source, or + * {@link java.util.NoSuchElementException} for an empty source, or * {@link IndexOutOfBoundsException} for a source with more than one element. * *

@@ -8585,7 +8651,7 @@ * Subscribe a {@link Consumer} to this {@link Flux} that will consume all the * elements in the sequence. It will request an unbounded demand ({@code Long.MAX_VALUE}). *

- * For a passive version that observe and forward incoming data see {@link #doOnNext(Consumer)}. + * For a passive version that observe and forward incoming data see {@link #doOnNext(java.util.function.Consumer)}. *

* For a version that gives you more control over backpressure and the request, see * {@link #subscribe(Subscriber)} with a {@link BaseSubscriber}. @@ -8612,7 +8678,7 @@ * The subscription will request an unbounded demand ({@code Long.MAX_VALUE}). *

* For a passive version that observe and forward incoming data see - * {@link #doOnNext(Consumer)} and {@link #doOnError(Consumer)}. + * {@link #doOnNext(java.util.function.Consumer)} and {@link #doOnError(java.util.function.Consumer)}. *

For a version that gives you more control over backpressure and the request, see * {@link #subscribe(Subscriber)} with a {@link BaseSubscriber}. *

@@ -8638,8 +8704,8 @@ * elements in the sequence, handle errors and react to completion. The subscription * will request unbounded demand ({@code Long.MAX_VALUE}). *

- * For a passive version that observe and forward incoming data see {@link #doOnNext(Consumer)}, - * {@link #doOnError(Consumer)} and {@link #doOnComplete(Runnable)}. + * For a passive version that observe and forward incoming data see {@link #doOnNext(java.util.function.Consumer)}, + * {@link #doOnError(java.util.function.Consumer)} and {@link #doOnComplete(Runnable)}. *

For a version that gives you more control over backpressure and the request, see * {@link #subscribe(Subscriber)} with a {@link BaseSubscriber}. *

@@ -8670,8 +8736,8 @@ * request the adequate amount of data, or request unbounded demand * {@code Long.MAX_VALUE} if no such consumer is provided. *

- * For a passive version that observe and forward incoming data see {@link #doOnNext(Consumer)}, - * {@link #doOnError(Consumer)}, {@link #doOnComplete(Runnable)} + * For a passive version that observe and forward incoming data see {@link #doOnNext(java.util.function.Consumer)}, + * {@link #doOnError(java.util.function.Consumer)}, {@link #doOnComplete(Runnable)} * and {@link #doOnSubscribe(Consumer)}. *

For a version that gives you more control over backpressure and the request, see * {@link #subscribe(Subscriber)} with a {@link BaseSubscriber}. @@ -8710,8 +8776,8 @@ * elements in the sequence, handle errors and react to completion. Additionally, a {@link Context} * is tied to the subscription. At subscription, an unbounded request is implicitly made. *

- * For a passive version that observe and forward incoming data see {@link #doOnNext(Consumer)}, - * {@link #doOnError(Consumer)}, {@link #doOnComplete(Runnable)} + * For a passive version that observe and forward incoming data see {@link #doOnNext(java.util.function.Consumer)}, + * {@link #doOnError(java.util.function.Consumer)}, {@link #doOnComplete(Runnable)} * and {@link #doOnSubscribe(Consumer)}. *

For a version that gives you more control over backpressure and the request, see * {@link #subscribe(Subscriber)} with a {@link BaseSubscriber}. @@ -8770,6 +8836,7 @@ } } + subscriber = Operators.restoreContextOnSubscriberIfPublisherNonInternal(publisher, subscriber); publisher.subscribe(subscriber); } catch (Throwable e) { @@ -8797,7 +8864,7 @@ * the next occurrence of a {@link #publishOn(Scheduler) publishOn}. *

* Note that if you are using an eager or blocking - * {@link #create(Consumer, OverflowStrategy)} + * {@link #create(Consumer, FluxSink.OverflowStrategy)} * as the source, it can lead to deadlocks due to requests piling up behind the emitter. * In such case, you should call {@link #subscribeOn(Scheduler, boolean) subscribeOn(scheduler, false)} * instead. @@ -8834,7 +8901,7 @@ * the next occurrence of a {@link #publishOn(Scheduler) publishOn}. *

* Note that if you are using an eager or blocking - * {@link Flux#create(Consumer, OverflowStrategy)} + * {@link Flux#create(Consumer, FluxSink.OverflowStrategy)} * as the source, it can lead to deadlocks due to requests piling up behind the emitter. * Thus this operator has a {@code requestOnSeparateThread} parameter, which should be * set to {@code false} in this case. @@ -9658,7 +9725,7 @@ } /** - * Emit a {@link Tuple2} pair of T1 the current clock time in + * Emit a {@link reactor.util.function.Tuple2} pair of T1 the current clock time in * millis (as a {@link Long} measured by the {@link Schedulers#parallel() parallel} * Scheduler) and T2 the emitted data (as a {@code T}), for each item from this {@link Flux}. * @@ -9674,7 +9741,7 @@ } /** - * Emit a {@link Tuple2} pair of T1 the current clock time in + * Emit a {@link reactor.util.function.Tuple2} pair of T1 the current clock time in * millis (as a {@link Long} measured by the provided {@link Scheduler}) and T2 * the emitted data (as a {@code T}), for each item from this {@link Flux}. * @@ -9916,7 +9983,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. @@ -9956,7 +10023,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: The overlapping variant DOES NOT discard elements, as they might be part of another still valid window. * The exact window and dropping window variants bot discard elements they internally queued for backpressure @@ -9992,7 +10059,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors and those emitted by the {@code boundary} delivered to the window - * {@link Flux} are wrapped in {@link Exceptions.SourceException}. + * {@link Flux} are wrapped in {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. @@ -10024,7 +10091,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. @@ -10067,7 +10134,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: The overlapping variant DOES NOT discard elements, as they might be part of another still valid window. * The exact window and dropping window variants bot discard elements they internally queued for backpressure @@ -10101,7 +10168,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. @@ -10145,7 +10212,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: The overlapping variant DOES NOT discard elements, as they might be part of another still valid window. * The exact window and dropping window variants bot discard elements they internally queued for backpressure @@ -10185,7 +10252,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. @@ -10219,7 +10286,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. @@ -10255,7 +10322,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. @@ -10290,7 +10357,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. @@ -10330,7 +10397,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. Upon cancellation of the current window, @@ -10372,7 +10439,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. Upon cancellation of the current window, @@ -10416,7 +10483,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. Upon cancellation of the current window, @@ -10455,7 +10522,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. Upon cancellation of the current window, @@ -10486,7 +10553,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. Upon cancellation of the current window, @@ -10519,7 +10586,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal. Upon cancellation of the current window, @@ -10559,7 +10626,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal, as well as the triggering element(s) (that doesn't match @@ -10597,7 +10664,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator discards elements it internally queued for backpressure * upon cancellation or error triggered by a data signal, as well as the triggering element(s) (that doesn't match @@ -10641,7 +10708,7 @@ *

* To distinguish errors emitted by the processing of individual windows, source * sequence errors delivered to the window {@link Flux} are wrapped in - * {@link Exceptions.SourceException}. + * {@link reactor.core.Exceptions.SourceException}. * *

Discard Support: This operator DOES NOT discard elements. * @@ -11065,8 +11132,12 @@ */ @SuppressWarnings("unchecked") static Flux wrap(Publisher source) { - if (source instanceof Flux) { - return (Flux) source; + boolean shouldWrap = ContextPropagationSupport.shouldWrapPublisher(source); + if (source instanceof Flux) { + if (!shouldWrap) { + return (Flux) source; + } + return ContextPropagation.fluxRestoreThreadLocals((Flux) source); } //for scalars we'll instantiate the operators directly to avoid onAssembly @@ -11084,16 +11155,22 @@ } } - if(source instanceof Mono){ - if(source instanceof Fuseable){ - return new FluxSourceMonoFuseable<>((Mono)source); + Flux target; + if (source instanceof Mono) { + if (source instanceof Fuseable) { + target = new FluxSourceMonoFuseable<>((Mono) source); + } else { + target = new FluxSourceMono<>((Mono) source); } - return new FluxSourceMono<>((Mono)source); + } else if (source instanceof Fuseable) { + target = new FluxSourceFuseable<>(source); + } else { + target = new FluxSource<>(source); } - if(source instanceof Fuseable){ - return new FluxSourceFuseable<>(source); + if (shouldWrap) { + return ContextPropagation.fluxRestoreThreadLocals(target); } - return new FluxSource<>(source); + return target; } @SuppressWarnings("rawtypes") @@ -11108,4 +11185,4 @@ @SuppressWarnings("rawtypes") static final Function IDENTITY_FUNCTION = Function.identity(); -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxArray.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxArray.java (.../FluxArray.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxArray.java (.../FluxArray.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,8 +64,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.BUFFERED) return array.length; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - - return null; + return SourceProducer.super.scanUnsafe(key); } static final class ArraySubscription Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxBufferBoundary.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxBufferBoundary.java (.../FluxBufferBoundary.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxBufferBoundary.java (.../FluxBufferBoundary.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ Publisher other, Supplier bufferSupplier) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); this.bufferSupplier = Objects.requireNonNull(bufferSupplier, "bufferSupplier"); } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxBufferPredicate.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxBufferPredicate.java (.../FluxBufferPredicate.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxBufferPredicate.java (.../FluxBufferPredicate.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -40,7 +40,7 @@ /** * Buffers elements into custom collections where the buffer boundary is determined by - * a {@link Predicate} on the values. The predicate can be used in + * a {@link java.util.function.Predicate} on the values. The predicate can be used in * several modes: *

    *
  • {@code Until}: A new buffer starts when the predicate returns true. The @@ -461,4 +461,4 @@ } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxBufferWhen.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxBufferWhen.java (.../FluxBufferWhen.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxBufferWhen.java (.../FluxBufferWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,7 +65,7 @@ Supplier bufferSupplier, Supplier> queueSupplier) { super(source); - this.start = Objects.requireNonNull(start, "start"); + this.start = Operators.toFluxOrMono(Objects.requireNonNull(start, "start")); this.end = Objects.requireNonNull(end, "end"); this.bufferSupplier = Objects.requireNonNull(bufferSupplier, "bufferSupplier"); this.queueSupplier = Objects.requireNonNull(queueSupplier, "queueSupplier"); @@ -360,6 +360,7 @@ BufferWhenCloseSubscriber bc = new BufferWhenCloseSubscriber<>(this, idx); subscribers.add(bc); + p = Operators.toFluxOrMono(p); p.subscribe(bc); } @@ -431,7 +432,7 @@ if (key == Attr.ERROR) return errors; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return InnerOperator.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxCallable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxCallable.java (.../FluxCallable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxCallable.java (.../FluxCallable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxCombineLatest.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxCombineLatest.java (.../FluxCombineLatest.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxCombineLatest.java (.../FluxCombineLatest.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -166,6 +166,8 @@ } } + Operators.toFluxOrMono(a); + Queue queue = queueSupplier.get(); CombineLatestCoordinator coordinator = @@ -180,7 +182,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PREFETCH) return prefetch; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class CombineLatestCoordinator Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatArray.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatArray.java (.../FluxConcatArray.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatArray.java (.../FluxConcatArray.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,6 +61,7 @@ if (p == null) { Operators.error(actual, new NullPointerException("The single source Publisher is null")); } else { + p = Operators.toFluxOrMono(p); p.subscribe(actual); } return; @@ -83,7 +84,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.DELAY_ERROR) return delayError; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } /** @@ -255,6 +256,7 @@ if (this.cancelled) { return; } + p = Operators.toFluxOrMono(p); p.subscribe(this); final Object state = this.get(); @@ -404,7 +406,7 @@ return; } - final Publisher p = a[i]; + Publisher p = a[i]; if (p == null) { this.remove(); @@ -440,6 +442,7 @@ return; } + p = Operators.toFluxOrMono(p); p.subscribe(this); final Object state = this.get(); Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatIterable.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatIterable.java (.../FluxConcatIterable.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatIterable.java (.../FluxConcatIterable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,7 +64,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class ConcatIterableSubscriber @@ -144,6 +144,7 @@ produced(c); } + p = Operators.toFluxOrMono(p); p.subscribe(this); if (isCancelled()) { Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatMap.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatMap.java (.../FluxConcatMap.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatMap.java (.../FluxConcatMap.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -448,6 +448,7 @@ } else { active = true; + p = Operators.toFluxOrMono(p); p.subscribe(inner); } } @@ -805,6 +806,7 @@ } else { active = true; + p = Operators.toFluxOrMono(p); p.subscribe(inner); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatMapNoPrefetch.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatMapNoPrefetch.java (.../FluxConcatMapNoPrefetch.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxConcatMapNoPrefetch.java (.../FluxConcatMapNoPrefetch.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -203,6 +203,7 @@ return; } + p = Operators.toFluxOrMono(p); p.subscribe(inner); } catch (Throwable e) { Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxContextWrite.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxContextWrite.java (.../FluxContextWrite.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxContextWrite.java (.../FluxContextWrite.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -46,7 +46,7 @@ @Override public Object scanUnsafe(Attr key) { - if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == Scannable.Attr.RUN_STYLE) return Attr.RunStyle.SYNC; return super.scanUnsafe(key); } @@ -79,7 +79,7 @@ if (key == Attr.PARENT) { return s; } - if (key == Attr.RUN_STYLE) { + if (key == Scannable.Attr.RUN_STYLE) { return Attr.RunStyle.SYNC; } return InnerOperator.super.scanUnsafe(key); @@ -175,4 +175,4 @@ return qs != null ? qs.size() : 0; } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxContextWriteRestoringThreadLocals.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxContextWriteRestoringThreadLocals.java (.../FluxContextWriteRestoringThreadLocals.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxContextWriteRestoringThreadLocals.java (.../FluxContextWriteRestoringThreadLocals.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -22,6 +22,7 @@ import io.micrometer.context.ContextSnapshot; import org.reactivestreams.Subscription; import reactor.core.CoreSubscriber; +import reactor.core.Fuseable; import reactor.core.Fuseable.ConditionalSubscriber; import reactor.util.annotation.Nullable; import reactor.util.context.Context; @@ -49,10 +50,11 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return super.scanUnsafe(key); } - static final class ContextWriteRestoringThreadLocalsSubscriber + static class ContextWriteRestoringThreadLocalsSubscriber implements ConditionalSubscriber, InnerOperator { final CoreSubscriber actual; @@ -171,4 +173,46 @@ } } } + + static final class FuseableContextWriteRestoringThreadLocalsSubscriber + extends ContextWriteRestoringThreadLocalsSubscriber + implements Fuseable.QueueSubscription { + + FuseableContextWriteRestoringThreadLocalsSubscriber( + CoreSubscriber actual, Context context) { + super(actual, context); + } + + // Required for + // FuseableBestPracticesTest.coreFuseableSubscribersShouldNotExtendNonFuseableOnNext + @Override + public void onNext(T t) { + super.onNext(t); + } + + @Override + public T poll() { + throw new UnsupportedOperationException("Nope"); + } + + @Override + public int requestFusion(int requestedMode) { + return Fuseable.NONE; + } + + @Override + public int size() { + throw new UnsupportedOperationException("Nope"); + } + + @Override + public boolean isEmpty() { + throw new UnsupportedOperationException("Nope"); + } + + @Override + public void clear() { + throw new UnsupportedOperationException("Nope"); + } + } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxCreate.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxCreate.java (.../FluxCreate.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxCreate.java (.../FluxCreate.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -58,7 +58,7 @@ final CreateMode createMode; FluxCreate(Consumer> source, - OverflowStrategy backpressure, + FluxSink.OverflowStrategy backpressure, CreateMode createMode) { this.source = Objects.requireNonNull(source, "source"); this.backpressure = Objects.requireNonNull(backpressure, "backpressure"); @@ -88,24 +88,26 @@ @Override public void subscribe(CoreSubscriber actual) { - BaseSink sink = createSink(actual, backpressure); + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); + BaseSink sink = createSink(wrapped, backpressure); - actual.onSubscribe(sink); + wrapped.onSubscribe(sink); try { source.accept( createMode == CreateMode.PUSH_PULL ? new SerializedFluxSink<>(sink) : sink); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - sink.error(Operators.onOperatorError(ex, actual.currentContext())); + sink.error(Operators.onOperatorError(ex, wrapped.currentContext())); } } @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } /** @@ -1125,4 +1127,4 @@ } } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxDefer.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxDefer.java (.../FluxDefer.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxDefer.java (.../FluxDefer.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,6 +58,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxDeferContextual.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxDeferContextual.java (.../FluxDeferContextual.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxDeferContextual.java (.../FluxDeferContextual.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,13 +54,13 @@ return; } - from(p).subscribe(actual); + Operators.toFluxOrMono(p).subscribe(actual); } @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxDelaySubscription.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxDelaySubscription.java (.../FluxDelaySubscription.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxDelaySubscription.java (.../FluxDelaySubscription.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ FluxDelaySubscription(Flux source, Publisher other) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); } @Override @@ -68,7 +68,7 @@ static final class DelaySubscriptionOtherSubscriber extends Operators.DeferredSubscription implements InnerOperator { - final Consumer> source; + final Consumer> source; final CoreSubscriber actual; @@ -77,7 +77,7 @@ boolean done; DelaySubscriptionOtherSubscriber(CoreSubscriber actual, - Consumer> source) { + Consumer> source) { this.actual = actual; this.source = source; } @@ -199,4 +199,4 @@ actual.onComplete(); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxEmpty.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxEmpty.java (.../FluxEmpty.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxEmpty.java (.../FluxEmpty.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,7 +45,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } /** Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxError.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxError.java (.../FluxError.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxError.java (.../FluxError.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxErrorOnRequest.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxErrorOnRequest.java (.../FluxErrorOnRequest.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxErrorOnRequest.java (.../FluxErrorOnRequest.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class ErrorSubscription implements InnerProducer { Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxErrorSupplied.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxErrorSupplied.java (.../FluxErrorSupplied.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxErrorSupplied.java (.../FluxErrorSupplied.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ /** * Emits a generated {@link Throwable} instance to Subscribers, lazily generated via a - * provided {@link Supplier}. + * provided {@link java.util.function.Supplier}. * * @param the value type * @@ -57,6 +57,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxExpand.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxExpand.java (.../FluxExpand.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxExpand.java (.../FluxExpand.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2017-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,8 +119,8 @@ Publisher p; try { - p = Objects.requireNonNull(expander.apply(t), - "The expander returned a null Publisher"); + p = Operators.toFluxOrMono(Objects.requireNonNull(expander.apply(t), + "The expander returned a null Publisher")); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxFilter.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxFilter.java (.../FluxFilter.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxFilter.java (.../FluxFilter.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -61,7 +61,7 @@ static final class FilterSubscriber implements InnerOperator, - ConditionalSubscriber { + Fuseable.ConditionalSubscriber { final CoreSubscriber actual; final Context ctx; @@ -194,9 +194,9 @@ static final class FilterConditionalSubscriber implements InnerOperator, - ConditionalSubscriber { + Fuseable.ConditionalSubscriber { - final ConditionalSubscriber actual; + final Fuseable.ConditionalSubscriber actual; final Context ctx; final Predicate predicate; @@ -205,7 +205,7 @@ boolean done; - FilterConditionalSubscriber(ConditionalSubscriber actual, + FilterConditionalSubscriber(Fuseable.ConditionalSubscriber actual, Predicate predicate) { this.actual = actual; this.ctx = actual.currentContext(); @@ -327,4 +327,4 @@ } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxFilterWhen.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxFilterWhen.java (.../FluxFilterWhen.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxFilterWhen.java (.../FluxFilterWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2017-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -279,6 +279,7 @@ FilterWhenInner inner = new FilterWhenInner(this, !(p instanceof Mono)); if (CURRENT.compareAndSet(this,null, inner)) { state = STATE_RUNNING; + p = Operators.toFluxOrMono(p); p.subscribe(inner); break; } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxFirstWithSignal.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxFirstWithSignal.java (.../FluxFirstWithSignal.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxFirstWithSignal.java (.../FluxFirstWithSignal.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -127,11 +127,14 @@ new NullPointerException("The single source Publisher is null")); } else { + p = Operators.toFluxOrMono(p); p.subscribe(actual); } return; } + Operators.toFluxOrMono(a); + RaceCoordinator coordinator = new RaceCoordinator<>(n); coordinator.subscribe(a, n, actual); @@ -164,7 +167,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class RaceCoordinator Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxFirstWithValue.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxFirstWithValue.java (.../FluxFirstWithValue.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxFirstWithValue.java (.../FluxFirstWithValue.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -159,7 +159,7 @@ return; } if (n == 1) { - Publisher p = a[0]; + Publisher p = Flux.from(a[0]); if (p == null) { Operators.error(actual, @@ -178,7 +178,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class RaceValuesCoordinator @@ -227,6 +227,8 @@ actual.onSubscribe(this); + Operators.toFluxOrMono(sources); + for (int i = 0; i < n; i++) { if (cancelled || winner != Integer.MIN_VALUE) { return; Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxFlatMap.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxFlatMap.java (.../FluxFlatMap.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxFlatMap.java (.../FluxFlatMap.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -30,6 +30,7 @@ import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; +import reactor.core.CorePublisher; import reactor.core.CoreSubscriber; import reactor.core.Exceptions; import reactor.core.Fuseable; @@ -196,6 +197,7 @@ } } else { + p = Operators.toFluxOrMono(p); if (!fuseableExpected || p instanceof Fuseable) { p.subscribe(s); } @@ -424,6 +426,7 @@ else { FlatMapInner inner = new FlatMapInner<>(this, prefetch); if (add(inner)) { + p = Operators.toFluxOrMono(p); p.subscribe(inner); } else { Operators.onDiscard(t, actual.currentContext()); Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxFromMonoOperator.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxFromMonoOperator.java (.../FluxFromMonoOperator.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxFromMonoOperator.java (.../FluxFromMonoOperator.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,6 +63,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.PARENT) return source; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -80,6 +81,7 @@ } OptimizableOperator newSource = operator.nextOptimizableSource(); if (newSource == null) { + subscriber = Operators.restoreContextOnSubscriberIfPublisherNonInternal(operator.source(), subscriber); operator.source().subscribe(subscriber); return; } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxGenerate.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxGenerate.java (.../FluxGenerate.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxGenerate.java (.../FluxGenerate.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,21 +74,24 @@ @Override public void subscribe(CoreSubscriber actual) { + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); + S state; try { state = stateSupplier.call(); } catch (Throwable e) { - Operators.error(actual, Operators.onOperatorError(e, actual.currentContext())); + Operators.error(wrapped, Operators.onOperatorError(e, wrapped.currentContext())); return; } - actual.onSubscribe(new GenerateSubscription<>(actual, state, generator, stateConsumer)); + wrapped.onSubscribe(new GenerateSubscription<>(wrapped, state, generator, stateConsumer)); } @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class GenerateSubscription Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxGroupJoin.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxGroupJoin.java (.../FluxGroupJoin.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxGroupJoin.java (.../FluxGroupJoin.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,7 +81,7 @@ Supplier> queueSupplier, Supplier> processorQueueSupplier) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); this.leftEnd = Objects.requireNonNull(leftEnd, "leftEnd"); this.rightEnd = Objects.requireNonNull(rightEnd, "rightEnd"); this.processorQueueSupplier = Objects.requireNonNull(processorQueueSupplier, "processorQueueSupplier"); @@ -336,6 +336,7 @@ new LeftRightEndSubscriber(this, true, idx); cancellations.add(end); + p = Operators.toFluxOrMono(p); p.subscribe(end); ex = error; @@ -404,6 +405,7 @@ new LeftRightEndSubscriber(this, false, idx); cancellations.add(end); + p = Operators.toFluxOrMono(p); p.subscribe(end); ex = error; Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxIndexFuseable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxIndexFuseable.java (.../FluxIndexFuseable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxIndexFuseable.java (.../FluxIndexFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -26,7 +26,7 @@ import reactor.util.function.Tuple2; /** - * A {@link Fuseable} version of {@link FluxIndex}, an + * A {@link reactor.core.Fuseable} version of {@link FluxIndex}, an * operator that tags the values it passes through with their index in the original * sequence, either as their natural long index (0-based) or as a customized index * by way of a user-provided {@link BiFunction}. The resulting sequence is one of @@ -367,4 +367,4 @@ return InnerOperator.super.scanUnsafe(key); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxInterval.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxInterval.java (.../FluxInterval.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxInterval.java (.../FluxInterval.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,8 +80,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.RUN_ON) return timedScheduler; if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; - - return null; + return SourceProducer.super.scanUnsafe(key); } static final class IntervalRunnable implements Runnable, Subscription, Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxIterable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxIterable.java (.../FluxIterable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxIterable.java (.../FluxIterable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,7 +92,7 @@ if (key == Attr.RUN_STYLE) { return Attr.RunStyle.SYNC; } - return null; + return SourceProducer.super.scanUnsafe(key); } /** Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxJoin.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxJoin.java (.../FluxJoin.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxJoin.java (.../FluxJoin.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ import java.util.function.BiFunction; import java.util.function.BiPredicate; import java.util.function.Function; -import java.util.function.Supplier; import java.util.stream.Stream; import org.reactivestreams.Publisher; @@ -63,7 +62,7 @@ Function> rightEnd, BiFunction resultSelector) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); this.leftEnd = Objects.requireNonNull(leftEnd, "leftEnd"); this.rightEnd = Objects.requireNonNull(rightEnd, "rightEnd"); this.resultSelector = Objects.requireNonNull(resultSelector, "resultSelector"); @@ -289,6 +288,7 @@ new LeftRightEndSubscriber(this, true, idx); cancellations.add(end); + p = Operators.toFluxOrMono(p); p.subscribe(end); ex = error; @@ -366,6 +366,7 @@ new LeftRightEndSubscriber(this, false, idx); cancellations.add(end); + p = Operators.toFluxOrMono(p); p.subscribe(end); ex = error; Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxJust.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxJust.java (.../FluxJust.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxJust.java (.../FluxJust.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2015-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.BUFFERED) return 1; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxLift.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxLift.java (.../FluxLift.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxLift.java (.../FluxLift.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ @Override public CoreSubscriber subscribeOrReturn(CoreSubscriber actual) { CoreSubscriber input = - liftFunction.lifter.apply(source, actual); + liftFunction.lifter.apply(source, Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, actual)); Objects.requireNonNull(input, "Lifted subscriber MUST NOT be null"); Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxLiftFuseable.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxLiftFuseable.java (.../FluxLiftFuseable.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxLiftFuseable.java (.../FluxLiftFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ @Override public CoreSubscriber subscribeOrReturn(CoreSubscriber actual) { CoreSubscriber input = - liftFunction.lifter.apply(source, actual); + liftFunction.lifter.apply(source, Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, actual)); Objects.requireNonNull(input, "Lifted subscriber MUST NOT be null"); @@ -65,6 +65,6 @@ input = new FluxHide.SuppressFuseableSubscriber<>(input); } //otherwise QS is not required or user already made a compatible conversion - return input; + return Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, input); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxMerge.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxMerge.java (.../FluxMerge.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxMerge.java (.../FluxMerge.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,9 @@ throw new IllegalArgumentException("maxConcurrency > 0 required but it was " + maxConcurrency); } this.sources = Objects.requireNonNull(sources, "sources"); + + Operators.toFluxOrMono(this.sources); + this.delayError = delayError; this.maxConcurrency = maxConcurrency; this.prefetch = prefetch; @@ -106,7 +109,7 @@ if (key == Attr.PREFETCH) return prefetch; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } \ No newline at end of file Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxMergeComparing.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxMergeComparing.java (.../FluxMergeComparing.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxMergeComparing.java (.../FluxMergeComparing.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2018-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ * Merges the provided sources {@link org.reactivestreams.Publisher}, assuming a total order * of the values, by picking the smallest available value from each publisher, resulting in * a single totally ordered {@link Flux} sequence. This operator considers its primary - * parent to be the first of the sources, for the purpose of {@link Attr#PARENT}. + * parent to be the first of the sources, for the purpose of {@link reactor.core.Scannable.Attr#PARENT}. * * @param the value type * @author David Karnok @@ -67,6 +67,8 @@ } } + Operators.toFluxOrMono(this.sources); + this.prefetch = prefetch; this.valueComparator = valueComparator; this.delayError = delayError; @@ -111,8 +113,7 @@ if (key == Attr.PREFETCH) return prefetch; if (key == Attr.DELAY_ERROR) return delayError; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - - return null; + return SourceProducer.super.scanUnsafe(key); } @Override @@ -396,7 +397,7 @@ if (key == Attr.REQUESTED_FROM_DOWNSTREAM) return requested - emitted; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return InnerProducer.super.scanUnsafe(key); } } @@ -492,7 +493,7 @@ if (key == Attr.BUFFERED) return queue.size(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return InnerOperator.super.scanUnsafe(key); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxMergeSequential.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxMergeSequential.java (.../FluxMergeSequential.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxMergeSequential.java (.../FluxMergeSequential.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -205,7 +205,7 @@ Publisher publisher; try { - publisher = Objects.requireNonNull(mapper.apply(t), "publisher"); + publisher = Operators.toFluxOrMono(Objects.requireNonNull(mapper.apply(t), "publisher")); } catch (Throwable ex) { onError(Operators.onOperatorError(s, ex, t, actual.currentContext())); Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxMetricsFuseable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxMetricsFuseable.java (.../FluxMetricsFuseable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxMetricsFuseable.java (.../FluxMetricsFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -72,13 +72,13 @@ * subsequences immediately upstream of it, so Counters would be a bit irrelevant. We however want to instrument * onNext counts. */ - static final class MetricsFuseableSubscriber extends MetricsSubscriber + static final class MetricsFuseableSubscriber extends FluxMetrics.MetricsSubscriber implements Fuseable, QueueSubscription { int mode; @Nullable - QueueSubscription qs; + Fuseable.QueueSubscription qs; MetricsFuseableSubscriber(CoreSubscriber actual, MeterRegistry registry, @@ -179,4 +179,4 @@ return qs == null ? 0 : qs.size(); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxName.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxName.java (.../FluxName.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxName.java (.../FluxName.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -32,7 +32,7 @@ /** * An operator that just bears a name or a set of tags, which can be retrieved via the - * {@link Attr#TAGS TAGS} + * {@link reactor.core.Scannable.Attr#TAGS TAGS} * attribute. * * @author Simon BaslĂ© @@ -128,4 +128,4 @@ return super.scanUnsafe(key); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxNever.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxNever.java (.../FluxNever.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxNever.java (.../FluxNever.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } /** Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxOnErrorResume.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxOnErrorResume.java (.../FluxOnErrorResume.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxOnErrorResume.java (.../FluxOnErrorResume.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -91,8 +91,8 @@ Publisher p; try { - p = Objects.requireNonNull(nextFactory.apply(t), - "The nextFactory returned a null Publisher"); + p = Operators.toFluxOrMono(Objects.requireNonNull(nextFactory.apply(t), + "The nextFactory returned a null Publisher")); } catch (Throwable e) { Throwable _e = Operators.onOperatorError(e, actual.currentContext()); Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxOperator.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxOperator.java (.../FluxOperator.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxOperator.java (.../FluxOperator.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,8 @@ package reactor.core.publisher; import java.util.Objects; -import java.util.function.BiFunction; -import java.util.function.Function; import org.reactivestreams.Publisher; -import reactor.core.CoreSubscriber; import reactor.core.Scannable; import reactor.util.annotation.Nullable; @@ -50,6 +47,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.PARENT) return source; + if (key == InternalProducerAttr.INSTANCE) return false; // public class! return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxPublish.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxPublish.java (.../FluxPublish.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxPublish.java (.../FluxPublish.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -159,6 +159,7 @@ if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.PARENT) return source; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -316,11 +317,13 @@ return; } - done = true; if (!Exceptions.addThrowable(ERROR, this, t)) { Operators.onErrorDroppedMulticast(t, subscribers); + return; } + done = true; + long previousState = markTerminated(this); if (isTerminated(previousState) || isCancelled(previousState)) { return; @@ -402,7 +405,7 @@ boolean add(PublishInner inner) { for (; ; ) { - PubSubInner[] a = subscribers; + FluxPublish.PubSubInner[] a = subscribers; if (a == TERMINATED) { return false; } @@ -940,4 +943,4 @@ return super.scanUnsafe(key); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxPublishMulticast.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxPublishMulticast.java (.../FluxPublishMulticast.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxPublishMulticast.java (.../FluxPublishMulticast.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,8 +78,9 @@ queueSupplier, actual.currentContext()); - Publisher out = Objects.requireNonNull(transform.apply(multicast), - "The transform returned a null Publisher"); + Publisher out = Operators.toFluxOrMono(Objects.requireNonNull( + transform.apply(multicast), + "The transform returned a null Publisher")); if (out instanceof Fuseable) { out.subscribe(new CancelFuseableMulticaster<>(actual, multicast)); Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxPublishOn.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxPublishOn.java (.../FluxPublishOn.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxPublishOn.java (.../FluxPublishOn.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -324,6 +324,12 @@ // In all other modes we are free to discard queue immediately since there is no racing on pooling Operators.onDiscardQueueWithClear(queue, actual.currentContext(), null); } + + if (cancelled) { + Operators.onErrorDropped(ree, actual.currentContext()); + return; + } + actual.onError(Operators.onRejectedExecution(ree, subscription, suppressed, dataSignal, actual.currentContext())); } @@ -884,6 +890,12 @@ // In all other modes we are free to discard queue immediately since there is no racing on pooling Operators.onDiscardQueueWithClear(queue, actual.currentContext(), null); } + + if (cancelled) { + Operators.onErrorDropped(ree, actual.currentContext()); + return; + } + actual.onError(Operators.onRejectedExecution(ree, subscription, suppressed, dataSignal, actual.currentContext())); } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxRange.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxRange.java (.../FluxRange.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxRange.java (.../FluxRange.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class RangeSubscription implements InnerProducer, Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxRepeatWhen.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxRepeatWhen.java (.../FluxRepeatWhen.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxRepeatWhen.java (.../FluxRepeatWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,6 +76,7 @@ return null; } + p = Operators.toFluxOrMono(p); p.subscribe(other); if (!main.cancelled) { @@ -225,6 +226,7 @@ if (key == Attr.PARENT) return main.otherArbiter; if (key == Attr.ACTUAL) return main; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxReplay.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxReplay.java (.../FluxReplay.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxReplay.java (.../FluxReplay.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1209,11 +1209,12 @@ @Override @Nullable - public Object scanUnsafe(Attr key) { + public Object scanUnsafe(Scannable.Attr key) { if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.PARENT) return source; if (key == Attr.RUN_ON) return scheduler; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -1861,4 +1862,4 @@ REQUESTED.addAndGet(this, -n); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxRetry.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxRetry.java (.../FluxRetry.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxRetry.java (.../FluxRetry.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import org.reactivestreams.Publisher; import reactor.core.CorePublisher; import reactor.core.CoreSubscriber; @@ -114,7 +115,9 @@ produced(c); } - source.subscribe(this); + // Not wrapping source, but just the subscriber due to requirements + // in TailCallSubscribeTest#retry + source.subscribe(Operators.restoreContextOnSubscriberIfPublisherNonInternal(source, this)); } while (WIP.decrementAndGet(this) != 0); } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxRetryWhen.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxRetryWhen.java (.../FluxRetryWhen.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxRetryWhen.java (.../FluxRetryWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,12 +53,14 @@ static void subscribe(CoreSubscriber s, Retry whenSourceFactory, CorePublisher source) { + CorePublisher wrapped = Operators.toFluxOrMono(source); + RetryWhenOtherSubscriber other = new RetryWhenOtherSubscriber(); CoreSubscriber serial = Operators.serialize(s); RetryWhenMainSubscriber main = - new RetryWhenMainSubscriber<>(serial, other.completionSignal, source, whenSourceFactory.retryContext()); + new RetryWhenMainSubscriber<>(serial, other.completionSignal, wrapped, whenSourceFactory.retryContext()); other.main = main; serial.onSubscribe(main); @@ -71,10 +73,12 @@ s.onError(Operators.onOperatorError(e, s.currentContext())); return; } + + p = Operators.toFluxOrMono(p); p.subscribe(other); if (!main.cancelled) { - source.subscribe(main); + wrapped.subscribe(main); } } @@ -255,6 +259,7 @@ if (key == Attr.PARENT) return main.otherArbiter; if (key == Attr.ACTUAL) return main; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSample.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSample.java (.../FluxSample.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSample.java (.../FluxSample.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +52,7 @@ FluxSample(Flux source, Publisher other) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSampleFirst.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSampleFirst.java (.../FluxSampleFirst.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSampleFirst.java (.../FluxSampleFirst.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -191,6 +191,7 @@ SampleFirstOther other = new SampleFirstOther<>(this); if (Operators.replace(OTHER, this, other)) { + p = Operators.toFluxOrMono(p); p.subscribe(other); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSampleTimeout.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSampleTimeout.java (.../FluxSampleTimeout.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSampleTimeout.java (.../FluxSampleTimeout.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -207,6 +207,7 @@ SampleTimeoutOther os = new SampleTimeoutOther<>(this, t, idx); if (Operators.replace(OTHER, this, os)) { + p = Operators.toFluxOrMono(p); p.subscribe(os); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSink.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSink.java (.../FluxSink.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSink.java (.../FluxSink.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -105,7 +105,7 @@ * any request to this sink. *

    * For push/pull sinks created using {@link Flux#create(java.util.function.Consumer)} - * or {@link Flux#create(java.util.function.Consumer, OverflowStrategy)}, + * or {@link Flux#create(java.util.function.Consumer, FluxSink.OverflowStrategy)}, * the consumer * is invoked for every request to enable a hybrid backpressure-enabled push/pull model. *

    @@ -118,7 +118,7 @@ * by delivering data to sink only when requests are pending. *

    * For push-only sinks created using {@link Flux#push(java.util.function.Consumer)} - * or {@link Flux#push(java.util.function.Consumer, OverflowStrategy)}, + * or {@link Flux#push(java.util.function.Consumer, FluxSink.OverflowStrategy)}, * the consumer is invoked with an initial request of {@code Long.MAX_VALUE} when this method * is invoked. * @@ -187,4 +187,4 @@ */ BUFFER } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSkipUntilOther.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSkipUntilOther.java (.../FluxSkipUntilOther.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSkipUntilOther.java (.../FluxSkipUntilOther.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ FluxSkipUntilOther(Flux source, Publisher other) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSource.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSource.java (.../FluxSource.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSource.java (.../FluxSource.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -68,11 +68,7 @@ @Override @SuppressWarnings("unchecked") public void subscribe(CoreSubscriber actual) { - if (ContextPropagationSupport.shouldPropagateContextToThreadLocals()) { - source.subscribe(new FluxSourceRestoringThreadLocalsSubscriber<>(actual)); - } else { - source.subscribe(actual); - } + source.subscribe(actual); } @Override @@ -96,97 +92,6 @@ if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.PARENT) return source; if (key == Attr.RUN_STYLE) return Scannable.from(source).scanUnsafe(key); - return null; + return SourceProducer.super.scanUnsafe(key); } - - static final class FluxSourceRestoringThreadLocalsSubscriber - implements Fuseable.ConditionalSubscriber, InnerConsumer { - - final CoreSubscriber actual; - final Fuseable.ConditionalSubscriber actualConditional; - - Subscription s; - - @SuppressWarnings("unchecked") - FluxSourceRestoringThreadLocalsSubscriber(CoreSubscriber actual) { - this.actual = actual; - if (actual instanceof Fuseable.ConditionalSubscriber) { - this.actualConditional = (Fuseable.ConditionalSubscriber) actual; - } - else { - this.actualConditional = null; - } - } - - @Override - @Nullable - public Object scanUnsafe(Attr key) { - if (key == Attr.PARENT) { - return s; - } - if (key == Attr.RUN_STYLE) { - return Attr.RunStyle.SYNC; - } - if (key == Attr.ACTUAL) { - return actual; - } - return null; - } - - @Override - public Context currentContext() { - return actual.currentContext(); - } - - @SuppressWarnings("try") - @Override - public void onSubscribe(Subscription s) { - // This is needed, as the downstream can then switch threads, - // continue the subscription using different primitives and omit this operator - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - actual.onSubscribe(s); - } - } - - @SuppressWarnings("try") - @Override - public void onNext(T t) { - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - actual.onNext(t); - } - } - - @SuppressWarnings("try") - @Override - public boolean tryOnNext(T t) { - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - if (actualConditional != null) { - return actualConditional.tryOnNext(t); - } - actual.onNext(t); - return true; - } - } - - @SuppressWarnings("try") - @Override - public void onError(Throwable t) { - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - actual.onError(t); - } - } - - @SuppressWarnings("try") - @Override - public void onComplete() { - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - actual.onComplete(); - } - } - } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSourceFuseable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSourceFuseable.java (.../FluxSourceFuseable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSourceFuseable.java (.../FluxSourceFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,10 +77,10 @@ @Override @Nullable - public Object scanUnsafe(Attr key) { - if (key == Attr.PREFETCH) return getPrefetch(); - if (key == Attr.PARENT) return source; + public Object scanUnsafe(Scannable.Attr key) { + if (key == Scannable.Attr.PREFETCH) return getPrefetch(); + if (key == Scannable.Attr.PARENT) return source; if (key == Attr.RUN_STYLE) return Scannable.from(source).scanUnsafe(key); - return null; + return SourceProducer.super.scanUnsafe(key); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxStream.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxStream.java (.../FluxStream.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxStream.java (.../FluxStream.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,6 +72,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSubscribeOnCallable.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSubscribeOnCallable.java (.../FluxSubscribeOnCallable.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSubscribeOnCallable.java (.../FluxSubscribeOnCallable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,6 +67,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.RUN_ON) return scheduler; if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSubscribeOnValue.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSubscribeOnValue.java (.../FluxSubscribeOnValue.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSubscribeOnValue.java (.../FluxSubscribeOnValue.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,6 +73,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.RUN_ON) return scheduler; if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -119,7 +120,7 @@ @Override @Nullable - public Object scanUnsafe(Attr key) { + public Object scanUnsafe(Scannable.Attr key) { if (key == Attr.CANCELLED) { return future == OperatorDisposables.DISPOSED; } @@ -298,4 +299,4 @@ } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchIfEmpty.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchIfEmpty.java (.../FluxSwitchIfEmpty.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchIfEmpty.java (.../FluxSwitchIfEmpty.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ FluxSwitchIfEmpty(Flux source, Publisher other) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchMap.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchMap.java (.../FluxSwitchMap.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchMap.java (.../FluxSwitchMap.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -233,6 +233,7 @@ if (INNER.compareAndSet(this, si, innerSubscriber)) { ACTIVE.getAndIncrement(this); + p = Operators.toFluxOrMono(p); p.subscribe(innerSubscriber); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchMapNoPrefetch.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchMapNoPrefetch.java (.../FluxSwitchMapNoPrefetch.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchMapNoPrefetch.java (.../FluxSwitchMapNoPrefetch.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2021-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -215,6 +215,7 @@ return; } + p = Operators.toFluxOrMono(p); p.subscribe(nextInner); } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchOnFirst.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchOnFirst.java (.../FluxSwitchOnFirst.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxSwitchOnFirst.java (.../FluxSwitchOnFirst.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2018-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -519,7 +519,7 @@ return; } - final Publisher outboundPublisher; + Publisher outboundPublisher; final SwitchOnFirstControlSubscriber o = this.outboundSubscriber; try { @@ -542,6 +542,7 @@ return; } + outboundPublisher = Operators.toFluxOrMono(outboundPublisher); outboundPublisher.subscribe(o); return; } @@ -575,7 +576,7 @@ } if (!hasFirstValueReceived(previousState)) { - final Publisher result; + Publisher result; final CoreSubscriber o = this.outboundSubscriber; try { final Signal signal = Signal.error(t, o.currentContext()); @@ -586,6 +587,7 @@ return; } + result = Operators.toFluxOrMono(result); result.subscribe(o); } } @@ -611,7 +613,7 @@ } if (!hasFirstValueReceived(previousState)) { - final Publisher result; + Publisher result; final CoreSubscriber o = this.outboundSubscriber; try { @@ -623,6 +625,7 @@ return; } + result = Operators.toFluxOrMono(result); result.subscribe(o); } } @@ -844,7 +847,7 @@ return true; } - final Publisher result; + Publisher result; final SwitchOnFirstControlSubscriber o = this.outboundSubscriber; try { @@ -868,6 +871,7 @@ return true; } + result = Operators.toFluxOrMono(result); result.subscribe(o); return true; } @@ -1013,7 +1017,7 @@ if (key == Attr.CANCELLED) return hasOutboundCancelled(this.parent.state); if (key == Attr.TERMINATED) return hasOutboundTerminated(this.parent.state); - return null; + return InnerOperator.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxTakeUntilOther.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxTakeUntilOther.java (.../FluxTakeUntilOther.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxTakeUntilOther.java (.../FluxTakeUntilOther.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ FluxTakeUntilOther(Flux source, Publisher other) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxTapFuseable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxTapFuseable.java (.../FluxTapFuseable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxTapFuseable.java (.../FluxTapFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -27,7 +27,7 @@ import reactor.util.context.Context; /** - * A {@link Fuseable} generic per-Subscription side effect {@link Flux} that notifies a + * A {@link reactor.core.Fuseable} generic per-Subscription side effect {@link Flux} that notifies a * {@link SignalListener} of most events. * * @author Simon Baslé @@ -305,4 +305,4 @@ return false; } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxTapRestoringThreadLocals.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxTapRestoringThreadLocals.java (.../FluxTapRestoringThreadLocals.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxTapRestoringThreadLocals.java (.../FluxTapRestoringThreadLocals.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -88,7 +88,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - + if (key == InternalProducerAttr.INSTANCE) return true; return super.scanUnsafe(key); } @@ -130,7 +130,7 @@ if (key == Attr.PARENT) return s; if (key == Attr.TERMINATED) return done; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - + if (key == InternalProducerAttr.INSTANCE) return true; return InnerOperator.super.scanUnsafe(key); } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxTimeout.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxTimeout.java (.../FluxTimeout.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxTimeout.java (.../FluxTimeout.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +56,8 @@ Function> itemTimeout, String timeoutDescription) { super(source); - this.firstTimeout = Objects.requireNonNull(firstTimeout, "firstTimeout"); + this.firstTimeout = Operators.toFluxOrMono(Objects.requireNonNull(firstTimeout, + "firstTimeout")); this.itemTimeout = Objects.requireNonNull(itemTimeout, "itemTimeout"); this.other = null; @@ -69,9 +70,9 @@ Function> itemTimeout, Publisher other) { super(source); - this.firstTimeout = Objects.requireNonNull(firstTimeout, "firstTimeout"); + this.firstTimeout = Operators.toFluxOrMono(Objects.requireNonNull(firstTimeout, "firstTimeout")); this.itemTimeout = Objects.requireNonNull(itemTimeout, "itemTimeout"); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); this.timeoutDescription = null; } @@ -199,7 +200,7 @@ return; } - p.subscribe(ts); + Operators.toFluxOrMono(p).subscribe(ts); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxUsing.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxUsing.java (.../FluxUsing.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxUsing.java (.../FluxUsing.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,7 +119,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class UsingSubscriber Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxUsingWhen.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxUsingWhen.java (.../FluxUsingWhen.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxUsingWhen.java (.../FluxUsingWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2018-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import java.util.Objects; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.function.BiFunction; import java.util.function.Function; @@ -91,6 +90,7 @@ asyncCancel, null); + p = Operators.toFluxOrMono(p); p.subscribe(subscriber); } } @@ -101,13 +101,15 @@ } //trigger the resource creation and delay the subscription to actual - resourceSupplier.subscribe(new ResourceSubscriber(actual, resourceClosure, asyncComplete, asyncError, asyncCancel, resourceSupplier instanceof Mono)); + // + ensure onLastOperatorHook is called by invoking Publisher::subscribe(Subscriber) + ((Publisher) Operators.toFluxOrMono(resourceSupplier)).subscribe( + new ResourceSubscriber(actual, resourceClosure, asyncComplete, asyncError, asyncCancel, resourceSupplier instanceof Mono)); } @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } private static Publisher deriveFluxFromResource( @@ -190,8 +192,9 @@ } resourceProvided = true; - final Publisher p = deriveFluxFromResource(resource, resourceClosure); + Publisher p = deriveFluxFromResource(resource, resourceClosure); + p = Operators.toFluxOrMono(p); p.subscribe(FluxUsingWhen.prepareSubscriberForResource(resource, this.actual, this.asyncComplete, @@ -361,6 +364,7 @@ return; } + p = Operators.toFluxOrMono(p); p.subscribe(new RollbackInner(this, t)); } } @@ -381,6 +385,7 @@ return; } + p = Operators.toFluxOrMono(p); p.subscribe(new CommitInner(this)); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowBoundary.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowBoundary.java (.../FluxWindowBoundary.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowBoundary.java (.../FluxWindowBoundary.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ FluxWindowBoundary(Flux source, Publisher other, Supplier> processorQueueSupplier) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); this.processorQueueSupplier = Objects.requireNonNull(processorQueueSupplier, "processorQueueSupplier"); } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowPredicate.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowPredicate.java (.../FluxWindowPredicate.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowPredicate.java (.../FluxWindowPredicate.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,7 +76,7 @@ int prefetch, Predicate predicate, Mode mode) { - super(source); + super(Flux.from(source)); if (prefetch <= 0) { throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch); } @@ -111,7 +111,7 @@ } static final class WindowPredicateMain - implements QueueSubscription>, + implements Fuseable.QueueSubscription>, InnerOperator> { final CoreSubscriber> actual; @@ -577,7 +577,7 @@ } static final class WindowFlux extends Flux - implements Fuseable, QueueSubscription, InnerOperator { + implements Fuseable, Fuseable.QueueSubscription, InnerOperator { final Queue queue; @@ -922,4 +922,4 @@ } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowTimeout.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowTimeout.java (.../FluxWindowTimeout.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowTimeout.java (.../FluxWindowTimeout.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2017-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ TimeUnit unit, Scheduler timer, boolean fairBackpressure) { - super(source); + super(Flux.from(source)); if (timespan <= 0) { throw new IllegalArgumentException("Timeout period must be strictly positive"); } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowWhen.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowWhen.java (.../FluxWindowWhen.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxWindowWhen.java (.../FluxWindowWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,7 +61,7 @@ Function> end, Supplier> processorQueueSupplier) { super(source); - this.start = Objects.requireNonNull(start, "start"); + this.start = Operators.toFluxOrMono(Objects.requireNonNull(start, "start")); this.end = Objects.requireNonNull(end, "end"); this.processorQueueSupplier = Objects.requireNonNull(processorQueueSupplier, "processorQueueSupplier"); @@ -308,7 +308,7 @@ if (resources.add(cl)) { OPEN_WINDOW_COUNT.getAndIncrement(this); - p.subscribe(cl); + Operators.toFluxOrMono(p).subscribe(cl); } continue; Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxWithLatestFrom.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxWithLatestFrom.java (.../FluxWithLatestFrom.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxWithLatestFrom.java (.../FluxWithLatestFrom.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ Publisher other, BiFunction combiner) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); this.combiner = Objects.requireNonNull(combiner, "combiner"); } Index: 3rdParty_sources/reactor/reactor/core/publisher/FluxZip.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/FluxZip.java (.../FluxZip.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/FluxZip.java (.../FluxZip.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -294,6 +294,8 @@ @Nullable Object[] scalars, int n, int sc) { + Operators.toFluxOrMono(srcs); + if (sc != 0 && scalars != null) { if (n != sc) { ZipSingleCoordinator coordinator = @@ -321,7 +323,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PREFETCH) return prefetch; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class ZipScalarCoordinator implements InnerProducer, Index: 3rdParty_sources/reactor/reactor/core/publisher/GroupedLift.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/GroupedLift.java (.../GroupedLift.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/GroupedLift.java (.../GroupedLift.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,6 +62,9 @@ if (key == Attr.LIFTER) { return liftFunction.name; } + if (key == InternalProducerAttr.INSTANCE) { + return true; + } return null; } @@ -77,7 +80,7 @@ @Override public void subscribe(CoreSubscriber actual) { CoreSubscriber input = - liftFunction.lifter.apply(source, actual); + liftFunction.lifter.apply(source, Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, actual)); Objects.requireNonNull(input, "Lifted subscriber MUST NOT be null"); Index: 3rdParty_sources/reactor/reactor/core/publisher/GroupedLiftFuseable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/GroupedLiftFuseable.java (.../GroupedLiftFuseable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/GroupedLiftFuseable.java (.../GroupedLiftFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,6 +64,9 @@ if (key == Attr.LIFTER) { return liftFunction.name; } + if (key == InternalProducerAttr.INSTANCE) { + return true; + } return null; } @@ -79,16 +82,16 @@ @Override public void subscribe(CoreSubscriber actual) { CoreSubscriber input = - liftFunction.lifter.apply(source, actual); + liftFunction.lifter.apply(source, Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, actual)); Objects.requireNonNull(input, "Lifted subscriber MUST NOT be null"); - if (actual instanceof QueueSubscription + if (actual instanceof Fuseable.QueueSubscription && !(input instanceof QueueSubscription)) { //user didn't produce a QueueSubscription, original was one input = new FluxHide.SuppressFuseableSubscriber<>(input); } //otherwise QS is not required or user already made a compatible conversion source.subscribe(input); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/Hooks.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/Hooks.java (.../Hooks.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/Hooks.java (.../Hooks.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -474,7 +474,7 @@ /** * Reset global data dropped strategy to throwing via {@link - * Exceptions#failWithCancel()} + * reactor.core.Exceptions#failWithCancel()} */ public static void resetOnNextDropped() { log.debug("Reset to factory defaults : onNextDropped"); @@ -801,4 +801,4 @@ public static Queue wrapQueue(Queue queue) { return (Queue) QUEUE_WRAPPER.apply(queue); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/InnerProducer.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/InnerProducer.java (.../InnerProducer.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/InnerProducer.java (.../InnerProducer.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ /** * - * {@link InnerProducer} is a {@link Scannable} {@link Subscription} that produces + * {@link InnerProducer} is a {@link reactor.core.Scannable} {@link Subscription} that produces * data to an {@link #actual()} {@link Subscriber} * * @param output operator produced type @@ -43,7 +43,8 @@ if (key == Attr.ACTUAL) { return actual(); } + if (key == InternalProducerAttr.INSTANCE) return true; return null; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/InternalConnectableFluxOperator.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/InternalConnectableFluxOperator.java (.../InternalConnectableFluxOperator.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/InternalConnectableFluxOperator.java (.../InternalConnectableFluxOperator.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,9 +87,10 @@ @Override @Nullable - public Object scanUnsafe(Attr key) { - if (key == Attr.PREFETCH) return getPrefetch(); - if (key == Attr.PARENT) return source; + public Object scanUnsafe(Scannable.Attr key) { + if (key == Scannable.Attr.PREFETCH) return getPrefetch(); + if (key == Scannable.Attr.PARENT) return source; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/InternalFluxOperator.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/InternalFluxOperator.java (.../InternalFluxOperator.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/InternalFluxOperator.java (.../InternalFluxOperator.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,12 +54,18 @@ while (true) { subscriber = operator.subscribeOrReturn(subscriber); if (subscriber == null) { + // if internally subscribed, it means the optimized operator is + // already within the internals and subscribing up the chain will + // at some point need to consider the source and wrap it + // null means "I will subscribe myself", returning... return; } OptimizableOperator newSource = operator.nextOptimizableSource(); if (newSource == null) { - operator.source().subscribe(subscriber); + CorePublisher operatorSource = operator.source(); + subscriber = Operators.restoreContextOnSubscriberIfPublisherNonInternal(operatorSource, subscriber); + operatorSource.subscribe(subscriber); return; } operator = newSource; @@ -89,7 +95,8 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.PARENT) return source; - return null; + if (key == InternalProducerAttr.INSTANCE) return true; + return super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/InternalMonoOperator.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/InternalMonoOperator.java (.../InternalMonoOperator.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/InternalMonoOperator.java (.../InternalMonoOperator.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,19 +49,31 @@ } @Override + public Object scanUnsafe(Attr key) { + if (key == InternalProducerAttr.INSTANCE) return true; + return super.scanUnsafe(key); + } + + @Override @SuppressWarnings("unchecked") public final void subscribe(CoreSubscriber subscriber) { OptimizableOperator operator = this; try { while (true) { subscriber = operator.subscribeOrReturn(subscriber); if (subscriber == null) { + // if internally subscribed, it means the optimized operator is + // already within the internals and subscribing up the chain will + // at some point need to consider the source and wrap it + // null means "I will subscribe myself", returning... return; } OptimizableOperator newSource = operator.nextOptimizableSource(); if (newSource == null) { - operator.source().subscribe(subscriber); + CorePublisher operatorSource = operator.source(); + subscriber = Operators.restoreContextOnSubscriberIfPublisherNonInternal(operatorSource, subscriber); + operatorSource.subscribe(subscriber); return; } operator = newSource; Index: 3rdParty_sources/reactor/reactor/core/publisher/InternalProducerAttr.java =================================================================== diff -u --- 3rdParty_sources/reactor/reactor/core/publisher/InternalProducerAttr.java (revision 0) +++ 3rdParty_sources/reactor/reactor/core/publisher/InternalProducerAttr.java (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 VMware Inc. or its affiliates, All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package reactor.core.publisher; + +import reactor.core.Scannable; + +class InternalProducerAttr extends Scannable.Attr { + + private InternalProducerAttr(Boolean defaultValue) { + super(defaultValue); + } + + static final InternalProducerAttr INSTANCE = new InternalProducerAttr(true); +} Index: 3rdParty_sources/reactor/reactor/core/publisher/Mono.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/Mono.java (.../Mono.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/Mono.java (.../Mono.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2024 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,6 +115,7 @@ * @author Stephane Maldini * @author David Karnok * @author Simon Baslé + * @author Injae Kim * @see Flux */ public abstract class Mono implements CorePublisher { @@ -480,18 +481,26 @@ public static Mono from(Publisher source) { //some sources can be considered already assembled monos //all conversion methods (from, fromDirect, wrap) must accommodate for this - if (source instanceof Mono) { + boolean shouldWrap = ContextPropagationSupport.shouldWrapPublisher(source); + if (source instanceof Mono && !shouldWrap) { @SuppressWarnings("unchecked") Mono casted = (Mono) source; return casted; } + if (source instanceof FluxSourceMono || source instanceof FluxSourceMonoFuseable) { @SuppressWarnings("unchecked") FluxFromMonoOperator wrapper = (FluxFromMonoOperator) source; @SuppressWarnings("unchecked") Mono extracted = (Mono) wrapper.source; - return extracted; + boolean shouldWrapExtracted = ContextPropagationSupport.shouldWrapPublisher(extracted); + if (!shouldWrapExtracted) { + return extracted; + } else { + // Skip assembly hook + return wrap(extracted, false); + } } //we delegate to `wrap` and apply assembly hooks @@ -573,7 +582,8 @@ public static Mono fromDirect(Publisher source){ //some sources can be considered already assembled monos //all conversion methods (from, fromDirect, wrap) must accommodate for this - if(source instanceof Mono){ + boolean shouldWrap = ContextPropagationSupport.shouldWrapPublisher(source); + if (source instanceof Mono && !shouldWrap) { @SuppressWarnings("unchecked") Mono m = (Mono)source; return m; @@ -584,7 +594,14 @@ FluxFromMonoOperator wrapper = (FluxFromMonoOperator) source; @SuppressWarnings("unchecked") Mono extracted = (Mono) wrapper.source; - return extracted; + boolean shouldWrapExtracted = + ContextPropagationSupport.shouldWrapPublisher(extracted); + if (!shouldWrapExtracted) { + return extracted; + } else { + // Skip assembly hook + return wrap(extracted, false); + } } //we delegate to `wrap` and apply assembly hooks @@ -896,8 +913,58 @@ return using(resourceSupplier, sourceSupplier, resourceCleanup, true); } + /** + * Uses an {@link AutoCloseable} resource, generated by a supplier for each individual Subscriber, + * while streaming the value from a Mono derived from the same resource and makes sure + * the resource is released if the sequence terminates or the Subscriber cancels. + *

    + * Unlike in {@link Flux#using(Callable, Function, Consumer) Flux}, in the case of a valued {@link Mono} the cleanup + * happens just before passing the value to downstream. In all cases, exceptions raised by the cleanup + * {@link Consumer} may override the terminal event, discarding the element if the derived {@link Mono} was valued. + *

    + * + * + * @param resourceSupplier a {@link Callable} that is called on subscribe to create the resource + * @param sourceSupplier a {@link Mono} factory to create the Mono depending on the created resource + * @param emitted type + * @param resource type + * + * @return new {@link Mono} + */ + public static Mono using(Callable resourceSupplier, + Function> sourceSupplier) { + return using(resourceSupplier, sourceSupplier, true); + } /** + * Uses an {@link AutoCloseable} resource, generated by a supplier for each individual Subscriber, + * while streaming the value from a Mono derived from the same resource and makes sure + * the resource is released if the sequence terminates or the Subscriber cancels. + *

    + *

      + *
    • For eager cleanup, Unlike in {@link Flux#using(Callable, Function, Consumer) Flux}, + * in the case of a valued {@link Mono} the cleanup happens just before passing the value to downstream. + * In all cases, exceptions raised by the cleanup {@link Consumer} may override the terminal event, + * discarding the element if the derived {@link Mono} was valued.
    • + *
    • Non-eager cleanup will drop any exception.
    • + *
    + *

    + * + * + * @param resourceSupplier a {@link Callable} that is called on subscribe to create the resource + * @param sourceSupplier a {@link Mono} factory to create the Mono depending on the created resource + * @param eager set to true to clean before any signal (including onNext) is passed downstream + * @param emitted type + * @param resource type + * + * @return new {@link Mono} + */ + public static Mono using(Callable resourceSupplier, + Function> sourceSupplier, boolean eager) { + return using(resourceSupplier, sourceSupplier, Exceptions.AUTO_CLOSE, eager); + } + + /** * Uses a resource, generated by a {@link Publisher} for each individual {@link Subscriber}, * to derive a {@link Mono}. Note that all steps of the operator chain that would need the * resource to be in an open stable state need to be described inside the {@code resourceClosure} @@ -1717,7 +1784,8 @@ * received or a timeout expires. Returns that value, or null if the Mono completes * empty. In case the Mono errors, the original exception is thrown (wrapped in a * {@link RuntimeException} if it was a checked exception). - * If the provided timeout expires, a {@link RuntimeException} is thrown. + * If the provided timeout expires, a {@link RuntimeException} is thrown + * with a {@link TimeoutException} as the cause. * *

    * @@ -1726,6 +1794,7 @@ * might miss signal from hot publishers. * * @param timeout maximum time period to wait for before raising a {@link RuntimeException} + * with a {@link TimeoutException} as the cause * * @return T the result */ @@ -1769,7 +1838,8 @@ * Exception via {@link Optional#orElseThrow(Supplier)}. * In case the Mono itself errors, the original exception is thrown (wrapped in a * {@link RuntimeException} if it was a checked exception). - * If the provided timeout expires, a {@link RuntimeException} is thrown. + * If the provided timeout expires, a {@link RuntimeException} is thrown + * with a {@link TimeoutException} as the cause. * *

    * @@ -1778,6 +1848,7 @@ * might miss signal from hot publishers. * * @param timeout maximum time period to wait for before raising a {@link RuntimeException} + * with a {@link TimeoutException} as the cause * * @return T the result */ @@ -2853,7 +2924,7 @@ } /** - * Map this {@link Mono} into {@link Tuple2 Tuple2<Long, T>} + * Map this {@link Mono} into {@link reactor.util.function.Tuple2 Tuple2<Long, T>} * of timemillis and source data. The timemillis corresponds to the elapsed time between * the subscribe and the first next signal, as measured by the {@link Schedulers#parallel() parallel} scheduler. * @@ -2868,7 +2939,7 @@ } /** - * Map this {@link Mono} sequence into {@link Tuple2 Tuple2<Long, T>} + * Map this {@link Mono} sequence into {@link reactor.util.function.Tuple2 Tuple2<Long, T>} * of timemillis and source data. The timemillis corresponds to the elapsed time between the subscribe and the first * next signal, as measured by the provided {@link Scheduler}. * @@ -3478,7 +3549,7 @@ * The name serves as a prefix in the reported metrics names. In case no name has been provided, the default name "reactor" will be applied. *

    * The {@link MeterRegistry} used by reactor can be configured via - * {@link Metrics.MicrometerConfiguration#useRegistry(MeterRegistry)} + * {@link reactor.util.Metrics.MicrometerConfiguration#useRegistry(MeterRegistry)} * prior to using this operator, the default being * {@link io.micrometer.core.instrument.Metrics#globalRegistry}. *

    @@ -4157,7 +4228,7 @@ * The companion is generated by the provided {@link Retry} instance, see {@link Retry#max(long)}, {@link Retry#maxInARow(long)} * and {@link Retry#backoff(long, Duration)} for readily available strategy builders. *

    - * The operator generates a base for the companion, a {@link Flux} of {@link Retry.RetrySignal} + * The operator generates a base for the companion, a {@link Flux} of {@link reactor.util.retry.Retry.RetrySignal} * which each give metadata about each retryable failure whenever this {@link Mono} signals an error. The final companion * should be derived from that base companion and emit data in response to incoming onNext (although it can emit less * elements, or delay the emissions). @@ -4167,11 +4238,11 @@ *

    * *

    - * Note that the {@link Retry.RetrySignal} state can be transient and change between each source + * Note that the {@link reactor.util.retry.Retry.RetrySignal} state can be transient and change between each source * {@link org.reactivestreams.Subscriber#onError(Throwable) onError} or * {@link org.reactivestreams.Subscriber#onNext(Object) onNext}. If processed with a delay, * this could lead to the represented state being out of sync with the state at which the retry - * was evaluated. Map it to {@link Retry.RetrySignal#copy()} right away to mediate this. + * was evaluated. Map it to {@link reactor.util.retry.Retry.RetrySignal#copy()} right away to mediate this. *

    * Note that if the companion {@link Publisher} created by the {@code whenFactory} * emits {@link Context} as trigger objects, these {@link Context} will be merged with @@ -4196,7 +4267,7 @@ * * * @param retrySpec the {@link Retry} strategy that will generate the companion {@link Publisher}, - * given a {@link Flux} that signals each onError as a {@link Retry.RetrySignal}. + * given a {@link Flux} that signals each onError as a {@link reactor.util.retry.Retry.RetrySignal}. * * @return a {@link Mono} that retries on onError when a companion {@link Publisher} produces an onNext signal * @see Retry#max(long) @@ -4210,9 +4281,10 @@ /** * Prepare a {@link Mono} which shares this {@link Mono} result similar to {@link Flux#shareNext()}. * This will effectively turn this {@link Mono} into a hot task when the first - * {@link Subscriber} subscribes using {@link #subscribe()} API. Further {@link Subscriber} will share the same {@link Subscription} + * {@link Subscriber} subscribes using {@link #subscribe()} API. + * Further {@link Subscriber} will share the same {@link Subscription} * and therefore the same result. - * It's worth noting this is an un-cancellable {@link Subscription}. + * When all subscribers have cancelled it will cancel the source {@link Mono}. *

    * * @@ -4231,7 +4303,7 @@ /** * Expect exactly one item from this {@link Mono} source or signal - * {@link NoSuchElementException} for an empty source. + * {@link java.util.NoSuchElementException} for an empty source. *

    * *

    @@ -4327,7 +4399,7 @@ * Subscribe a {@link Consumer} to this {@link Mono} that will consume all the * sequence. It will request an unbounded demand ({@code Long.MAX_VALUE}). *

    - * For a passive version that observe and forward incoming data see {@link #doOnNext(Consumer)}. + * For a passive version that observe and forward incoming data see {@link #doOnNext(java.util.function.Consumer)}. *

    * Keep in mind that since the sequence can be asynchronous, this will immediately * return control to the calling thread. This can give the impression the consumer is @@ -4351,7 +4423,7 @@ * The subscription will request an unbounded demand ({@code Long.MAX_VALUE}). *

    * For a passive version that observe and forward incoming data see {@link #doOnSuccess(Consumer)} and - * {@link #doOnError(Consumer)}. + * {@link #doOnError(java.util.function.Consumer)}. *

    * Keep in mind that since the sequence can be asynchronous, this will immediately * return control to the calling thread. This can give the impression the consumer is @@ -4376,7 +4448,7 @@ * will request unbounded demand ({@code Long.MAX_VALUE}). *

    * For a passive version that observe and forward incoming data see {@link #doOnSuccess(Consumer)} and - * {@link #doOnError(Consumer)}. + * {@link #doOnError(java.util.function.Consumer)}. *

    * Keep in mind that since the sequence can be asynchronous, this will immediately * return control to the calling thread. This can give the impression the consumer is @@ -4406,7 +4478,7 @@ * {@code Long.MAX_VALUE} if no such consumer is provided. *

    * For a passive version that observe and forward incoming data see {@link #doOnSuccess(Consumer)} and - * {@link #doOnError(Consumer)}. + * {@link #doOnError(java.util.function.Consumer)}. *

    * Keep in mind that since the sequence can be asynchronous, this will immediately * return control to the calling thread. This can give the impression the consumer is @@ -4438,7 +4510,7 @@ * is tied to the subscription. At subscription, an unbounded request is implicitly made. *

    * For a passive version that observe and forward incoming data see {@link #doOnSuccess(Consumer)} and - * {@link #doOnError(Consumer)}. + * {@link #doOnError(java.util.function.Consumer)}. *

    * Keep in mind that since the sequence can be asynchronous, this will immediately * return control to the calling thread. This can give the impression the consumer is @@ -4492,6 +4564,7 @@ } } + subscriber = Operators.restoreContextOnSubscriberIfPublisherNonInternal(publisher, subscriber); publisher.subscribe(subscriber); } catch (Throwable e) { @@ -4521,7 +4594,7 @@ * * *

    -	 * {@code mono.subscribeOn(Schedulers.parallel()).subscribe()) }
    +	 * {@code mono.subscribeOn(Schedulers.parallel()).subscribe() }
     	 * 
    * * @param scheduler a {@link Scheduler} providing the {@link Worker} where to subscribe @@ -5024,7 +5097,7 @@ } /** - * If this {@link Mono} is valued, emit a {@link Tuple2} pair of + * If this {@link Mono} is valued, emit a {@link reactor.util.function.Tuple2} pair of * T1 the current clock time in millis (as a {@link Long} measured by the * {@link Schedulers#parallel() parallel} Scheduler) and T2 the emitted data (as a {@code T}). * @@ -5039,7 +5112,7 @@ } /** - * If this {@link Mono} is valued, emit a {@link Tuple2} pair of + * If this {@link Mono} is valued, emit a {@link reactor.util.function.Tuple2} pair of * T1 the current clock time in millis (as a {@link Long} measured by the * provided {@link Scheduler}) and T2 the emitted data (as a {@code T}). * @@ -5324,52 +5397,67 @@ * Note that this bypasses {@link Hooks#onEachOperator(String, Function) assembly hooks}. * * @param source the {@link Publisher} to wrap - * @param enforceMonoContract {@code} true to wrap publishers without assumption about their cardinality + * @param enforceMonoContract {@code true} to wrap publishers without assumption about their cardinality * (first {@link Subscriber#onNext(Object)} will cancel the source), {@code false} to behave like {@link #fromDirect(Publisher)}. * @param input upstream type * @return a wrapped {@link Mono} */ static Mono wrap(Publisher source, boolean enforceMonoContract) { //some sources can be considered already assembled monos //all conversion methods (from, fromDirect, wrap) must accommodate for this + boolean shouldWrap = ContextPropagationSupport.shouldWrapPublisher(source); if (source instanceof Mono) { - return (Mono) source; + if (!shouldWrap) { + return (Mono) source; + } + return ContextPropagation.monoRestoreThreadLocals((Mono) source); } - if (source instanceof FluxSourceMono - || source instanceof FluxSourceMonoFuseable) { - @SuppressWarnings("unchecked") - Mono extracted = (Mono) ((FluxFromMonoOperator) source).source; - return extracted; + + if (source instanceof FluxSourceMono || source instanceof FluxSourceMonoFuseable) { + @SuppressWarnings("unchecked") Mono extracted = + (Mono) ((FluxFromMonoOperator) source).source; + boolean shouldWrapExtracted = + ContextPropagationSupport.shouldWrapPublisher(extracted); + if (!shouldWrapExtracted) { + return extracted; + } + return ContextPropagation.monoRestoreThreadLocals(extracted); } + if (source instanceof Flux && source instanceof Callable) { + @SuppressWarnings("unchecked") Callable m = (Callable) source; + return Flux.wrapToMono(m); + } + + Mono target; + //equivalent to what from used to be, without assembly hooks if (enforceMonoContract) { - if (source instanceof Flux && source instanceof Callable) { - @SuppressWarnings("unchecked") Callable m = (Callable) source; - return Flux.wrapToMono(m); - } if (source instanceof Flux) { - return new MonoNext<>((Flux) source); + target = new MonoNext<>((Flux) source); + } else { + target = new MonoFromPublisher<>(source); } - return new MonoFromPublisher<>(source); + //equivalent to what fromDirect used to be without onAssembly + } else if (source instanceof Flux && source instanceof Fuseable) { + target = new MonoSourceFluxFuseable<>((Flux) source); + } else if (source instanceof Flux) { + target = new MonoSourceFlux<>((Flux) source); + } else if (source instanceof Fuseable) { + target = new MonoSourceFuseable<>(source); + } else { + target = new MonoSource<>(source); } - //equivalent to what fromDirect used to be without onAssembly - if(source instanceof Flux && source instanceof Fuseable) { - return new MonoSourceFluxFuseable<>((Flux) source); + if (shouldWrap) { + return ContextPropagation.monoRestoreThreadLocals(target); } - if (source instanceof Flux) { - return new MonoSourceFlux<>((Flux) source); - } - if(source instanceof Fuseable) { - return new MonoSourceFuseable<>(source); - } - return new MonoSource<>(source); + return target; } @SuppressWarnings("unchecked") static BiPredicate equalsBiPredicate(){ return EQUALS_BIPREDICATE; } static final BiPredicate EQUALS_BIPREDICATE = Object::equals; -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoCacheInvalidateWhen.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoCacheInvalidateWhen.java (.../MonoCacheInvalidateWhen.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoCacheInvalidateWhen.java (.../MonoCacheInvalidateWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2021-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -282,6 +282,9 @@ for (@SuppressWarnings("unchecked") CacheMonoSubscriber inner : SUBSCRIBERS.getAndSet(this, COORDINATOR_DONE)) { inner.complete(value); } + // even though the trigger can deliver values on different threads, + // it's not causing any delivery to downstream, so we don't need to + // wrap it invalidateTrigger.subscribe(new TriggerSubscriber(this.main)); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoCallable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoCallable.java (.../MonoCallable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoCallable.java (.../MonoCallable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,7 +75,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static class MonoCallableSubscription Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoCompletionStage.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoCompletionStage.java (.../MonoCompletionStage.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoCompletionStage.java (.../MonoCompletionStage.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -52,19 +52,15 @@ @Override public void subscribe(CoreSubscriber actual) { - if (ContextPropagationSupport.shouldPropagateContextToThreadLocals()) { - actual.onSubscribe( - new MonoCompletionStageRestoringThreadLocalsSubscription<>( - actual, future, suppressCancellation)); - } else { - actual.onSubscribe(new MonoCompletionStageSubscription<>( - actual, future, suppressCancellation)); - } + CoreSubscriber wrapped = Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); + wrapped.onSubscribe(new MonoCompletionStageSubscription<>( + wrapped, future, suppressCancellation)); } @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -165,108 +161,4 @@ } } } - - static class MonoCompletionStageRestoringThreadLocalsSubscription - implements InnerProducer, BiFunction { - - final CoreSubscriber actual; - final CompletionStage future; - final boolean suppressCancellation; - - volatile int requestedOnce; - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater REQUESTED_ONCE = - AtomicIntegerFieldUpdater.newUpdater(MonoCompletionStageRestoringThreadLocalsSubscription.class, "requestedOnce"); - - volatile boolean cancelled; - - MonoCompletionStageRestoringThreadLocalsSubscription( - CoreSubscriber actual, - CompletionStage future, - boolean suppressCancellation) { - this.actual = actual; - this.future = future; - this.suppressCancellation = suppressCancellation; - } - - @Override - public CoreSubscriber actual() { - return this.actual; - } - - @Override - public Void apply(@Nullable T value, @Nullable Throwable e) { - final CoreSubscriber actual = this.actual; - - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - if (this.cancelled) { - //nobody is interested in the Mono anymore, don't risk dropping errors - final Context ctx = actual.currentContext(); - if (e == null || e instanceof CancellationException) { - //we discard any potential value and ignore Future cancellations - Operators.onDiscard(value, ctx); - } - else { - //we make sure we keep _some_ track of a Future failure AFTER the Mono cancellation - Operators.onErrorDropped(e, ctx); - //and we discard any potential value just in case both e and v are not null - Operators.onDiscard(value, ctx); - } - - return null; - } - - try { - if (e instanceof CompletionException) { - actual.onError(e.getCause()); - } - else if (e != null) { - actual.onError(e); - } - else if (value != null) { - actual.onNext(value); - actual.onComplete(); - } - else { - actual.onComplete(); - } - } - catch (Throwable e1) { - Operators.onErrorDropped(e1, actual.currentContext()); - throw Exceptions.bubble(e1); - } - return null; - } - } - - @Override - public void request(long n) { - if (this.cancelled) { - return; - } - - if (this.requestedOnce == 1 || !REQUESTED_ONCE.compareAndSet(this, 0 , 1)) { - return; - } - - future.handle(this); - } - - @Override - public void cancel() { - this.cancelled = true; - - final CompletionStage future = this.future; - if (!suppressCancellation && future instanceof Future) { - try { - //noinspection unchecked - ((Future) future).cancel(true); - } - catch (Throwable t) { - Operators.onErrorDropped(t, this.actual.currentContext()); - } - } - } - } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoContextWriteRestoringThreadLocals.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoContextWriteRestoringThreadLocals.java (.../MonoContextWriteRestoringThreadLocals.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoContextWriteRestoringThreadLocals.java (.../MonoContextWriteRestoringThreadLocals.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -48,6 +48,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return super.scanUnsafe(key); } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoCreate.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoCreate.java (.../MonoCreate.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoCreate.java (.../MonoCreate.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,22 +50,26 @@ @Override public void subscribe(CoreSubscriber actual) { - DefaultMonoSink emitter = new DefaultMonoSink<>(actual); + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); - actual.onSubscribe(emitter); + DefaultMonoSink emitter = new DefaultMonoSink<>(wrapped); + wrapped.onSubscribe(emitter); + try { callback.accept(emitter); } catch (Throwable ex) { - emitter.error(Operators.onOperatorError(ex, actual.currentContext())); + emitter.error(Operators.onOperatorError(ex, wrapped.currentContext())); } } @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; - return null; + if (key == InternalProducerAttr.INSTANCE) return true; + return SourceProducer.super.scanUnsafe(key); } static final class DefaultMonoSink extends AtomicBoolean Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoCurrentContext.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoCurrentContext.java (.../MonoCurrentContext.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoCurrentContext.java (.../MonoCurrentContext.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoDefer.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoDefer.java (.../MonoDefer.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoDefer.java (.../MonoDefer.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -50,12 +50,12 @@ return; } - p.subscribe(actual); + fromDirect(p).subscribe(actual); } @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoDeferContextual.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoDeferContextual.java (.../MonoDeferContextual.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoDeferContextual.java (.../MonoDeferContextual.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,12 +52,12 @@ return; } - p.subscribe(actual); + Operators.toFluxOrMono(p).subscribe(actual); } @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; //no particular key to be represented, still useful in hooks + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoDelay.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoDelay.java (.../MonoDelay.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoDelay.java (.../MonoDelay.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,8 +71,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.RUN_ON) return timedScheduler; if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; - - return null; + return SourceProducer.super.scanUnsafe(key); } static final class MonoDelayRunnable implements Runnable, InnerProducer { Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoDelaySubscription.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoDelaySubscription.java (.../MonoDelaySubscription.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoDelaySubscription.java (.../MonoDelaySubscription.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ MonoDelaySubscription(Mono source, Publisher other) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoDelayUntil.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoDelayUntil.java (.../MonoDelayUntil.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoDelayUntil.java (.../MonoDelayUntil.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2017-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -94,7 +94,7 @@ @Override public void subscribe(CoreSubscriber actual) { try { - source.subscribe(subscribeOrReturn(actual)); + Operators.toFluxOrMono(source).subscribe(subscribeOrReturn(actual)); } catch (Throwable e) { Operators.error(actual, Operators.onOperatorError(e, actual.currentContext())); @@ -123,6 +123,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; //no particular key to be represented, still useful in hooks } @@ -286,7 +287,7 @@ final Function> generator = this.otherGenerators[this.index]; - final Publisher p; + Publisher p; try { p = generator.apply(this.value); @@ -303,6 +304,7 @@ this.triggerSubscriber = triggerSubscriber; } + p = Operators.toFluxOrMono(p); p.subscribe(triggerSubscriber); } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoDoOnEachFuseable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoDoOnEachFuseable.java (.../MonoDoOnEachFuseable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoDoOnEachFuseable.java (.../MonoDoOnEachFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -23,7 +23,7 @@ import reactor.core.Fuseable; /** - * Peek into the lifecycle events and signals of a sequence, {@link Fuseable} + * Peek into the lifecycle events and signals of a sequence, {@link reactor.core.Fuseable} * version of {@link MonoDoOnEach}. * * @param the value type @@ -49,4 +49,4 @@ if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; return super.scanUnsafe(key); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoEmpty.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoEmpty.java (.../MonoEmpty.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoEmpty.java (.../MonoEmpty.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,6 +78,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoError.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoError.java (.../MonoError.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoError.java (.../MonoError.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,6 +64,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoErrorSupplied.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoErrorSupplied.java (.../MonoErrorSupplied.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoErrorSupplied.java (.../MonoErrorSupplied.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,6 +68,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoFilterWhen.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoFilterWhen.java (.../MonoFilterWhen.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoFilterWhen.java (.../MonoFilterWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2017-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,6 +143,7 @@ } else { FilterWhenInner inner = new FilterWhenInner<>(this, !(p instanceof Mono), t); + p = Operators.toFluxOrMono(p); p.subscribe(inner); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoFirstWithSignal.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoFirstWithSignal.java (.../MonoFirstWithSignal.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoFirstWithSignal.java (.../MonoFirstWithSignal.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -136,11 +136,14 @@ actual.currentContext())); } else { + p = Operators.toFluxOrMono(p); p.subscribe(actual); } return; } + Operators.toFluxOrMono(a); + FluxFirstWithSignal.RaceCoordinator coordinator = new FluxFirstWithSignal.RaceCoordinator<>(n); @@ -150,7 +153,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } \ No newline at end of file Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoFirstWithValue.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoFirstWithValue.java (.../MonoFirstWithValue.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoFirstWithValue.java (.../MonoFirstWithValue.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -147,7 +147,7 @@ return; } if (n == 1) { - Publisher p = a[0]; + Publisher p = Mono.from(a[0]); if (p == null) { Operators.error(actual, @@ -169,6 +169,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoFlatMap.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoFlatMap.java (.../MonoFlatMap.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoFlatMap.java (.../MonoFlatMap.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -162,7 +162,7 @@ } try { - m.subscribe(new FlatMapInner<>(this)); + Mono.fromDirect(m).subscribe(new FlatMapInner<>(this)); } catch (Throwable e) { actual.onError(Operators.onOperatorError(this, e, t, Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoFlatMapMany.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoFlatMapMany.java (.../MonoFlatMapMany.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoFlatMapMany.java (.../MonoFlatMapMany.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -192,6 +192,7 @@ return; } + p = Operators.toFluxOrMono(p); p.subscribe(new FlatMapManyInner<>(this, actual)); } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoFromFluxOperator.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoFromFluxOperator.java (.../MonoFromFluxOperator.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoFromFluxOperator.java (.../MonoFromFluxOperator.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,6 +62,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PREFETCH) return Integer.MAX_VALUE; if (key == Attr.PARENT) return source; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -78,6 +79,7 @@ } OptimizableOperator newSource = operator.nextOptimizableSource(); if (newSource == null) { + subscriber = Operators.restoreContextOnSubscriberIfPublisherNonInternal(operator.source(), subscriber); operator.source().subscribe(subscriber); return; } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoFromPublisher.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoFromPublisher.java (.../MonoFromPublisher.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoFromPublisher.java (.../MonoFromPublisher.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -55,15 +55,12 @@ @Override @SuppressWarnings("unchecked") public void subscribe(CoreSubscriber actual) { - if (ContextPropagationSupport.shouldPropagateContextToThreadLocals()) { - actual = new MonoSource.MonoSourceRestoringThreadLocalsSubscriber<>(actual); - } - try { CoreSubscriber subscriber = subscribeOrReturn(actual); if (subscriber == null) { return; } + subscriber = Operators.restoreContextOnSubscriberIfPublisherNonInternal(source, subscriber); source.subscribe(subscriber); } catch (Throwable e) { @@ -89,13 +86,16 @@ @Override @Nullable - public Object scanUnsafe(Attr key) { - if (key == Attr.PARENT) { + public Object scanUnsafe(Scannable.Attr key) { + if (key == Scannable.Attr.PARENT) { return source; } - if (key == Attr.RUN_STYLE) { + if (key == Scannable.Attr.RUN_STYLE) { return Attr.RunStyle.SYNC; } + if (key == InternalProducerAttr.INSTANCE) { + return true; + } return null; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoIgnorePublisher.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoIgnorePublisher.java (.../MonoIgnorePublisher.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoIgnorePublisher.java (.../MonoIgnorePublisher.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ final OptimizableOperator optimizableOperator; MonoIgnorePublisher(Publisher source) { - this.source = Objects.requireNonNull(source, "publisher"); + this.source = Operators.toFluxOrMono(Objects.requireNonNull(source, "publisher")); if (source instanceof OptimizableOperator) { @SuppressWarnings("unchecked") OptimizableOperator optimSource = (OptimizableOperator) source; @@ -79,13 +79,16 @@ @Override @Nullable - public Object scanUnsafe(Attr key) { - if (key == Attr.PARENT) { + public Object scanUnsafe(Scannable.Attr key) { + if (key == Scannable.Attr.PARENT) { return source; } if (key == Attr.RUN_STYLE) { return Attr.RunStyle.SYNC; } + if (key == InternalProducerAttr.INSTANCE) { + return true; + } return null; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoIgnoreThen.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoIgnoreThen.java (.../MonoIgnoreThen.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoIgnoreThen.java (.../MonoIgnoreThen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,6 +71,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -237,19 +238,19 @@ } onComplete(); } else { - m.subscribe(this); + Operators.toFluxOrMono(m).subscribe(this); } return; } else { - final Publisher m = a[i]; + Publisher p = a[i]; - if (m instanceof Callable) { + if (p instanceof Callable) { if (isCancelled(this.state)) { //NB: in the non-callable case, this is handled by activeSubscription.cancel() return; } try { - Operators.onDiscard(((Callable) m).call(), currentContext()); + Operators.onDiscard(((Callable) p).call(), currentContext()); } catch (Throwable ex) { onError(Operators.onOperatorError(ex, currentContext())); @@ -260,7 +261,8 @@ continue; } - m.subscribe((CoreSubscriber) this); + p = Operators.toFluxOrMono(p); + p.subscribe((CoreSubscriber) this); return; } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoJust.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoJust.java (.../MonoJust.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoJust.java (.../MonoJust.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2015-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,6 +59,6 @@ public Object scanUnsafe(Attr key) { if (key == Attr.BUFFERED) return 1; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoLift.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoLift.java (.../MonoLift.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoLift.java (.../MonoLift.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ @Override public CoreSubscriber subscribeOrReturn(CoreSubscriber actual) { CoreSubscriber input = - liftFunction.lifter.apply(source, actual); + liftFunction.lifter.apply(source, Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, actual)); Objects.requireNonNull(input, "Lifted subscriber MUST NOT be null"); Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoLiftFuseable.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoLiftFuseable.java (.../MonoLiftFuseable.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoLiftFuseable.java (.../MonoLiftFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,9 +55,8 @@ @Override public CoreSubscriber subscribeOrReturn(CoreSubscriber actual) { + CoreSubscriber input = liftFunction.lifter.apply(source, Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, actual)); - CoreSubscriber input = liftFunction.lifter.apply(source, actual); - Objects.requireNonNull(input, "Lifted subscriber MUST NOT be null"); if (actual instanceof QueueSubscription Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoMetricsFuseable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoMetricsFuseable.java (.../MonoMetricsFuseable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoMetricsFuseable.java (.../MonoMetricsFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -76,7 +76,7 @@ int mode; @Nullable - QueueSubscription qs; + Fuseable.QueueSubscription qs; MetricsFuseableSubscriber(CoreSubscriber actual, MeterRegistry registry, @@ -196,4 +196,4 @@ } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoNever.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoNever.java (.../MonoNever.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoNever.java (.../MonoNever.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } /** Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoOperator.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoOperator.java (.../MonoOperator.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoOperator.java (.../MonoOperator.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,8 @@ package reactor.core.publisher; import java.util.Objects; -import java.util.function.BiFunction; -import java.util.function.Function; - import org.reactivestreams.Publisher; -import reactor.core.CoreSubscriber; import reactor.core.Scannable; import reactor.util.annotation.Nullable; @@ -51,6 +47,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PREFETCH) return Integer.MAX_VALUE; if (key == Attr.PARENT) return source; + if (key == InternalProducerAttr.INSTANCE) return false; // public class! return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoPeekTerminal.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoPeekTerminal.java (.../MonoPeekTerminal.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoPeekTerminal.java (.../MonoPeekTerminal.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -84,7 +84,7 @@ */ static final class MonoTerminalPeekSubscriber implements ConditionalSubscriber, InnerOperator, - QueueSubscription { + Fuseable.QueueSubscription { final CoreSubscriber actual; final ConditionalSubscriber actualConditional; @@ -94,7 +94,7 @@ //TODO could go into a common base for all-in-one subscribers? (as well as actual above) Subscription s; @Nullable - QueueSubscription queueSubscription; + Fuseable.QueueSubscription queueSubscription; int sourceMode; @@ -393,4 +393,5 @@ return queueSubscription == null ? 0 : queueSubscription.size(); } } -} \ No newline at end of file +} + Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoPublishMulticast.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoPublishMulticast.java (.../MonoPublishMulticast.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoPublishMulticast.java (.../MonoPublishMulticast.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2017-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,8 +53,8 @@ public CoreSubscriber subscribeOrReturn(CoreSubscriber actual) { MonoPublishMulticaster multicast = new MonoPublishMulticaster<>(actual.currentContext()); - Mono out = Objects.requireNonNull(transform.apply(fromDirect(multicast)), - "The transform returned a null Mono"); + Mono out = fromDirect( + Objects.requireNonNull(transform.apply(fromDirect(multicast)), "The transform returned a null Mono")); if (out instanceof Fuseable) { out.subscribe(new FluxPublishMulticast.CancelFuseableMulticaster<>(actual, multicast)); Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoRetryWhen.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoRetryWhen.java (.../MonoRetryWhen.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoRetryWhen.java (.../MonoRetryWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ final Retry whenSourceFactory; MonoRetryWhen(Mono source, Retry whenSourceFactory) { - super(source); + super(Mono.fromDirect(source)); this.whenSourceFactory = Objects.requireNonNull(whenSourceFactory, "whenSourceFactory"); } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoRunnable.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoRunnable.java (.../MonoRunnable.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoRunnable.java (.../MonoRunnable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2015-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,7 +77,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class MonoRunnableEagerSubscription extends AtomicBoolean implements Subscription { Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSequenceEqual.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSequenceEqual.java (.../MonoSequenceEqual.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSequenceEqual.java (.../MonoSequenceEqual.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,8 +42,8 @@ MonoSequenceEqual(Publisher first, Publisher second, BiPredicate comparer, int prefetch) { - this.first = Objects.requireNonNull(first, "first"); - this.second = Objects.requireNonNull(second, "second"); + this.first = Operators.toFluxOrMono(Objects.requireNonNull(first, "first")); + this.second = Operators.toFluxOrMono(Objects.requireNonNull(second, "second")); this.comparer = Objects.requireNonNull(comparer, "comparer"); if(prefetch < 1){ throw new IllegalArgumentException("Buffer size must be strictly positive: " + @@ -64,7 +64,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PREFETCH) return prefetch; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class EqualCoordinator implements InnerProducer { Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSingleCallable.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSingleCallable.java (.../MonoSingleCallable.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSingleCallable.java (.../MonoSingleCallable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -122,6 +122,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSingleOptional.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSingleOptional.java (.../MonoSingleOptional.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSingleOptional.java (.../MonoSingleOptional.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -39,7 +39,7 @@ @Override public CoreSubscriber subscribeOrReturn(CoreSubscriber> actual) { - return new SingleOptionalSubscriber<>(actual); + return new MonoSingleOptional.SingleOptionalSubscriber<>(actual); } @Override @@ -121,4 +121,4 @@ } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSingleOptionalCallable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSingleOptionalCallable.java (.../MonoSingleOptionalCallable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSingleOptionalCallable.java (.../MonoSingleOptionalCallable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -93,6 +93,6 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSource.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSource.java (.../MonoSource.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSource.java (.../MonoSource.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -65,11 +65,7 @@ */ @Override public void subscribe(CoreSubscriber actual) { - if (ContextPropagationSupport.shouldPropagateContextToThreadLocals()) { - source.subscribe(new MonoSourceRestoringThreadLocalsSubscriber<>(actual)); - } else { - source.subscribe(actual); - } + source.subscribe(actual); } @Override @@ -96,92 +92,6 @@ if (key == Attr.RUN_STYLE) { return Scannable.from(source).scanUnsafe(key); } - return null; + return SourceProducer.super.scanUnsafe(key); } - - static final class MonoSourceRestoringThreadLocalsSubscriber - implements InnerConsumer { - - final CoreSubscriber actual; - - Subscription s; - boolean done; - - MonoSourceRestoringThreadLocalsSubscriber(CoreSubscriber actual) { - this.actual = actual; - } - - @Override - @Nullable - public Object scanUnsafe(Attr key) { - if (key == Attr.PARENT) { - return s; - } - if (key == Attr.RUN_STYLE) { - return Attr.RunStyle.SYNC; - } - if (key == Attr.ACTUAL) { - return actual; - } - return null; - } - - @Override - public Context currentContext() { - return actual.currentContext(); - } - - @SuppressWarnings("try") - @Override - public void onSubscribe(Subscription s) { - // This is needed, as the downstream can then switch threads, - // continue the subscription using different primitives and omit this operator - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - actual.onSubscribe(s); - } - } - - @SuppressWarnings("try") - @Override - public void onNext(T t) { - this.done = true; - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - actual.onNext(t); - actual.onComplete(); - } - } - - @SuppressWarnings("try") - @Override - public void onError(Throwable t) { - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - if (this.done) { - Operators.onErrorDropped(t, actual.currentContext()); - return; - } - - this.done = true; - - actual.onError(t); - } - } - - @SuppressWarnings("try") - @Override - public void onComplete() { - if (this.done) { - return; - } - - this.done = true; - - try (ContextSnapshot.Scope ignored = - ContextPropagation.setThreadLocals(actual.currentContext())) { - actual.onComplete(); - } - } - } } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoStreamCollector.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoStreamCollector.java (.../MonoStreamCollector.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoStreamCollector.java (.../MonoStreamCollector.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -28,7 +28,7 @@ import reactor.util.context.Context; /** - * Collects the values from the source sequence into a {@link Collector} + * Collects the values from the source sequence into a {@link java.util.stream.Collector} * instance. * * @param the source value type @@ -202,4 +202,4 @@ return r; } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSubscribeOn.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSubscribeOn.java (.../MonoSubscribeOn.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSubscribeOn.java (.../MonoSubscribeOn.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -45,7 +45,7 @@ @Override public CoreSubscriber subscribeOrReturn(CoreSubscriber actual) { - Worker worker = scheduler.createWorker(); + Scheduler.Worker worker = scheduler.createWorker(); SubscribeOnSubscriber parent = new SubscribeOnSubscriber<>(source, actual, worker); @@ -78,7 +78,7 @@ final Publisher parent; - final Worker worker; + final Scheduler.Worker worker; volatile Subscription s; @SuppressWarnings("rawtypes") @@ -211,4 +211,4 @@ worker.dispose(); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSubscribeOnCallable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSubscribeOnCallable.java (.../MonoSubscribeOnCallable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSubscribeOnCallable.java (.../MonoSubscribeOnCallable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,10 +59,11 @@ } @Override - public Object scanUnsafe(Attr key) { - if (key == Attr.RUN_ON) return scheduler; + public Object scanUnsafe(Scannable.Attr key) { + if (key == Scannable.Attr.RUN_ON) return scheduler; if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSubscribeOnValue.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSubscribeOnValue.java (.../MonoSubscribeOnValue.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSubscribeOnValue.java (.../MonoSubscribeOnValue.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,6 +67,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.RUN_ON) return scheduler; if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSupplier.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSupplier.java (.../MonoSupplier.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSupplier.java (.../MonoSupplier.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,7 +70,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static class MonoSupplierSubscription Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoSwitchIfEmpty.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoSwitchIfEmpty.java (.../MonoSwitchIfEmpty.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoSwitchIfEmpty.java (.../MonoSwitchIfEmpty.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ MonoSwitchIfEmpty(Mono source, Mono other) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = fromDirect(Objects.requireNonNull(other, "other")); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoTakeUntilOther.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoTakeUntilOther.java (.../MonoTakeUntilOther.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoTakeUntilOther.java (.../MonoTakeUntilOther.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ MonoTakeUntilOther(Mono source, Publisher other) { super(source); - this.other = Objects.requireNonNull(other, "other"); + this.other = Operators.toFluxOrMono(Objects.requireNonNull(other, "other")); } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoTapRestoringThreadLocals.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoTapRestoringThreadLocals.java (.../MonoTapRestoringThreadLocals.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoTapRestoringThreadLocals.java (.../MonoTapRestoringThreadLocals.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -83,6 +83,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PREFETCH) return -1; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return super.scanUnsafe(key); } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoTimeout.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoTimeout.java (.../MonoTimeout.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoTimeout.java (.../MonoTimeout.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -48,7 +48,7 @@ Publisher firstTimeout, String timeoutDescription) { super(source); - this.firstTimeout = Objects.requireNonNull(firstTimeout, "firstTimeout"); + this.firstTimeout = Mono.fromDirect(Objects.requireNonNull(firstTimeout, "firstTimeout")); this.other = null; this.timeoutDescription = timeoutDescription; } @@ -57,8 +57,8 @@ Publisher firstTimeout, Publisher other) { super(source); - this.firstTimeout = Objects.requireNonNull(firstTimeout, "firstTimeout"); - this.other = Objects.requireNonNull(other, "other"); + this.firstTimeout = Mono.fromDirect(Objects.requireNonNull(firstTimeout, "firstTimeout")); + this.other = Mono.fromDirect(Objects.requireNonNull(other, "other")); this.timeoutDescription = null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoUsing.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoUsing.java (.../MonoUsing.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoUsing.java (.../MonoUsing.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82,8 +82,8 @@ Mono p; try { - p = Objects.requireNonNull(sourceFactory.apply(resource), - "The sourceFactory returned a null value"); + p = Mono.fromDirect(Objects.requireNonNull(sourceFactory.apply(resource), + "The sourceFactory returned a null value")); } catch (Throwable e) { @@ -117,7 +117,7 @@ @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class MonoUsingSubscriber Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoUsingWhen.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoUsingWhen.java (.../MonoUsingWhen.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoUsingWhen.java (.../MonoUsingWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2018-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,7 +84,7 @@ asyncCancel, null); - p.subscribe(subscriber); + fromDirect(p).subscribe(subscriber); } } catch (Throwable e) { @@ -93,15 +93,15 @@ return; } - resourceSupplier.subscribe(new ResourceSubscriber(actual, resourceClosure, - asyncComplete, asyncError, asyncCancel, - resourceSupplier instanceof Mono)); + // Ensure onLastOperatorHook is called by invoking Publisher::subscribe(Subscriber) + ((Publisher) Operators.toFluxOrMono(resourceSupplier)).subscribe( + new ResourceSubscriber(actual, resourceClosure, asyncComplete, asyncError, asyncCancel, resourceSupplier instanceof Mono)); } @Override public Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } private static Mono deriveMonoFromResource( @@ -180,7 +180,7 @@ final Mono p = deriveMonoFromResource(resource, resourceClosure); - p.subscribe(MonoUsingWhen.prepareSubscriberForResource(resource, + fromDirect(p).subscribe(MonoUsingWhen.prepareSubscriberForResource(resource, this.actual, this.asyncComplete, this.asyncError, @@ -243,7 +243,7 @@ } } - static class MonoUsingWhenSubscriber extends UsingWhenSubscriber { + static class MonoUsingWhenSubscriber extends FluxUsingWhen.UsingWhenSubscriber { MonoUsingWhenSubscriber(CoreSubscriber actual, S resource, @@ -277,4 +277,4 @@ this.actual.onError(error); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoWhen.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoWhen.java (.../MonoWhen.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoWhen.java (.../MonoWhen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2017-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -95,6 +95,8 @@ return; } + Operators.toFluxOrMono(a); + WhenCoordinator parent = new WhenCoordinator(a, actual, n, delayError); actual.onSubscribe(parent); } @@ -104,7 +106,7 @@ if (key == Attr.DELAY_ERROR) return delayError; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class WhenCoordinator implements InnerProducer, Index: 3rdParty_sources/reactor/reactor/core/publisher/MonoZip.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/MonoZip.java (.../MonoZip.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/MonoZip.java (.../MonoZip.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -122,14 +122,18 @@ return; } + for (int i = 0; i < n; i++) { + a[i] = Mono.fromDirect(a[i]); + } + actual.onSubscribe(new ZipCoordinator<>(a, actual, n, delayError, zipper)); } @Override public Object scanUnsafe(Attr key) { if (key == Attr.DELAY_ERROR) return delayError; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; - return null; + return SourceProducer.super.scanUnsafe(key); } static final class ZipCoordinator implements InnerProducer, Index: 3rdParty_sources/reactor/reactor/core/publisher/NextProcessor.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/NextProcessor.java (.../NextProcessor.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/NextProcessor.java (.../NextProcessor.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -207,9 +207,9 @@ @SuppressWarnings("unused") EmitResult emitResult = tryEmitValue(null); } - void emitEmpty(EmitFailureHandler failureHandler) { + void emitEmpty(Sinks.EmitFailureHandler failureHandler) { for (;;) { - EmitResult emitResult = tryEmitValue(null); + Sinks.EmitResult emitResult = tryEmitValue(null); if (emitResult.isSuccess()) { return; } @@ -269,7 +269,7 @@ } @SuppressWarnings("unchecked") - EmitResult tryEmitError(Throwable cause) { + Sinks.EmitResult tryEmitError(Throwable cause) { Objects.requireNonNull(cause, "onError cannot be null"); if (UPSTREAM.getAndSet(this, Operators.cancelledSubscription()) == Operators.cancelledSubscription()) { @@ -628,4 +628,4 @@ return super.scanUnsafe(key); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/Operators.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/Operators.java (.../Operators.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/Operators.java (.../Operators.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -582,7 +582,7 @@ } /** - * Invoke a (local or global) hook that processes elements that remains in an {@link Iterator}. + * Invoke a (local or global) hook that processes elements that remains in an {@link java.util.Iterator}. * Since iterators can be infinite, this method requires that you explicitly ensure the iterator is * {@code knownToBeFinite}. Typically, operating on an {@link Iterable} one can get such a * guarantee by looking at the {@link Iterable#spliterator() Spliterator's} {@link Spliterator#getExactSizeIfKnown()}. @@ -620,7 +620,7 @@ /** - * Invoke a (local or global) hook that processes elements that remains in an {@link Spliterator}. + * Invoke a (local or global) hook that processes elements that remains in an {@link java.util.Spliterator}. * Since spliterators can be infinite, this method requires that you explicitly ensure the spliterator is * {@code knownToBeFinite}. Typically, one can get such a guarantee by looking at the {@link Spliterator#getExactSizeIfKnown()}. * @@ -991,6 +991,57 @@ } } + public static CorePublisher toFluxOrMono(Publisher publisher) { + if (publisher instanceof Mono) { + return Mono.fromDirect(publisher); + } + return Flux.from(publisher); + } + + public static void toFluxOrMono(Publisher[] sources) { + for (int i = 0; i < sources.length; i++) { + if (sources[i] != null) { + sources[i] = toFluxOrMono(sources[i]); + } + } + } + + static CoreSubscriber restoreContextOnSubscriberIfPublisherNonInternal( + Publisher publisher, CoreSubscriber subscriber) { + if (ContextPropagationSupport.shouldWrapPublisher(publisher)) { + return restoreContextOnSubscriber(publisher, subscriber); + } + return subscriber; + } + + static CoreSubscriber restoreContextOnSubscriberIfAutoCPEnabled( + Publisher publisher, CoreSubscriber subscriber) { + if (ContextPropagationSupport.shouldPropagateContextToThreadLocals()) { + return restoreContextOnSubscriber(publisher, subscriber); + } + return subscriber; + } + + static CoreSubscriber restoreContextOnSubscriber(Publisher publisher, CoreSubscriber subscriber) { + if (publisher instanceof Fuseable) { + return new FluxContextWriteRestoringThreadLocals.FuseableContextWriteRestoringThreadLocalsSubscriber<>( + subscriber, subscriber.currentContext()); + } else { + return new FluxContextWriteRestoringThreadLocals.ContextWriteRestoringThreadLocalsSubscriber<>( + subscriber, + subscriber.currentContext()); + } + } + + static CoreSubscriber[] restoreContextOnSubscribers( + Publisher publisher, CoreSubscriber[] subscribers) { + CoreSubscriber[] actualSubscribers = new CoreSubscriber[subscribers.length]; + for (int i = 0; i < subscribers.length; i++) { + actualSubscribers[i] = restoreContextOnSubscriber(publisher, subscribers[i]); + } + return actualSubscribers; + } + private static Throwable unwrapOnNextError(Throwable error) { return Exceptions.isBubbling(error) ? error : Exceptions.unwrap(error); } @@ -1341,16 +1392,16 @@ } /** - * If the actual {@link CoreSubscriber} is not {@link Fuseable.ConditionalSubscriber}, + * If the actual {@link CoreSubscriber} is not {@link reactor.core.Fuseable.ConditionalSubscriber}, * it will apply an adapter which directly maps all - * {@link Fuseable.ConditionalSubscriber#tryOnNext(Object)} to + * {@link reactor.core.Fuseable.ConditionalSubscriber#tryOnNext(Object)} to * {@link Subscriber#onNext(Object)} * and always returns true as the result * * @param passed subscriber type * * @param actual the {@link Subscriber} to adapt - * @return a potentially adapted {@link Fuseable.ConditionalSubscriber} + * @return a potentially adapted {@link reactor.core.Fuseable.ConditionalSubscriber} */ @SuppressWarnings("unchecked") public static Fuseable.ConditionalSubscriber toConditionalSubscriber(CoreSubscriber actual) { @@ -1476,24 +1527,14 @@ Operators() { } - static final class CorePublisherAdapter implements CorePublisher, - OptimizableOperator { + static final class CorePublisherAdapter implements CorePublisher { final Publisher publisher; - @Nullable - final OptimizableOperator optimizableOperator; - CorePublisherAdapter(Publisher publisher) { this.publisher = publisher; - if (publisher instanceof OptimizableOperator) { - @SuppressWarnings("unchecked") - OptimizableOperator optimSource = (OptimizableOperator) publisher; - this.optimizableOperator = optimSource; - } - else { - this.optimizableOperator = null; - } + // note: if publisher is not CorePublisher it can't be an + // OptimizableOperator, which extends CorePublisher } @Override @@ -1505,21 +1546,6 @@ public void subscribe(Subscriber s) { publisher.subscribe(s); } - - @Override - public CoreSubscriber subscribeOrReturn(CoreSubscriber actual) { - return actual; - } - - @Override - public final CorePublisher source() { - return this; - } - - @Override - public final OptimizableOperator nextOptimizableSource() { - return optimizableOperator; - } } static final Fuseable.ConditionalSubscriber EMPTY_SUBSCRIBER = new Fuseable.ConditionalSubscriber() { @@ -2004,10 +2030,10 @@ @Override @Nullable - public Object scanUnsafe(Attr key) { - if (key == Attr.PREFETCH) return 0; - if (key == Attr.PARENT) return s; - if (key == Attr.RUN_STYLE) return RunStyle.SYNC; + public Object scanUnsafe(Scannable.Attr key) { + if (key == Scannable.Attr.PREFETCH) return 0; + if (key == Scannable.Attr.PARENT) return s; + if (key == Scannable.Attr.RUN_STYLE) return Scannable.Attr.RunStyle.SYNC; return InnerOperator.super.scanUnsafe(key); } @@ -2605,7 +2631,7 @@ /** * This class wraps any non-conditional {@link CoreSubscriber} so the delegate - * can have an emulation of {@link Fuseable.ConditionalSubscriber} + * can have an emulation of {@link reactor.core.Fuseable.ConditionalSubscriber} * behaviors * * @param passed subscriber type @@ -2656,6 +2682,11 @@ final Predicate filter; final String name; + // TODO: this leaks to the users of LiftFunction, encapsulation is broken + // consider: liftFunction.lifter.apply could go through encapsulation + // like: liftFunction.applyLifter() where what lifter.apply returns is wrapped + // unconditionally; otherwise -> all lift* operators need to be considered as + // NOT INTERNAL_PRODUCER sources final BiFunction, ? extends CoreSubscriber> lifter; @@ -2670,7 +2701,7 @@ } BiFunction, ? extends CoreSubscriber> - effectiveLifter = (pub, sub) -> lifter.apply(Scannable.from(pub), sub); + effectiveLifter = (pub, sub) -> lifter.apply(Scannable.from(pub), restoreContextOnSubscriberIfAutoCPEnabled(pub, sub)); return new LiftFunction<>(effectiveFilter, effectiveLifter, lifter.toString()); } @@ -2972,4 +3003,4 @@ final static Logger log = Loggers.getLogger(Operators.class); -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelArraySource.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelArraySource.java (.../ParallelArraySource.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelArraySource.java (.../ParallelArraySource.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2015-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,6 @@ } int n = subscribers.length; - for (int i = 0; i < n; i++) { Flux.from(sources[i]).subscribe(subscribers[i]); } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelCollect.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelCollect.java (.../ParallelCollect.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelCollect.java (.../ParallelCollect.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ ParallelCollect(ParallelFlux source, Supplier initialCollection, BiConsumer collector) { - this.source = source; + this.source = ParallelFlux.from(source); this.initialCollection = initialCollection; this.collector = collector; } @@ -54,6 +54,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelConcatMap.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelConcatMap.java (.../ParallelConcatMap.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelConcatMap.java (.../ParallelConcatMap.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,7 +50,7 @@ Function> mapper, Supplier> queueSupplier, int prefetch, ErrorMode errorMode) { - this.source = source; + this.source = ParallelFlux.from(source); this.mapper = Objects.requireNonNull(mapper, "mapper"); this.queueSupplier = Objects.requireNonNull(queueSupplier, "queueSupplier"); this.prefetch = prefetch; @@ -64,6 +64,7 @@ if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.DELAY_ERROR) return errorMode != ErrorMode.IMMEDIATE; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelDoOnEach.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelDoOnEach.java (.../ParallelDoOnEach.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelDoOnEach.java (.../ParallelDoOnEach.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,7 @@ @Nullable BiConsumer onError, @Nullable Consumer onComplete ) { - this.source = source; + this.source = ParallelFlux.from(source); this.onNext = onNext; this.onError = onError; @@ -98,6 +98,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelFilter.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelFilter.java (.../ParallelFilter.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelFilter.java (.../ParallelFilter.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ final Predicate predicate; ParallelFilter(ParallelFlux source, Predicate predicate) { - this.source = source; + this.source = ParallelFlux.from(source); this.predicate = predicate; } @@ -45,6 +45,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelFlatMap.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelFlatMap.java (.../ParallelFlatMap.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelFlatMap.java (.../ParallelFlatMap.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ boolean delayError, int maxConcurrency, Supplier> mainQueueSupplier, int prefetch, Supplier> innerQueueSupplier) { - this.source = source; + this.source = ParallelFlux.from(source); this.mapper = mapper; this.delayError = delayError; this.maxConcurrency = maxConcurrency; @@ -69,6 +69,7 @@ if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.DELAY_ERROR) return delayError; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelFlux.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelFlux.java (.../ParallelFlux.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelFlux.java (.../ParallelFlux.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,6 +76,13 @@ */ public abstract class ParallelFlux implements CorePublisher { + static ParallelFlux from(ParallelFlux source) { + if (ContextPropagationSupport.shouldWrapPublisher(source)) { + return new ParallelFluxRestoringThreadLocals<>(source); + } + return source; + } + /** * Take a Publisher and prepare to consume it on multiple 'rails' (one per CPU core) * in a round-robin fashion. Equivalent to {@link Flux#parallel}. Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxHide.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxHide.java (.../ParallelFluxHide.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxHide.java (.../ParallelFluxHide.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ final ParallelFlux source; ParallelFluxHide(ParallelFlux source) { - this.source = source; + this.source = ParallelFlux.from(source); } @Override @@ -51,6 +51,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxName.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxName.java (.../ParallelFluxName.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxName.java (.../ParallelFluxName.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,7 +80,7 @@ ParallelFluxName(ParallelFlux source, @Nullable String name, @Nullable List> tags) { - this.source = source; + this.source = ParallelFlux.from(source); this.name = name; this.tagsWithDuplicates = tags; } @@ -113,6 +113,8 @@ return SYNC; } + if (key == InternalProducerAttr.INSTANCE) return true; + return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxOnAssembly.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxOnAssembly.java (.../ParallelFluxOnAssembly.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxOnAssembly.java (.../ParallelFluxOnAssembly.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,7 @@ * Create an assembly trace wrapping a {@link ParallelFlux}. */ ParallelFluxOnAssembly(ParallelFlux source, AssemblySnapshot stacktrace) { - this.source = source; + this.source = ParallelFlux.from(source); this.stacktrace = stacktrace; } @@ -97,6 +97,7 @@ if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.ACTUAL_METADATA) return !stacktrace.isCheckpoint; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxRestoringThreadLocals.java =================================================================== diff -u --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxRestoringThreadLocals.java (revision 0) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelFluxRestoringThreadLocals.java (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 VMware Inc. or its affiliates, All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package reactor.core.publisher; + +import reactor.core.CoreSubscriber; +import reactor.core.Scannable; + +class ParallelFluxRestoringThreadLocals extends ParallelFlux implements + Scannable { + + private final ParallelFlux source; + + ParallelFluxRestoringThreadLocals(ParallelFlux source) { + this.source = source; + } + + @Override + public int parallelism() { + return source.parallelism(); + } + + @Override + public void subscribe(CoreSubscriber[] subscribers) { + CoreSubscriber[] actualSubscribers = + Operators.restoreContextOnSubscribers(source, subscribers); + + source.subscribe(actualSubscribers); + } + + @Override + public Object scanUnsafe(Attr key) { + if (key == Attr.PARENT) return source; + if (key == Attr.PREFETCH) return getPrefetch(); + if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; + return null; + } +} Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelGroup.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelGroup.java (.../ParallelGroup.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelGroup.java (.../ParallelGroup.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ final ParallelFlux source; ParallelGroup(ParallelFlux source) { - this.source = source; + this.source = ParallelFlux.from(source); } @Override @@ -65,6 +65,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelLift.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelLift.java (.../ParallelLift.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelLift.java (.../ParallelLift.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ ParallelLift(ParallelFlux p, Operators.LiftFunction liftFunction) { - this.source = Objects.requireNonNull(p, "source"); + this.source = ParallelFlux.from(Objects.requireNonNull(p, "source")); this.liftFunction = liftFunction; } @@ -62,7 +62,9 @@ if (key == Attr.LIFTER) { return liftFunction.name; } - + if (key == InternalProducerAttr.INSTANCE) { + return true; + } return null; } @@ -82,7 +84,8 @@ int i = 0; while (i < subscribers.length) { subscribers[i] = - Objects.requireNonNull(liftFunction.lifter.apply(source, s[i]), + Objects.requireNonNull(liftFunction.lifter.apply(source, + Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, s[i])), "Lifted subscriber MUST NOT be null"); i++; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelLiftFuseable.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelLiftFuseable.java (.../ParallelLiftFuseable.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelLiftFuseable.java (.../ParallelLiftFuseable.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ ParallelLiftFuseable(ParallelFlux p, Operators.LiftFunction liftFunction) { - this.source = Objects.requireNonNull(p, "source"); + this.source = ParallelFlux.from(Objects.requireNonNull(p, "source")); this.liftFunction = liftFunction; } @@ -65,7 +65,9 @@ if (key == Attr.LIFTER) { return liftFunction.name; } - + if (key == InternalProducerAttr.INSTANCE) { + return true; + } return null; } @@ -86,12 +88,12 @@ while (i < subscribers.length) { CoreSubscriber actual = s[i]; CoreSubscriber converted = - Objects.requireNonNull(liftFunction.lifter.apply(source, actual), + Objects.requireNonNull(liftFunction.lifter.apply(source, Operators.restoreContextOnSubscriberIfAutoCPEnabled(source, actual)), "Lifted subscriber MUST NOT be null"); Objects.requireNonNull(converted, "Lifted subscriber MUST NOT be null"); - if (actual instanceof QueueSubscription + if (actual instanceof Fuseable.QueueSubscription && !(converted instanceof QueueSubscription)) { //user didn't produce a QueueSubscription, original was one converted = new FluxHide.SuppressFuseableSubscriber<>(converted); @@ -105,4 +107,4 @@ } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelLog.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelLog.java (.../ParallelLog.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelLog.java (.../ParallelLog.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ ParallelLog(ParallelFlux source, SignalPeek log ) { - this.source = source; + this.source = ParallelFlux.from(source); this.log = log; } @@ -81,6 +81,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelMap.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelMap.java (.../ParallelMap.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelMap.java (.../ParallelMap.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ final Function mapper; ParallelMap(ParallelFlux source, Function mapper) { - this.source = source; + this.source = ParallelFlux.from(source); this.mapper = mapper; } @@ -46,6 +46,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeOrdered.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeOrdered.java (.../ParallelMergeOrdered.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeOrdered.java (.../ParallelMergeOrdered.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ if (prefetch <= 0) { throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch); } - this.source = source; + this.source = ParallelFlux.from(source); this.prefetch = prefetch; this.valueComparator = valueComparator; } @@ -57,6 +57,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return prefetch; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeReduce.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeReduce.java (.../ParallelMergeReduce.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeReduce.java (.../ParallelMergeReduce.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ ParallelMergeReduce(ParallelFlux source, BiFunction reducer) { - this.source = source; + this.source = ParallelFlux.from(source); this.reducer = reducer; } @@ -51,6 +51,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.PARENT) return source; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeSequential.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeSequential.java (.../ParallelMergeSequential.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeSequential.java (.../ParallelMergeSequential.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,7 @@ if (prefetch <= 0) { throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch); } - this.source = source; + this.source = ParallelFlux.from(source); this.prefetch = prefetch; this.queueSupplier = queueSupplier; } @@ -57,6 +57,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeSort.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeSort.java (.../ParallelMergeSort.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelMergeSort.java (.../ParallelMergeSort.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,7 @@ ParallelMergeSort(ParallelFlux> source, Comparator comparator) { - this.source = source; + this.source = ParallelFlux.from(source); this.comparator = comparator; } @@ -71,6 +71,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelPeek.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelPeek.java (.../ParallelPeek.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelPeek.java (.../ParallelPeek.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +52,7 @@ @Nullable LongConsumer onRequest, @Nullable Runnable onCancel ) { - this.source = source; + this.source = ParallelFlux.from(source); this.onNext = onNext; this.onAfterNext = onAfterNext; @@ -153,6 +153,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelReduceSeed.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelReduceSeed.java (.../ParallelReduceSeed.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelReduceSeed.java (.../ParallelReduceSeed.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,17 +44,18 @@ ParallelReduceSeed(ParallelFlux source, Supplier initialSupplier, BiFunction reducer) { - this.source = source; + this.source = ParallelFlux.from(source); this.initialSupplier = initialSupplier; this.reducer = reducer; } @Override @Nullable - public Object scanUnsafe(Attr key) { + public Object scanUnsafe(Scannable.Attr key) { if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -222,4 +223,4 @@ return super.scanUnsafe(key); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelRunOn.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelRunOn.java (.../ParallelRunOn.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelRunOn.java (.../ParallelRunOn.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,7 +45,7 @@ if (prefetch <= 0) { throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch); } - this.source = parent; + this.source = ParallelFlux.from(parent); this.scheduler = scheduler; this.prefetch = prefetch; this.queueSupplier = queueSupplier; @@ -57,6 +57,7 @@ if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.ASYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelSource.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelSource.java (.../ParallelSource.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelSource.java (.../ParallelSource.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ if (prefetch <= 0) { throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch); } - this.source = source; + this.source = Operators.toFluxOrMono(source); this.parallelism = parallelism; this.prefetch = prefetch; this.queueSupplier = queueSupplier; @@ -72,10 +72,11 @@ @Override @Nullable - public Object scanUnsafe(Attr key) { + public Object scanUnsafe(Scannable.Attr key) { if (key == Attr.PARENT) return source; if (key == Attr.PREFETCH) return getPrefetch(); if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -518,4 +519,4 @@ } } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/ParallelThen.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/ParallelThen.java (.../ParallelThen.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/ParallelThen.java (.../ParallelThen.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2019-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,14 +34,15 @@ final ParallelFlux source; ParallelThen(ParallelFlux source) { - this.source = source; + this.source = ParallelFlux.from(source); } @Override @Nullable public Object scanUnsafe(Attr key) { if (key == Attr.PARENT) return source; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/SignalLogger.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SignalLogger.java (.../SignalLogger.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/SignalLogger.java (.../SignalLogger.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package reactor.core.publisher; +import java.time.Instant; import java.util.Objects; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; Index: 3rdParty_sources/reactor/reactor/core/publisher/SinkEmptyMulticast.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SinkEmptyMulticast.java (.../SinkEmptyMulticast.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/SinkEmptyMulticast.java (.../SinkEmptyMulticast.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -124,6 +124,7 @@ if (key == Attr.TERMINATED) return isTerminated(subscribers); if (key == Attr.ERROR) return subscribers == TERMINATED_ERROR ? error : null; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -196,8 +197,10 @@ //redefined in SinkOneMulticast @Override public void subscribe(final CoreSubscriber actual) { - Inner as = new VoidInner<>(actual, this); - actual.onSubscribe(as); + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); + Inner as = new VoidInner<>(wrapped, this); + wrapped.onSubscribe(as); final int addedState = add(as); if (addedState == STATE_ADDED) { if (as.isCancelled()) { @@ -207,7 +210,7 @@ else if (addedState == STATE_ERROR) { Throwable ex = error; - actual.onError(ex); + wrapped.onError(ex); } else { as.complete(); Index: 3rdParty_sources/reactor/reactor/core/publisher/SinkManyBestEffort.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SinkManyBestEffort.java (.../SinkManyBestEffort.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/SinkManyBestEffort.java (.../SinkManyBestEffort.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,6 +77,7 @@ public Object scanUnsafe(Attr key) { if (key == Attr.TERMINATED) return subscribers == TERMINATED; if (key == Attr.ERROR) return error; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -191,9 +192,12 @@ public void subscribe(CoreSubscriber actual) { Objects.requireNonNull(actual, "subscribe(null) is forbidden"); - DirectInner p = new DirectInner<>(actual, this); - actual.onSubscribe(p); + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); + DirectInner p = new DirectInner<>(wrapped, this); + wrapped.onSubscribe(p); + if (p.isCancelled()) { return; } @@ -206,18 +210,18 @@ else { Throwable e = error; if (e != null) { - actual.onError(e); + wrapped.onError(e); } else { - actual.onComplete(); + wrapped.onComplete(); } } } /** - * Add a new {@link DirectInner} to this publisher. + * Add a new {@link SinkManyBestEffort.DirectInner} to this publisher. * - * @param s the new {@link DirectInner} to add + * @param s the new {@link SinkManyBestEffort.DirectInner} to add * * @return {@code true} if the inner could be added, {@code false} if the publisher cannot accept new subscribers */ @@ -246,10 +250,10 @@ } /** - * Remove an {@link DirectInner} from this publisher. Does nothing if the inner is not currently managed + * Remove an {@link SinkManyBestEffort.DirectInner} from this publisher. Does nothing if the inner is not currently managed * by the publisher. * - * @param s the {@link DirectInner} to remove + * @param s the {@link SinkManyBestEffort.DirectInner} to remove */ @SuppressWarnings("unchecked") public void remove(DirectInner s) { @@ -391,4 +395,5 @@ } } -} \ No newline at end of file +} + Index: 3rdParty_sources/reactor/reactor/core/publisher/SinkManyEmitterProcessor.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SinkManyEmitterProcessor.java (.../SinkManyEmitterProcessor.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/SinkManyEmitterProcessor.java (.../SinkManyEmitterProcessor.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -165,9 +165,13 @@ @Override public void subscribe(CoreSubscriber actual) { Objects.requireNonNull(actual, "subscribe"); - EmitterInner inner = new EmitterInner<>(actual, this); - actual.onSubscribe(inner); + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); + + EmitterInner inner = new EmitterInner<>(wrapped, this); + wrapped.onSubscribe(inner); + if (inner.isCancelled()) { return; } @@ -222,7 +226,7 @@ return EmitResult.OK; } else { - return EmitResult.FAIL_TERMINATED; + return Sinks.EmitResult.FAIL_TERMINATED; } } @@ -238,7 +242,7 @@ @Override public EmitResult tryEmitNext(T t) { if (done) { - return EmitResult.FAIL_TERMINATED; + return Sinks.EmitResult.FAIL_TERMINATED; } Objects.requireNonNull(t, "tryEmitNext must be invoked with a non-null value"); @@ -373,6 +377,7 @@ if (key == Attr.TERMINATED) return isTerminated(); if (key == Attr.ERROR) return getError(); if (key == Attr.CAPACITY) return getPrefetch(); + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @@ -649,4 +654,4 @@ } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/SinkManyReplayProcessor.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SinkManyReplayProcessor.java (.../SinkManyReplayProcessor.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/SinkManyReplayProcessor.java (.../SinkManyReplayProcessor.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -295,9 +295,12 @@ @Override public void subscribe(CoreSubscriber actual) { Objects.requireNonNull(actual, "subscribe"); - FluxReplay.ReplaySubscription rs = new ReplayInner<>(actual, this); - actual.onSubscribe(rs); + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); + FluxReplay.ReplaySubscription rs = new ReplayInner<>(wrapped, this); + wrapped.onSubscribe(rs); + if (add(rs)) { if (rs.isCancelled()) { remove(rs); @@ -412,14 +415,14 @@ @Override public void onComplete() { //no particular error condition handling for onComplete - @SuppressWarnings("unused") EmitResult emitResult = tryEmitComplete(); + @SuppressWarnings("unused") Sinks.EmitResult emitResult = tryEmitComplete(); } @Override - public EmitResult tryEmitComplete() { + public Sinks.EmitResult tryEmitComplete() { FluxReplay.ReplayBuffer b = buffer; if (b.isDone()) { - return EmitResult.FAIL_TERMINATED; + return Sinks.EmitResult.FAIL_TERMINATED; } b.onComplete(); @@ -462,18 +465,18 @@ } @Override - public EmitResult tryEmitNext(T t) { + public Sinks.EmitResult tryEmitNext(T t) { FluxReplay.ReplayBuffer b = buffer; if (b.isDone()) { - return EmitResult.FAIL_TERMINATED; + return Sinks.EmitResult.FAIL_TERMINATED; } //note: SinkManyReplayProcessor can so far ALWAYS buffer the element, no FAIL_ZERO_SUBSCRIBER here b.add(t); for (FluxReplay.ReplaySubscription rs : subscribers) { b.replay(rs); } - return EmitResult.OK; + return Sinks.EmitResult.OK; } @Override Index: 3rdParty_sources/reactor/reactor/core/publisher/SinkManySerialized.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SinkManySerialized.java (.../SinkManySerialized.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/SinkManySerialized.java (.../SinkManySerialized.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -54,7 +54,7 @@ } @Override - public final Sinks.EmitResult tryEmitComplete() { + public Sinks.EmitResult tryEmitComplete() { Thread currentThread = Thread.currentThread(); if (!tryAcquire(currentThread)) { return Sinks.EmitResult.FAIL_NON_SERIALIZED; @@ -70,7 +70,7 @@ } @Override - public final Sinks.EmitResult tryEmitError(Throwable t) { + public Sinks.EmitResult tryEmitError(Throwable t) { Objects.requireNonNull(t, "t is null in sink.error(t)"); Thread currentThread = Thread.currentThread(); @@ -88,7 +88,7 @@ } @Override - public final Sinks.EmitResult tryEmitNext(T t) { + public Sinks.EmitResult tryEmitNext(T t) { Objects.requireNonNull(t, "t is null in sink.next(t)"); Thread currentThread = Thread.currentThread(); Index: 3rdParty_sources/reactor/reactor/core/publisher/SinkManyUnicast.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SinkManyUnicast.java (.../SinkManyUnicast.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/SinkManyUnicast.java (.../SinkManyUnicast.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -130,6 +130,7 @@ AtomicReferenceFieldUpdater.newUpdater(SinkManyUnicast.class, Disposable.class, "onTerminate"); volatile boolean done; + volatile boolean subscriptionDelivered; Throwable error; boolean hasDownstream; //important to not loose the downstream too early and miss discard hook, while having relevant hasDownstreams() @@ -183,6 +184,7 @@ if (Attr.CANCELLED == key) return cancelled; if (Attr.TERMINATED == key) return done; if (Attr.ERROR == key) return error; + if (InternalProducerAttr.INSTANCE == key) return true; return null; } @@ -201,13 +203,13 @@ doTerminate(); drain(null); - return EmitResult.OK; + return Sinks.EmitResult.OK; } @Override - public EmitResult tryEmitError(Throwable t) { + public Sinks.EmitResult tryEmitError(Throwable t) { if (done) { - return EmitResult.FAIL_TERMINATED; + return Sinks.EmitResult.FAIL_TERMINATED; } if (cancelled) { return EmitResult.FAIL_CANCELLED; @@ -355,9 +357,8 @@ int missed = 1; for (;;) { - CoreSubscriber a = actual; - if (a != null) { - + if (subscriptionDelivered) { + CoreSubscriber a = actual; if (outputFused) { drainFused(a); } else { @@ -408,18 +409,21 @@ @Override public void subscribe(CoreSubscriber actual) { Objects.requireNonNull(actual, "subscribe"); + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); if (once == 0 && ONCE.compareAndSet(this, 0, 1)) { this.hasDownstream = true; - actual.onSubscribe(this); - this.actual = actual; + this.actual = wrapped; + wrapped.onSubscribe(this); + subscriptionDelivered = true; if (cancelled) { this.hasDownstream = false; } else { drain(null); } } else { - Operators.error(actual, new IllegalStateException("Sinks.many().unicast() sinks only allow a single Subscriber")); + Operators.error(wrapped, new IllegalStateException("Sinks.many().unicast() sinks only allow a single Subscriber")); } } @@ -511,4 +515,4 @@ public boolean isDisposed() { return cancelled || done; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/SinkManyUnicastNoBackpressure.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SinkManyUnicastNoBackpressure.java (.../SinkManyUnicastNoBackpressure.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/SinkManyUnicastNoBackpressure.java (.../SinkManyUnicastNoBackpressure.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,13 +76,17 @@ public void subscribe(CoreSubscriber actual) { Objects.requireNonNull(actual, "subscribe"); + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); + if (!STATE.compareAndSet(this, State.INITIAL, State.SUBSCRIBED)) { - Operators.reportThrowInSubscribe(actual, new IllegalStateException("Unicast Sinks.Many allows only a single Subscriber")); + Operators.reportThrowInSubscribe(wrapped, new IllegalStateException( + "Unicast Sinks.Many allows only a single Subscriber")); return; } - this.actual = actual; - actual.onSubscribe(this); + this.actual = wrapped; + wrapped.onSubscribe(this); } @Override @@ -106,24 +110,24 @@ } @Override - public EmitResult tryEmitNext(T t) { + public Sinks.EmitResult tryEmitNext(T t) { Objects.requireNonNull(t, "t"); switch (state) { case INITIAL: - return EmitResult.FAIL_ZERO_SUBSCRIBER; + return Sinks.EmitResult.FAIL_ZERO_SUBSCRIBER; case SUBSCRIBED: if (requested == 0L) { - return EmitResult.FAIL_OVERFLOW; + return Sinks.EmitResult.FAIL_OVERFLOW; } actual.onNext(t); Operators.produced(REQUESTED, this, 1); - return EmitResult.OK; + return Sinks.EmitResult.OK; case TERMINATED: - return EmitResult.FAIL_TERMINATED; + return Sinks.EmitResult.FAIL_TERMINATED; case CANCELLED: - return EmitResult.FAIL_CANCELLED; + return Sinks.EmitResult.FAIL_CANCELLED; default: throw new IllegalStateException(); } @@ -136,18 +140,18 @@ State s = this.state; switch (s) { case INITIAL: - return EmitResult.FAIL_ZERO_SUBSCRIBER; + return Sinks.EmitResult.FAIL_ZERO_SUBSCRIBER; case SUBSCRIBED: if (STATE.compareAndSet(this, s, State.TERMINATED)) { actual.onError(t); actual = null; - return EmitResult.OK; + return Sinks.EmitResult.OK; } continue; case TERMINATED: - return EmitResult.FAIL_TERMINATED; + return Sinks.EmitResult.FAIL_TERMINATED; case CANCELLED: - return EmitResult.FAIL_CANCELLED; + return Sinks.EmitResult.FAIL_CANCELLED; default: throw new IllegalStateException(); } @@ -160,7 +164,7 @@ State s = this.state; switch (s) { case INITIAL: - return EmitResult.FAIL_ZERO_SUBSCRIBER; + return Sinks.EmitResult.FAIL_ZERO_SUBSCRIBER; case SUBSCRIBED: if (STATE.compareAndSet(this, s, State.TERMINATED)) { actual.onComplete(); @@ -169,9 +173,9 @@ } continue; case TERMINATED: - return EmitResult.FAIL_TERMINATED; + return Sinks.EmitResult.FAIL_TERMINATED; case CANCELLED: - return EmitResult.FAIL_CANCELLED; + return Sinks.EmitResult.FAIL_CANCELLED; default: throw new IllegalStateException(); } @@ -190,7 +194,8 @@ if (key == Attr.ACTUAL) return actual; if (key == Attr.TERMINATED) return state == State.TERMINATED; if (key == Attr.CANCELLED) return state == State.CANCELLED; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/SinkOneMulticast.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SinkOneMulticast.java (.../SinkOneMulticast.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/SinkOneMulticast.java (.../SinkOneMulticast.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package reactor.core.publisher; import java.time.Duration; -import java.util.Objects; import reactor.core.CoreSubscriber; import reactor.core.publisher.Sinks.EmitResult; @@ -75,22 +74,25 @@ if (key == Attr.TERMINATED) return isTerminated(subscribers); if (key == Attr.ERROR) return subscribers == TERMINATED_ERROR ? error : null; if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } @Override public void subscribe(final CoreSubscriber actual) { - NextInner as = new NextInner<>(actual, this); - actual.onSubscribe(as); + CoreSubscriber wrapped = + Operators.restoreContextOnSubscriberIfAutoCPEnabled(this, actual); + NextInner as = new NextInner<>(wrapped, this); + wrapped.onSubscribe(as); final int addState = add(as); if (addState == STATE_ADDED) { if (as.isCancelled()) { remove(as); } } else if (addState == STATE_ERROR) { - actual.onError(error); + wrapped.onError(error); } else if (addState == STATE_EMPTY) { as.complete(); Index: 3rdParty_sources/reactor/reactor/core/publisher/Sinks.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/Sinks.java (.../Sinks.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/Sinks.java (.../Sinks.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -35,7 +35,7 @@ * semantics. These standalone sinks expose {@link Many#tryEmitNext(Object) tryEmit} methods that return an {@link EmitResult} enum, * allowing to atomically fail in case the attempted signal is inconsistent with the spec and/or the state of the sink. *

    - * This class exposes a collection of ({@link Many} builders and {@link One} factories. Unless constructed through the + * This class exposes a collection of ({@link Sinks.Many} builders and {@link Sinks.One} factories. Unless constructed through the * {@link #unsafe()} spec, these sinks are thread safe in the sense that they will detect concurrent access and fail fast on one of * the attempts. {@link #unsafe()} sinks on the other hand are expected to be externally synchronized (typically by being called from * within a Reactive Streams-compliant context, like a {@link Subscriber} or an operator, which means it is ok to remove the overhead @@ -50,39 +50,39 @@ } /** - * A {@link Empty} which exclusively produces one terminal signal: error or complete. + * A {@link Sinks.Empty} which exclusively produces one terminal signal: error or complete. * It has the following characteristics: *

      *
    • Multicast
    • *
    • Backpressure : this sink does not need any demand since it can only signal error or completion
    • *
    • Replaying: Replay the terminal signal (error or complete).
    • *
    - * Use {@link Empty#asMono()} to expose the {@link Mono} view of the sink to downstream consumers. + * Use {@link Sinks.Empty#asMono()} to expose the {@link Mono} view of the sink to downstream consumers. * - * @return a new {@link Empty} + * @return a new {@link Sinks.Empty} * @see RootSpec#empty() */ - public static Empty empty() { + public static Sinks.Empty empty() { return SinksSpecs.DEFAULT_SINKS.empty(); } /** - * A {@link One} that works like a conceptual promise: it can be completed + * A {@link Sinks.One} that works like a conceptual promise: it can be completed * with or without a value at any time, but only once. This completion is replayed to late subscribers. - * Calling {@link One#tryEmitValue(Object)} (or {@link One#emitValue(Object, EmitFailureHandler)}) is enough and will + * Calling {@link One#tryEmitValue(Object)} (or {@link One#emitValue(Object, Sinks.EmitFailureHandler)}) is enough and will * implicitly produce a {@link Subscriber#onComplete()} signal as well. *

    * Use {@link One#asMono()} to expose the {@link Mono} view of the sink to downstream consumers. * - * @return a new {@link One} + * @return a new {@link Sinks.One} * @see RootSpec#one() */ - public static One one() { + public static Sinks.One one() { return SinksSpecs.DEFAULT_SINKS.one(); } /** - * Help building {@link Many} sinks that will broadcast multiple signals to one or more {@link Subscriber}. + * Help building {@link Sinks.Many} sinks that will broadcast multiple signals to one or more {@link Subscriber}. *

    * Use {@link Many#asFlux()} to expose the {@link Flux} view of the sink to the downstream consumers. * @@ -95,7 +95,7 @@ /** * Return a {@link RootSpec root spec} for more advanced use cases such as building operators. - * Unsafe {@link Many}, {@link One} and {@link Empty} are not serialized nor thread safe, + * Unsafe {@link Sinks.Many}, {@link Sinks.One} and {@link Sinks.Empty} are not serialized nor thread safe, * which implies they MUST be externally synchronized so as to respect the Reactive Streams specification. * This can typically be the case when the sinks are being called from within a Reactive Streams-compliant context, * like a {@link Subscriber} or an operator. In turn, this allows the sinks to have less overhead, since they @@ -108,7 +108,7 @@ } /** - * Represents the immediate result of an emit attempt (eg. in {@link Many#tryEmitNext(Object)}. + * Represents the immediate result of an emit attempt (eg. in {@link Sinks.Many#tryEmitNext(Object)}. * This does not guarantee that a signal is consumed, it simply refers to the sink state when an emit method is invoked. * This is a particularly important distinction with regard to {@link #FAIL_CANCELLED} which means the sink is -now- * interrupted and emission can't proceed. Consequently, it is possible to emit a signal and obtain an "OK" status even @@ -237,12 +237,12 @@ @Override public boolean onEmitFailure(SignalType signalType, EmitResult emitResult) { - return emitResult.equals(EmitResult.FAIL_NON_SERIALIZED) && (System.nanoTime() < this.deadline); + return emitResult.equals(Sinks.EmitResult.FAIL_NON_SERIALIZED) && (System.nanoTime() < this.deadline); } } /** - * A handler supporting the emit API (eg. {@link Many#emitNext(Object, EmitFailureHandler)}), + * A handler supporting the emit API (eg. {@link Many#emitNext(Object, Sinks.EmitFailureHandler)}), * checking non-successful emission results from underlying {@link Many#tryEmitNext(Object) tryEmit} * API calls to decide whether or not such calls should be retried. * Other than instructing to retry, the handlers are allowed to have side effects @@ -293,36 +293,36 @@ //implementation note: this should now only be implemented by the Sinks.unsafe() path /** - * Provides a choice of {@link One}/{@link Empty} factories and - * {@link ManySpec further specs} for {@link Many}. + * Provides a choice of {@link Sinks.One}/{@link Sinks.Empty} factories and + * {@link Sinks.ManySpec further specs} for {@link Sinks.Many}. */ public interface RootSpec { /** - * A {@link Empty} which exclusively produces one terminal signal: error or complete. + * A {@link Sinks.Empty} which exclusively produces one terminal signal: error or complete. * It has the following characteristics: *

      *
    • Multicast
    • *
    • Backpressure : this sink does not need any demand since it can only signal error or completion
    • *
    • Replaying: Replay the terminal signal (error or complete).
    • *
    - * Use {@link Empty#asMono()} to expose the {@link Mono} view of the sink to downstream consumers. + * Use {@link Sinks.Empty#asMono()} to expose the {@link Mono} view of the sink to downstream consumers. */ - Empty empty(); + Sinks.Empty empty(); /** - * A {@link One} that works like a conceptual promise: it can be completed + * A {@link Sinks.One} that works like a conceptual promise: it can be completed * with or without a value at any time, but only once. This completion is replayed to late subscribers. - * Calling {@link One#emitValue(Object, EmitFailureHandler)} (or + * Calling {@link One#emitValue(Object, Sinks.EmitFailureHandler)} (or * {@link One#tryEmitValue(Object)}) is enough and will implicitly produce * a {@link Subscriber#onComplete()} signal as well. *

    * Use {@link One#asMono()} to expose the {@link Mono} view of the sink to downstream consumers. */ - One one(); + Sinks.One one(); /** - * Help building {@link Many} sinks that will broadcast multiple signals to one or more {@link Subscriber}. + * Help building {@link Sinks.Many} sinks that will broadcast multiple signals to one or more {@link Subscriber}. *

    * Use {@link Many#asFlux()} to expose the {@link Flux} view of the sink to the downstream consumers. * @@ -331,7 +331,7 @@ ManySpec many(); /** - * Help building {@link ManyWithUpstream} sinks that can also be {@link ManyWithUpstream#subscribeTo(Publisher) subscribed to} + * Help building {@link Sinks.ManyWithUpstream} sinks that can also be {@link ManyWithUpstream#subscribeTo(Publisher) subscribed to} * an upstream {@link Publisher}. This is an advanced use case, see {@link ManyWithUpstream#subscribeTo(Publisher)}. * * @return a {@link ManyWithUpstreamUnsafeSpec} @@ -340,25 +340,25 @@ } /** - * Provides {@link Many} specs for sinks which can emit multiple elements + * Provides {@link Sinks.Many} specs for sinks which can emit multiple elements */ public interface ManySpec { /** - * Help building {@link Many} that will broadcast signals to a single {@link Subscriber} + * Help building {@link Sinks.Many} that will broadcast signals to a single {@link Subscriber} * * @return {@link UnicastSpec} */ UnicastSpec unicast(); /** - * Help building {@link Many} that will broadcast signals to multiple {@link Subscriber} + * Help building {@link Sinks.Many} that will broadcast signals to multiple {@link Subscriber} * * @return {@link MulticastSpec} */ MulticastSpec multicast(); /** - * Help building {@link Many} that will broadcast signals to multiple {@link Subscriber} with the ability to retain + * Help building {@link Sinks.Many} that will broadcast signals to multiple {@link Subscriber} with the ability to retain * and replay all or an arbitrary number of elements. * * @return {@link MulticastReplaySpec} @@ -367,7 +367,7 @@ } /** - * Instead of {@link Sinks#unsafe() unsafe} flavors of {@link Many}, this spec provides {@link ManyWithUpstream} + * Instead of {@link Sinks#unsafe() unsafe} flavors of {@link Sinks.Many}, this spec provides {@link ManyWithUpstream} * implementations. These additionally support being subscribed to an upstream {@link Publisher}, at most once. * Please note that when this is done, one MUST stop using emit/tryEmit APIs, reserving signal creation to be the * sole responsibility of the upstream {@link Publisher}. @@ -377,15 +377,15 @@ */ public interface ManyWithUpstreamUnsafeSpec { /** - * A {@link ManyWithUpstream} with the following characteristics: + * A {@link Sinks.ManyWithUpstream} with the following characteristics: *

      *
    • Multicast
    • *
    • Without {@link Subscriber}: warm up. Remembers up to {@link Queues#SMALL_BUFFER_SIZE} * elements pushed via {@link Many#tryEmitNext(Object)} before the first {@link Subscriber} is registered.
    • *
    • Backpressure : this sink honors downstream demand by conforming to the lowest demand in case * of multiple subscribers.
      If the difference between multiple subscribers is greater than {@link Queues#SMALL_BUFFER_SIZE}: *
      • {@link Many#tryEmitNext(Object) tryEmitNext} will return {@link EmitResult#FAIL_OVERFLOW}
      • - *
      • {@link Many#emitNext(Object, EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, EmitFailureHandler) emitting} + *
      • {@link Many#emitNext(Object, Sinks.EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, Sinks.EmitFailureHandler) emitting} * an {@link Exceptions#failWithOverflow() overflow error}.
      *
    • *
    • Replaying: No replay of values seen by earlier subscribers. Only forwards to a {@link Subscriber} @@ -398,15 +398,15 @@ ManyWithUpstream multicastOnBackpressureBuffer(); /** - * A {@link ManyWithUpstream} with the following characteristics: + * A {@link Sinks.ManyWithUpstream} with the following characteristics: *
        *
      • Multicast
      • *
      • Without {@link Subscriber}: warm up. Remembers up to {@code bufferSize} * elements pushed via {@link Many#tryEmitNext(Object)} before the first {@link Subscriber} is registered.
      • *
      • Backpressure : this sink honors downstream demand by conforming to the lowest demand in case * of multiple subscribers.
        If the difference between multiple subscribers is too high compared to {@code bufferSize}: *
        • {@link Many#tryEmitNext(Object) tryEmitNext} will return {@link EmitResult#FAIL_OVERFLOW}
        • - *
        • {@link Many#emitNext(Object, EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, EmitFailureHandler) emitting} + *
        • {@link Many#emitNext(Object, Sinks.EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, Sinks.EmitFailureHandler) emitting} * an {@link Exceptions#failWithOverflow() overflow error}.
        *
      • *
      • Replaying: No replay of values seen by earlier subscribers. Only forwards to a {@link Subscriber} @@ -428,22 +428,22 @@ public interface UnicastSpec { /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
          - *
        • Unicast: contrary to most other {@link Many}, the + *
        • Unicast: contrary to most other {@link Sinks.Many}, the * {@link Flux} view rejects {@link Subscriber subscribers} past the first one.
        • *
        • Backpressure : this sink honors downstream demand of its single {@link Subscriber}.
        • *
        • Replaying: non-applicable, since only one {@link Subscriber} can register.
        • *
        • Without {@link Subscriber}: all elements pushed to this sink are remembered and will * be replayed once the {@link Subscriber} subscribes.
        • *
        */ - Many onBackpressureBuffer(); + Sinks.Many onBackpressureBuffer(); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
          - *
        • Unicast: contrary to most other {@link Many}, the + *
        • Unicast: contrary to most other {@link Sinks.Many}, the * {@link Flux} view rejects {@link Subscriber subscribers} past the first one.
        • *
        • Backpressure : this sink honors downstream demand of its single {@link Subscriber}.
        • *
        • Replaying: non-applicable, since only one {@link Subscriber} can register.
        • @@ -453,12 +453,12 @@ * * @param queue an arbitrary queue to use that must at least support Single Producer / Single Consumer semantics */ - Many onBackpressureBuffer(Queue queue); + Sinks.Many onBackpressureBuffer(Queue queue); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
            - *
          • Unicast: contrary to most other {@link Many}, the + *
          • Unicast: contrary to most other {@link Sinks.Many}, the * {@link Flux} view rejects {@link Subscriber subscribers} past the first one.
          • *
          • Backpressure : this sink honors downstream demand of its single {@link Subscriber}.
          • *
          • Replaying: non-applicable, since only one {@link Subscriber} can register.
          • @@ -469,19 +469,19 @@ * @param queue an arbitrary queue to use that must at least support Single Producer / Single Consumer semantics * @param endCallback when a terminal signal is observed: error, complete or cancel */ - Many onBackpressureBuffer(Queue queue, Disposable endCallback); + Sinks.Many onBackpressureBuffer(Queue queue, Disposable endCallback); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
              - *
            • Unicast: contrary to most other {@link Many}, the + *
            • Unicast: contrary to most other {@link Sinks.Many}, the * {@link Flux} view rejects {@link Subscriber subscribers} past the first one.
            • *
            • Backpressure : this sink honors downstream demand of the Subscriber, and will emit {@link Subscriber#onError(Throwable)} if there is a mismatch.
            • *
            • Replaying: No replay. Only forwards to a {@link Subscriber} the elements that have been * pushed to the sink AFTER this subscriber was subscribed.
            • *
            */ - Many onBackpressureError(); + Sinks.Many onBackpressureError(); } /** @@ -490,15 +490,15 @@ public interface MulticastSpec { /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
              *
            • Multicast
            • *
            • Without {@link Subscriber}: warm up. Remembers up to {@link Queues#SMALL_BUFFER_SIZE} * elements pushed via {@link Many#tryEmitNext(Object)} before the first {@link Subscriber} is registered.
            • *
            • Backpressure : this sink honors downstream demand by conforming to the lowest demand in case * of multiple subscribers.
              If the difference between multiple subscribers is greater than {@link Queues#SMALL_BUFFER_SIZE}: *
              • {@link Many#tryEmitNext(Object) tryEmitNext} will return {@link EmitResult#FAIL_OVERFLOW}
              • - *
              • {@link Many#emitNext(Object, EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, EmitFailureHandler) emitting} + *
              • {@link Many#emitNext(Object, Sinks.EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, Sinks.EmitFailureHandler) emitting} * an {@link Exceptions#failWithOverflow() overflow error}.
              *
            • *
            • Replaying: No replay of values seen by earlier subscribers. Only forwards to a {@link Subscriber} @@ -508,18 +508,18 @@ *

              * */ - Many onBackpressureBuffer(); + Sinks.Many onBackpressureBuffer(); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *

                *
              • Multicast
              • *
              • Without {@link Subscriber}: warm up. Remembers up to {@code bufferSize} * elements pushed via {@link Many#tryEmitNext(Object)} before the first {@link Subscriber} is registered.
              • *
              • Backpressure : this sink honors downstream demand by conforming to the lowest demand in case * of multiple subscribers.
                If the difference between multiple subscribers is too high compared to {@code bufferSize}: *
                • {@link Many#tryEmitNext(Object) tryEmitNext} will return {@link EmitResult#FAIL_OVERFLOW}
                • - *
                • {@link Many#emitNext(Object, EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, EmitFailureHandler) emitting} + *
                • {@link Many#emitNext(Object, Sinks.EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, Sinks.EmitFailureHandler) emitting} * an {@link Exceptions#failWithOverflow() overflow error}.
                *
              • *
              • Replaying: No replay of values seen by earlier subscribers. Only forwards to a {@link Subscriber} @@ -531,18 +531,18 @@ * * @param bufferSize the maximum queue size */ - Many onBackpressureBuffer(int bufferSize); + Sinks.Many onBackpressureBuffer(int bufferSize); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                  *
                • Multicast
                • *
                • Without {@link Subscriber}: warm up. Remembers up to {@code bufferSize} * elements pushed via {@link Many#tryEmitNext(Object)} before the first {@link Subscriber} is registered.
                • *
                • Backpressure : this sink honors downstream demand by conforming to the lowest demand in case * of multiple subscribers.
                  If the difference between multiple subscribers is too high compared to {@code bufferSize}: *
                  • {@link Many#tryEmitNext(Object) tryEmitNext} will return {@link EmitResult#FAIL_OVERFLOW}
                  • - *
                  • {@link Many#emitNext(Object, EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, EmitFailureHandler) emitting} + *
                  • {@link Many#emitNext(Object, Sinks.EmitFailureHandler) emitNext} will terminate the sink by {@link Many#emitError(Throwable, Sinks.EmitFailureHandler) emitting} * an {@link Exceptions#failWithOverflow() overflow error}.
                  *
                • *
                • Replaying: No replay of values seen by earlier subscribers. Only forwards to a {@link Subscriber} @@ -555,10 +555,10 @@ * @param bufferSize the maximum queue size * @param autoCancel should the sink fully shutdowns (not publishing anymore) when the last subscriber cancels */ - Many onBackpressureBuffer(int bufferSize, boolean autoCancel); + Sinks.Many onBackpressureBuffer(int bufferSize, boolean autoCancel); /** - A {@link Many} with the following characteristics: + A {@link Sinks.Many} with the following characteristics: *
                    *
                  • Multicast
                  • *
                  • Without {@link Subscriber}: fail fast on {@link Many#tryEmitNext(Object) tryEmitNext}.
                  • @@ -574,12 +574,12 @@ * * * @param the type of elements to emit - * @return a multicast {@link Many} that "drops" in case any subscriber is too slow + * @return a multicast {@link Sinks.Many} that "drops" in case any subscriber is too slow */ - Many directAllOrNothing(); + Sinks.Many directAllOrNothing(); /** - A {@link Many} with the following characteristics: + A {@link Sinks.Many} with the following characteristics: *
                      *
                    • Multicast
                    • *
                    • Without {@link Subscriber}: fail fast on {@link Many#tryEmitNext(Object) tryEmitNext}.
                    • @@ -595,17 +595,17 @@ * * * @param the type of elements to emit - * @return a multicast {@link Many} that "drops" in case of no demand from any subscriber + * @return a multicast {@link Sinks.Many} that "drops" in case of no demand from any subscriber */ - Many directBestEffort(); + Sinks.Many directBestEffort(); } /** * Provides multicast with history/replay capacity : 1 sink, N {@link Subscriber} */ public interface MulticastReplaySpec { /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                        *
                      • Multicast
                      • *
                      • Without {@link Subscriber}: all elements pushed to this sink are remembered, @@ -614,10 +614,10 @@ *
                      • Replaying: all elements pushed to this sink are replayed to new subscribers.
                      • *
                      */ - Many all(); + Sinks.Many all(); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                        *
                      • Multicast
                      • *
                      • Without {@link Subscriber}: all elements pushed to this sink are remembered, @@ -627,10 +627,10 @@ *
                      * @param batchSize the underlying buffer will optimize storage by linked arrays of given size */ - Many all(int batchSize); + Sinks.Many all(int batchSize); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                        *
                      • Multicast
                      • *
                      • Without {@link Subscriber}: the latest element pushed to this sink are remembered, @@ -639,10 +639,10 @@ *
                      • Replaying: the latest element pushed to this sink is replayed to new subscribers.
                      • *
                      */ - Many latest(); + Sinks.Many latest(); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                        *
                      • Multicast
                      • *
                      • Without {@link Subscriber}: the latest element pushed to this sink are remembered, @@ -653,10 +653,10 @@ * * @param value default value if there is no latest element to replay */ - Many latestOrDefault(T value); + Sinks.Many latestOrDefault(T value); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                          *
                        • Multicast
                        • *
                        • Without {@link Subscriber}: up to {@code historySize} elements pushed to this sink are remembered, @@ -671,10 +671,10 @@ * * @param historySize maximum number of elements able to replayed, strictly positive */ - Many limit(int historySize); + Sinks.Many limit(int historySize); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                            *
                          • Multicast
                          • *
                          • Without {@link Subscriber}: all elements pushed to this sink are remembered until their {@code maxAge} is reached, @@ -686,10 +686,10 @@ * * @param maxAge maximum retention time for elements to be retained */ - Many limit(Duration maxAge); + Sinks.Many limit(Duration maxAge); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                              *
                            • Multicast
                            • *
                            • Without {@link Subscriber}: all elements pushed to this sink are remembered until their {@code maxAge} is reached, @@ -703,10 +703,10 @@ * @param maxAge maximum retention time for elements to be retained * @param scheduler a {@link Scheduler} to derive the time from */ - Many limit(Duration maxAge, Scheduler scheduler); + Sinks.Many limit(Duration maxAge, Scheduler scheduler); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                                *
                              • Multicast
                              • *
                              • Without {@link Subscriber}: up to {@code historySize} elements pushed to this sink are remembered, @@ -723,10 +723,10 @@ * @param historySize maximum number of elements able to replayed, strictly positive * @param maxAge maximum retention time for elements to be retained */ - Many limit(int historySize, Duration maxAge); + Sinks.Many limit(int historySize, Duration maxAge); /** - * A {@link Many} with the following characteristics: + * A {@link Sinks.Many} with the following characteristics: *
                                  *
                                • Multicast
                                • *
                                • Without {@link Subscriber}: up to {@code historySize} elements pushed to this sink are remembered, @@ -744,7 +744,7 @@ * @param maxAge maximum retention time for elements to be retained * @param scheduler a {@link Scheduler} to derive the time from */ - Many limit(int historySize, Duration maxAge, Scheduler scheduler); + Sinks.Many limit(int historySize, Duration maxAge, Scheduler scheduler); } /** @@ -818,7 +818,7 @@ *
                                • *
                                • * {@link EmitResult#FAIL_OVERFLOW}: discard the value ({@link Operators#onDiscard(Object, Context)}) - * then call {@link #emitError(Throwable, EmitFailureHandler)} with a {@link Exceptions#failWithOverflow(String)} exception. + * then call {@link #emitError(Throwable, Sinks.EmitFailureHandler)} with a {@link Exceptions#failWithOverflow(String)} exception. *
                                • *
                                • * {@link EmitResult#FAIL_CANCELLED}: discard the value ({@link Operators#onDiscard(Object, Context)}). @@ -955,21 +955,21 @@ /** * Return a {@link Flux} view of this sink. Every call returns the same instance. * - * @return the {@link Flux} view associated to this {@link Many} + * @return the {@link Flux} view associated to this {@link Sinks.Many} */ Flux asFlux(); } /** - * A {@link Many} which additionally allows being subscribed to an upstream {@link Publisher}, + * A {@link Sinks.Many} which additionally allows being subscribed to an upstream {@link Publisher}, * which is an advanced pattern requiring external synchronization. See {@link #subscribeTo(Publisher)}} for more details. * * @param the type of data emitted by the sink */ public interface ManyWithUpstream extends Many { /** - * Explicitly subscribe this {@link Many} to an upstream {@link Publisher} without + * Explicitly subscribe this {@link Sinks.Many} to an upstream {@link Publisher} without * exposing it as a {@link Subscriber} at all. *

                                  * Note that when this is done, one MUST stop using emit/tryEmit APIs, reserving signal @@ -1006,7 +1006,7 @@ * example of how each of these can be dealt with, to decide if the emit API would be a good enough fit instead. * * @return an {@link EmitResult}, which should be checked to distinguish different possible failures - * @see #emitEmpty(EmitFailureHandler) + * @see #emitEmpty(Sinks.EmitFailureHandler) * @see Subscriber#onComplete() */ EmitResult tryEmitEmpty(); @@ -1020,7 +1020,7 @@ * * @param error the exception to signal, not null * @return an {@link EmitResult}, which should be checked to distinguish different possible failures - * @see #emitError(Throwable, EmitFailureHandler) + * @see #emitError(Throwable, Sinks.EmitFailureHandler) * @see Subscriber#onError(Throwable) */ EmitResult tryEmitError(Throwable error); @@ -1135,7 +1135,7 @@ /** * Return a {@link Mono} view of this sink. Every call returns the same instance. * - * @return the {@link Mono} view associated to this {@link One} + * @return the {@link Mono} view associated to this {@link Sinks.One} */ Mono asMono(); } @@ -1164,7 +1164,7 @@ * * @param value the value to emit and complete with, or {@code null} to only trigger an onComplete * @return an {@link EmitResult}, which should be checked to distinguish different possible failures - * @see #emitValue(Object, EmitFailureHandler) + * @see #emitValue(Object, Sinks.EmitFailureHandler) * @see Subscriber#onNext(Object) * @see Subscriber#onComplete() */ @@ -1190,7 +1190,7 @@ *

                                • *
                                • * {@link EmitResult#FAIL_OVERFLOW}: discard the value ({@link Operators#onDiscard(Object, Context)}) - * then call {@link #emitError(Throwable, EmitFailureHandler)} with a {@link Exceptions#failWithOverflow(String)} exception. + * then call {@link #emitError(Throwable, Sinks.EmitFailureHandler)} with a {@link Exceptions#failWithOverflow(String)} exception. *
                                • *
                                • * {@link EmitResult#FAIL_CANCELLED}: discard the value ({@link Operators#onDiscard(Object, Context)}). @@ -1218,4 +1218,4 @@ */ void emitValue(@Nullable T value, EmitFailureHandler failureHandler); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/publisher/SinksSpecs.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SinksSpecs.java (.../SinksSpecs.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/publisher/SinksSpecs.java (.../SinksSpecs.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -108,17 +108,17 @@ } @Override - public Many onBackpressureBuffer() { + public Sinks.Many onBackpressureBuffer() { return new SinkManyEmitterProcessor<>(true, Queues.SMALL_BUFFER_SIZE); } @Override - public Many onBackpressureBuffer(int bufferSize) { + public Sinks.Many onBackpressureBuffer(int bufferSize) { return new SinkManyEmitterProcessor<>(true, bufferSize); } @Override - public Many onBackpressureBuffer(int bufferSize, boolean autoCancel) { + public Sinks.Many onBackpressureBuffer(int bufferSize, boolean autoCancel) { return new SinkManyEmitterProcessor<>(autoCancel, bufferSize); } Index: 3rdParty_sources/reactor/reactor/core/publisher/SourceProducer.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/SourceProducer.java (.../SourceProducer.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/SourceProducer.java (.../SourceProducer.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,8 +36,9 @@ @Override @Nullable default Object scanUnsafe(Attr key) { - if (key == Attr.PARENT) return Scannable.from(null); - if (key == Attr.ACTUAL) return Scannable.from(null); + if (key == Attr.PARENT) return null; + if (key == Attr.ACTUAL) return null; + if (key == InternalProducerAttr.INSTANCE) return true; return null; } Index: 3rdParty_sources/reactor/reactor/core/publisher/Traces.java =================================================================== diff -u -r03ee7b3a8cdecd210e54619377d06f9c7cb4014b -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/publisher/Traces.java (.../Traces.java) (revision 03ee7b3a8cdecd210e54619377d06f9c7cb4014b) +++ 3rdParty_sources/reactor/reactor/core/publisher/Traces.java (.../Traces.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2018-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,11 @@ package reactor.core.publisher; -import java.util.Iterator; import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; -import sun.misc.JavaLangAccess; -import sun.misc.SharedSecrets; /** * Utilities around manipulating stack traces and displaying assembly traces. @@ -48,219 +45,9 @@ * each element being prepended with a tabulation and appended with a * newline. */ - static Supplier> callSiteSupplierFactory; + static final Supplier> callSiteSupplierFactory = new CallSiteSupplierFactory(); - static { - String[] strategyClasses = { - Traces.class.getName() + "$StackWalkerCallSiteSupplierFactory", - Traces.class.getName() + "$SharedSecretsCallSiteSupplierFactory", - Traces.class.getName() + "$ExceptionCallSiteSupplierFactory", - }; - // find one available call-site supplier w.r.t. the jdk version to provide - // linkage-compatibility between jdk 8 and 9+ - callSiteSupplierFactory = Stream - .of(strategyClasses) - .flatMap(className -> { - try { - Class clazz = Class.forName(className); - @SuppressWarnings("unchecked") - Supplier> function = (Supplier) clazz.getDeclaredConstructor() - .newInstance(); - return Stream.of(function); - } - // explicitly catch LinkageError to support static code analysis - // tools detect the attempt at finding out jdk environment - catch (LinkageError e) { - return Stream.empty(); - } - catch (Throwable e) { - return Stream.empty(); - } - }) - .findFirst() - .orElseThrow(() -> new IllegalStateException("Valid strategy not found")); - } - /** - * Utility class for the call-site extracting on Java 9+. - * - */ - @SuppressWarnings("unused") - static final class StackWalkerCallSiteSupplierFactory implements Supplier> { - - static { - // Trigger eager StackWalker class loading. - StackWalker.getInstance(); - } - - /** - * Transform the current stack trace into a {@link String} representation, - * each element being prepended with a tabulation and appended with a - * newline. - * - * @return the string version of the stacktrace. - */ - @Override - public Supplier get() { - StackWalker.StackFrame[] stack = StackWalker.getInstance().walk(s -> { - StackWalker.StackFrame[] result = new StackWalker.StackFrame[10]; - Iterator iterator = s.iterator(); - iterator.next(); // .get - - int i = 0; - while (iterator.hasNext()) { - StackWalker.StackFrame frame = iterator.next(); - - if (i >= result.length) { - return new StackWalker.StackFrame[0]; - } - - result[i++] = frame; - - if (isUserCode(frame.getClassName())) { - break; - } - } - StackWalker.StackFrame[] copy = new StackWalker.StackFrame[i]; - System.arraycopy(result, 0, copy, 0, i); - return copy; - }); - - if (stack.length == 0) { - return () -> ""; - } - - if (stack.length == 1) { - return () -> "\t" + stack[0].toString() + "\n"; - } - - return () -> { - StringBuilder sb = new StringBuilder(); - - for (int j = stack.length - 2; j > 0; j--) { - StackWalker.StackFrame previous = stack[j]; - - if (!full) { - if (previous.isNativeMethod()) { - continue; - } - - String previousRow = previous.getClassName() + "." + previous.getMethodName(); - if (shouldSanitize(previousRow)) { - continue; - } - } - sb.append("\t") - .append(previous.toString()) - .append("\n"); - break; - } - - sb.append("\t") - .append(stack[stack.length - 1].toString()) - .append("\n"); - - return sb.toString(); - }; - } - } - - @SuppressWarnings("unused") - static class SharedSecretsCallSiteSupplierFactory implements Supplier> { - - @Override - public Supplier get() { - return new TracingException(); - } - - static class TracingException extends Throwable implements Supplier { - - static final JavaLangAccess javaLangAccess = SharedSecrets.getJavaLangAccess(); - - @Override - public String get() { - int stackTraceDepth = javaLangAccess.getStackTraceDepth(this); - - StackTraceElement previousElement = null; - // Skip get() - for (int i = 2; i < stackTraceDepth; i++) { - StackTraceElement e = javaLangAccess.getStackTraceElement(this, i); - - String className = e.getClassName(); - if (isUserCode(className)) { - StringBuilder sb = new StringBuilder(); - - if (previousElement != null) { - sb.append("\t").append(previousElement.toString()).append("\n"); - } - sb.append("\t").append(e.toString()).append("\n"); - return sb.toString(); - } - else { - if (!full && e.getLineNumber() <= 1) { - continue; - } - - String classAndMethod = className + "." + e.getMethodName(); - if (!full && shouldSanitize(classAndMethod)) { - continue; - } - previousElement = e; - } - } - - return ""; - } - } - } - - @SuppressWarnings("unused") - static class ExceptionCallSiteSupplierFactory implements Supplier> { - - @Override - public Supplier get() { - return new TracingException(); - } - - static class TracingException extends Throwable implements Supplier { - - @Override - public String get() { - StackTraceElement previousElement = null; - StackTraceElement[] stackTrace = getStackTrace(); - // Skip get() - for (int i = 2; i < stackTrace.length; i++) { - StackTraceElement e = stackTrace[i]; - - String className = e.getClassName(); - if (isUserCode(className)) { - StringBuilder sb = new StringBuilder(); - - if (previousElement != null) { - sb.append("\t").append(previousElement.toString()).append("\n"); - } - sb.append("\t").append(e.toString()).append("\n"); - return sb.toString(); - } - else { - if (!full && e.getLineNumber() <= 1) { - continue; - } - - String classAndMethod = className + "." + e.getMethodName(); - if (!full && shouldSanitize(classAndMethod)) { - continue; - } - previousElement = e; - } - } - - return ""; - } - } - } - - /** * Return true for strings (usually from a stack trace element) that should be * sanitized out by {@link Traces#callSiteSupplierFactory}. * Index: 3rdParty_sources/reactor/reactor/core/scheduler/BoundedElasticScheduler.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/scheduler/BoundedElasticScheduler.java (.../BoundedElasticScheduler.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/scheduler/BoundedElasticScheduler.java (.../BoundedElasticScheduler.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -120,7 +120,7 @@ /** * Create a {@link BoundedElasticScheduler} with the given configuration. Note that backing threads - * (or executors) can be shared by each {@link Worker}, so each worker + * (or executors) can be shared by each {@link reactor.core.scheduler.Scheduler.Worker}, so each worker * can contribute to the task queue size. * * @param maxThreads the maximum number of backing threads to spawn, must be strictly positive @@ -1097,4 +1097,4 @@ super.submit(command); } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/scheduler/BoundedElasticSchedulerSupplier.java =================================================================== diff -u --- 3rdParty_sources/reactor/reactor/core/scheduler/BoundedElasticSchedulerSupplier.java (revision 0) +++ 3rdParty_sources/reactor/reactor/core/scheduler/BoundedElasticSchedulerSupplier.java (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 VMware Inc. or its affiliates, All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package reactor.core.scheduler; + +import java.util.function.Supplier; + +import reactor.util.Logger; +import reactor.util.Loggers; + +import static reactor.core.scheduler.Schedulers.BOUNDED_ELASTIC; +import static reactor.core.scheduler.Schedulers.DEFAULT_BOUNDED_ELASTIC_ON_VIRTUAL_THREADS; +import static reactor.core.scheduler.Schedulers.DEFAULT_BOUNDED_ELASTIC_QUEUESIZE; +import static reactor.core.scheduler.Schedulers.DEFAULT_BOUNDED_ELASTIC_SIZE; +import static reactor.core.scheduler.Schedulers.newBoundedElastic; + +/** + * JDK 8 Specific implementation of BoundedElasticScheduler supplier, which warns when + * one enables virtual thread support. An alternative variant is available for use on JDK 21+ + * where virtual threads are supported. + */ +class BoundedElasticSchedulerSupplier implements Supplier { + + static final Logger logger = Loggers.getLogger(BoundedElasticSchedulerSupplier.class); + + @Override + public Scheduler get() { + if (DEFAULT_BOUNDED_ELASTIC_ON_VIRTUAL_THREADS) { + logger.warn( + "Virtual Threads support is not available on the given JVM. Falling back to default BoundedElastic setup"); + } + + return newBoundedElastic(DEFAULT_BOUNDED_ELASTIC_SIZE, + DEFAULT_BOUNDED_ELASTIC_QUEUESIZE, + BOUNDED_ELASTIC, + BoundedElasticScheduler.DEFAULT_TTL_SECONDS, + true); + } +} Index: 3rdParty_sources/reactor/reactor/core/scheduler/BoundedElasticThreadPerTaskScheduler.java =================================================================== diff -u --- 3rdParty_sources/reactor/reactor/core/scheduler/BoundedElasticThreadPerTaskScheduler.java (revision 0) +++ 3rdParty_sources/reactor/reactor/core/scheduler/BoundedElasticThreadPerTaskScheduler.java (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 VMware Inc. or its affiliates, All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package reactor.core.scheduler; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +import reactor.core.Disposable; +import reactor.core.Scannable; + +/** + * This {@link BoundedElasticThreadPerTaskScheduler} variant is included when Reactor is + * used with JDK versions lower than 21, and all methods raise an + * {@link UnsupportedOperationException}. An alternative variant is available for use on + * JDK 21+ where virtual threads are supported. + */ +final class BoundedElasticThreadPerTaskScheduler + implements Scheduler, SchedulerState.DisposeAwaiter, Scannable { + + BoundedElasticThreadPerTaskScheduler(int maxThreads, int maxTaskQueuedPerThread, ThreadFactory factory) { + throw new UnsupportedOperationException("Unsupported in JDK lower than 21"); + } + + @Override + public boolean await(BoundedServices resource, long timeout, TimeUnit timeUnit) + throws InterruptedException { + return false; + } + + @Override + public Object scanUnsafe(Attr key) { + return null; + } + + @Override + public Disposable schedule(Runnable task) { + throw new UnsupportedOperationException("Unsupported in JDK lower than 21"); + } + + @Override + public Worker createWorker() { + throw new UnsupportedOperationException("Unsupported in JDK lower than 21"); + } + + static final class BoundedServices { + private BoundedServices() { + + } + + BoundedServices(BoundedElasticThreadPerTaskScheduler parent) {} + } +} \ No newline at end of file Index: 3rdParty_sources/reactor/reactor/core/scheduler/ExecutorScheduler.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/scheduler/ExecutorScheduler.java (.../ExecutorScheduler.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/scheduler/ExecutorScheduler.java (.../ExecutorScheduler.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -221,13 +221,13 @@ /** * A non-trampolining worker that tracks tasks. */ - static final class ExecutorSchedulerWorker implements Worker, WorkerDelete, Scannable { + static final class ExecutorSchedulerWorker implements Scheduler.Worker, WorkerDelete, Scannable { private final boolean wrapSchedule; final Executor executor; - final Composite tasks; + final Disposable.Composite tasks; ExecutorSchedulerWorker(Executor executor) { this.executor = executor; @@ -294,7 +294,7 @@ * A trampolining worker that tracks tasks. */ static final class ExecutorSchedulerTrampolineWorker - implements Worker, WorkerDelete, Runnable, Scannable { + implements Scheduler.Worker, WorkerDelete, Runnable, Scannable { private final boolean wrapSchedule; @@ -422,4 +422,4 @@ } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/scheduler/ImmediateScheduler.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/scheduler/ImmediateScheduler.java (.../ImmediateScheduler.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/scheduler/ImmediateScheduler.java (.../ImmediateScheduler.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -72,7 +72,7 @@ return new ImmediateSchedulerWorker(); } - static final class ImmediateSchedulerWorker implements Worker, Scannable { + static final class ImmediateSchedulerWorker implements Scheduler.Worker, Scannable { volatile boolean shutdown; @@ -104,4 +104,4 @@ } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/scheduler/Schedulers.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/core/scheduler/Schedulers.java (.../Schedulers.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/core/scheduler/Schedulers.java (.../Schedulers.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 VMware Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,6 +63,10 @@ * Factories prefixed with {@code new} (eg. {@link #newBoundedElastic(int, int, String)} return a new instance of their flavor of {@link Scheduler}, * while other factories like {@link #boundedElastic()} return a shared instance - which is the one used by operators requiring that flavor as their default Scheduler. * All instances are returned in a {@link Scheduler#init() initialized} state. + *

                                  + * Since 3.6.0 {@link #boundedElastic()} can run tasks on {@link VirtualThread}s if the application + * runs on a Java 21+ runtime and the {@link #DEFAULT_BOUNDED_ELASTIC_ON_VIRTUAL_THREADS} + * system property is set to {@code true}. * * @author Stephane Maldini */ @@ -105,6 +109,19 @@ .orElse(100000); /** + * Default execution of enqueued tasks on {@link Thread#ofVirtual} for the global + * {@link #boundedElastic()} {@link Scheduler}, + * initialized by system property {@code reactor.schedulers.defaultBoundedElasticOnVirtualThreads} + * and falls back to false . + * + * @see #boundedElastic() + */ + public static final boolean DEFAULT_BOUNDED_ELASTIC_ON_VIRTUAL_THREADS = + Optional.ofNullable(System.getProperty("reactor.schedulers.defaultBoundedElasticOnVirtualThreads")) + .map(Boolean::parseBoolean) + .orElse(false); + + /** * Create a {@link Scheduler} which uses a backing {@link Executor} to schedule * Runnables for async operators. * @@ -174,26 +191,69 @@ } /** - * The common boundedElastic instance, a {@link Scheduler} that dynamically creates a bounded number of - * ExecutorService-based Workers, reusing them once the Workers have been shut down. The underlying daemon - * threads can be evicted if idle for more than {@link BoundedElasticScheduler#DEFAULT_TTL_SECONDS 60} seconds. + * The common boundedElastic instance, a {@link Scheduler} that + * dynamically creates a bounded number of workers. *

                                  - * The maximum number of created threads is bounded by a {@code cap} (by default + * Depends on the available environment and specified configurations, there are two types + * of implementations for this shared scheduler: + *

                                    + * + *
                                  • ExecutorService-based implementation tailored to run on Platform {@link Thread} + * instances. Every Worker is {@link ExecutorService}-based. Reusing {@link Thread}s + * once the Workers have been shut down. The underlying daemon threads can be + * evicted if idle for more than + * {@link BoundedElasticScheduler#DEFAULT_TTL_SECONDS 60} seconds. + *
                                  • + * + *
                                  • As of 3.6.0 there is a thread-per-task implementation tailored for use + * with virtual threads. This implementation is enabled if the + * application runs on a JDK 21+ runtime and the system property + * {@link #DEFAULT_BOUNDED_ELASTIC_ON_VIRTUAL_THREADS} is set to + * {@code true}. Every Worker is based on the custom implementation of the execution + * mechanism which ensures every submitted task runs on a new + * {@link VirtualThread} instance. This implementation has a shared instance of + * {@link ScheduledExecutorService} used to schedule delayed and periodic tasks + * such that when triggered they are offloaded to a dedicated new + * {@link VirtualThread} instance. + *
                                  • + * + *
                                  + * + *

                                  + * Both implementations share the same configurations: + *

                                    + *
                                  • + * The maximum number of concurrent + * threads is bounded by a {@code cap} (by default * ten times the number of available CPU cores, see {@link #DEFAULT_BOUNDED_ELASTIC_SIZE}). + *

                                    + * Note: Consider increasing {@link #DEFAULT_BOUNDED_ELASTIC_SIZE} with the + * thread-per-task implementation to run more concurrent {@link VirtualThread} + * instances underneath. + *

                                  • + *
                                  • * The maximum number of task submissions that can be enqueued and deferred on each of these * backing threads is bounded (by default 100K additional tasks, see * {@link #DEFAULT_BOUNDED_ELASTIC_QUEUESIZE}). Past that point, a {@link RejectedExecutionException} * is thrown. + *
                                  • + *
                                  + * *

                                  - * By order of preference, threads backing a new {@link Scheduler.Worker} are - * picked from the idle pool, created anew or reused from the busy pool. In the later case, a best effort - * attempt at picking the thread backing the least amount of workers is made. + * Threads backing a new {@link reactor.core.scheduler.Scheduler.Worker} are + * picked from a pool or are created when needed. In the ExecutorService-based + * implementation, the pool is comprised either of idle or busy threads. When all + * threads are busy, a best effort attempt is made at picking the thread backing + * the least number of workers. In the case of the thread-per-task implementation, it + * always creates new threads up to the specified limit. *

                                  - * Note that if a thread is backing a low amount of workers, but these workers submit a lot of pending tasks, - * a second worker could end up being backed by the same thread and see tasks rejected. - * The picking of the backing thread is also done once and for all at worker creation, so - * tasks could be delayed due to two workers sharing the same backing thread and submitting long-running tasks, - * despite another backing thread becoming idle in the meantime. + * Note that if a scheduling mechanism is backing a low amount of workers, but these + * workers submit a lot of pending tasks, a second worker could end up being + * backed by the same mechanism and see tasks rejected. + * The picking of the backing mechanism is also done once and for all at worker + * creation, so tasks could be delayed due to two workers sharing the same backing + * mechanism and submitting long-running tasks, despite another backing mechanism + * becoming idle in the meantime. *

                                  * Only one instance of this common scheduler will be created on the first call and is cached. The same instance * is returned on subsequent calls until it is disposed. @@ -202,9 +262,12 @@ * between callers. They can however be all {@link #shutdownNow() shut down} together, or replaced by a * {@link #setFactory(Factory) change in Factory}. * - * @return the common boundedElastic instance, a {@link Scheduler} that dynamically creates workers with - * an upper bound to the number of backing threads and after that on the number of enqueued tasks, that reuses - * threads and evict idle ones + *

                                  + * + * @return the ExecutorService/thread-per-task-based boundedElastic + * instance. + * A {@link Scheduler} that dynamically creates workers with an upper + * bound to the number of backing threads and after that on the number of enqueued tasks. */ public static Scheduler boundedElastic() { return cache(CACHED_BOUNDED_ELASTIC, BOUNDED_ELASTIC, BOUNDED_ELASTIC_SUPPLIER); @@ -252,7 +315,7 @@ * backing threads is bounded by the provided {@code queuedTaskCap}. Past that point, * a {@link RejectedExecutionException} is thrown. *

                                  - * By order of preference, threads backing a new {@link Scheduler.Worker} are + * By order of preference, threads backing a new {@link reactor.core.scheduler.Scheduler.Worker} are * picked from the idle pool, created anew or reused from the busy pool. In the later case, a best effort * attempt at picking the thread backing the least amount of workers is made. *

                                  @@ -266,6 +329,12 @@ * from exiting until their worker has been disposed AND they've been evicted by TTL, or the whole * scheduler has been {@link Scheduler#dispose() disposed}. * + *

                                  + * Please note, this implementation is not designed to run tasks on + * {@link VirtualThread}. Please see + * {@link Factory#newThreadPerTaskBoundedElastic(int, int, ThreadFactory)} if you need + * {@link VirtualThread} compatible scheduler implementation + * * @param threadCap maximum number of underlying threads to create * @param queuedTaskCap maximum number of tasks to enqueue when no more threads can be created. Can be {@link Integer#MAX_VALUE} for unbounded enqueueing. * @param name Thread prefix @@ -287,7 +356,7 @@ * backing threads is bounded by the provided {@code queuedTaskCap}. Past that point, * a {@link RejectedExecutionException} is thrown. *

                                  - * By order of preference, threads backing a new {@link Scheduler.Worker} are + * By order of preference, threads backing a new {@link reactor.core.scheduler.Scheduler.Worker} are * picked from the idle pool, created anew or reused from the busy pool. In the later case, a best effort * attempt at picking the thread backing the least amount of workers is made. *

                                  @@ -301,10 +370,16 @@ * from exiting until their worker has been disposed AND they've been evicted by TTL, or the whole * scheduler has been {@link Scheduler#dispose() disposed}. * + *

                                  + * Please note, this implementation is not designed to run tasks on + * {@link VirtualThread}. Please see + * {@link Factory#newThreadPerTaskBoundedElastic(int, int, ThreadFactory)} if you need + * {@link VirtualThread} compatible scheduler implementation + * * @param threadCap maximum number of underlying threads to create * @param queuedTaskCap maximum number of tasks to enqueue when no more threads can be created. Can be {@link Integer#MAX_VALUE} for unbounded enqueueing. * @param name Thread prefix - * @param ttlSeconds Time-to-live for an idle {@link Scheduler.Worker} + * @param ttlSeconds Time-to-live for an idle {@link reactor.core.scheduler.Scheduler.Worker} * @return a new {@link Scheduler} that dynamically creates workers with an upper bound to * the number of backing threads and after that on the number of enqueued tasks, * that reuses threads and evict idle ones @@ -323,7 +398,7 @@ * backing threads is bounded by the provided {@code queuedTaskCap}. Past that point, * a {@link RejectedExecutionException} is thrown. *

                                  - * By order of preference, threads backing a new {@link Scheduler.Worker} are + * By order of preference, threads backing a new {@link reactor.core.scheduler.Scheduler.Worker} are * picked from the idle pool, created anew or reused from the busy pool. In the later case, a best effort * attempt at picking the thread backing the least amount of workers is made. *

                                  @@ -338,10 +413,16 @@ * worker has been disposed AND they've been evicted by TTL, or the whole scheduler has been * {@link Scheduler#dispose() disposed}. * + *

                                  + * Please note, this implementation is not designed to run tasks on + * {@link VirtualThread}. Please see + * {@link Factory#newThreadPerTaskBoundedElastic(int, int, ThreadFactory)} if you need + * {@link VirtualThread} compatible scheduler implementation + * * @param threadCap maximum number of underlying threads to create * @param queuedTaskCap maximum number of tasks to enqueue when no more threads can be created. Can be {@link Integer#MAX_VALUE} for unbounded enqueueing. * @param name Thread prefix - * @param ttlSeconds Time-to-live for an idle {@link Scheduler.Worker} + * @param ttlSeconds Time-to-live for an idle {@link reactor.core.scheduler.Scheduler.Worker} * @param daemon are backing threads {@link Thread#setDaemon(boolean) daemon threads} * @return a new {@link Scheduler} that dynamically creates workers with an upper bound to * the number of backing threads and after that on the number of enqueued tasks, @@ -364,7 +445,7 @@ * backing threads is bounded by the provided {@code queuedTaskCap}. Past that point, * a {@link RejectedExecutionException} is thrown. *

                                  - * By order of preference, threads backing a new {@link Scheduler.Worker} are + * By order of preference, threads backing a new {@link reactor.core.scheduler.Scheduler.Worker} are * picked from the idle pool, created anew or reused from the busy pool. In the later case, a best effort * attempt at picking the thread backing the least amount of workers is made. *

                                  @@ -379,10 +460,16 @@ * will prevent the JVM from exiting until their worker has been disposed AND they've been evicted by TTL, * or the whole scheduler has been {@link Scheduler#dispose() disposed}. * + *

                                  + * Please note, this implementation is not designed to run tasks on + * {@link VirtualThread}. Please see + * {@link Factory#newThreadPerTaskBoundedElastic(int, int, ThreadFactory)} if you need + * {@link VirtualThread} compatible scheduler implementation + * * @param threadCap maximum number of underlying threads to create * @param queuedTaskCap maximum number of tasks to enqueue when no more threads can be created. Can be {@link Integer#MAX_VALUE} for unbounded enqueueing. * @param threadFactory a {@link ThreadFactory} to use each thread initialization - * @param ttlSeconds Time-to-live for an idle {@link Scheduler.Worker} + * @param ttlSeconds Time-to-live for an idle {@link reactor.core.scheduler.Scheduler.Worker} * @return a new {@link Scheduler} that dynamically creates workers with an upper bound to * the number of backing threads and after that on the number of enqueued tasks, * that reuses threads and evict idle ones @@ -599,7 +686,7 @@ * *

                                  * The {@link MeterRegistry} used by reactor can be configured via - * {@link Metrics.MicrometerConfiguration#useRegistry(MeterRegistry)} + * {@link reactor.util.Metrics.MicrometerConfiguration#useRegistry(MeterRegistry)} * prior to using this method, the default being * {@link io.micrometer.core.instrument.Metrics#globalRegistry}. *

                                  @@ -945,16 +1032,16 @@ } /** - * Wraps a single {@link Scheduler.Worker} from some other - * {@link Scheduler} and provides {@link Scheduler.Worker} + * Wraps a single {@link reactor.core.scheduler.Scheduler.Worker} from some other + * {@link Scheduler} and provides {@link reactor.core.scheduler.Scheduler.Worker} * services on top of it. Unlike with other factory methods in this class, the delegate * is assumed to be {@link Scheduler#init() initialized} and won't be implicitly * initialized by this method. *

                                  * Use the {@link Scheduler#dispose()} to release the wrapped worker. * * @param original a {@link Scheduler} to call upon to get the single {@link - * Scheduler.Worker} + * reactor.core.scheduler.Scheduler.Worker} * * @return a wrapping {@link Scheduler} consistently returning a same worker from a * source {@link Scheduler} @@ -973,12 +1060,12 @@ * Workers, reusing them once the Workers have been shut down. The underlying (user or daemon) * threads can be evicted if idle for more than {@code ttlSeconds}. *

                                  - * The maximum number of created thread pools is bounded by the provided {@code cap}. + * The maximum number of created thread pools is bounded by the provided {@code threadCap}. * * @param threadCap maximum number of underlying threads to create * @param queuedTaskCap maximum number of tasks to enqueue when no more threads can be created. Can be {@link Integer#MAX_VALUE} for unbounded enqueueing. * @param threadFactory a {@link ThreadFactory} to use each thread initialization - * @param ttlSeconds Time-to-live for an idle {@link Scheduler.Worker} + * @param ttlSeconds Time-to-live for an idle {@link reactor.core.scheduler.Scheduler.Worker} * * @return a new {@link Scheduler} that dynamically creates workers with an upper bound to * the number of backing threads, reuses threads and evict idle ones @@ -988,6 +1075,31 @@ } /** + * {@link Scheduler} that dynamically creates a bounded number of Workers. + *

                                  + * The maximum number of created thread pools is bounded by the provided {@code threadCap}. + *

                                  + * The main difference between {@link BoundedElasticScheduler} and + * {@link BoundedElasticThreadPerTaskScheduler} is that underlying machinery + * allocates a new thread for every new task which is one of the requirements + * for usage with {@link VirtualThread}s + *

                                  + * Note: for now this scheduler is available only in Java 21+ runtime + * + * @param threadCap maximum number of underlying threads to create + * @param queuedTaskCap maximum number of tasks to enqueue when no more threads can be created. Can be {@link Integer#MAX_VALUE} for unbounded enqueueing. + * @param threadFactory a {@link ThreadFactory} to use each thread initialization + * + * @since 3.6.0 + * + * @return a new {@link Scheduler} that dynamically creates workers with an upper bound to + * the number of backing threads + */ + default Scheduler newThreadPerTaskBoundedElastic(int threadCap, int queuedTaskCap, ThreadFactory threadFactory) { + return new BoundedElasticThreadPerTaskScheduler(threadCap, queuedTaskCap, threadFactory); + } + + /** * {@link Scheduler} that hosts a fixed pool of workers and is suited for parallel * work. * @@ -1060,6 +1172,7 @@ // Internals static final String BOUNDED_ELASTIC = "boundedElastic"; // Blocking stuff with scale to zero + static final String LOOM_BOUNDED_ELASTIC = "loomBoundedElastic"; // Loom stuff static final String PARALLEL = "parallel"; //scale up common tasks static final String SINGLE = "single"; //non blocking tasks static final String IMMEDIATE = "immediate"; @@ -1072,9 +1185,7 @@ static AtomicReference CACHED_PARALLEL = new AtomicReference<>(); static AtomicReference CACHED_SINGLE = new AtomicReference<>(); - static final Supplier BOUNDED_ELASTIC_SUPPLIER = - () -> newBoundedElastic(DEFAULT_BOUNDED_ELASTIC_SIZE, DEFAULT_BOUNDED_ELASTIC_QUEUESIZE, - BOUNDED_ELASTIC, BoundedElasticScheduler.DEFAULT_TTL_SECONDS, true); + static final Supplier BOUNDED_ELASTIC_SUPPLIER = new BoundedElasticSchedulerSupplier(); static final Supplier PARALLEL_SUPPLIER = () -> newParallel(PARALLEL, DEFAULT_POOL_SIZE, true); @@ -1411,4 +1522,4 @@ return null; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/core/scheduler/VirtualThreadFactory.java =================================================================== diff -u --- 3rdParty_sources/reactor/reactor/core/scheduler/VirtualThreadFactory.java (revision 0) +++ 3rdParty_sources/reactor/reactor/core/scheduler/VirtualThreadFactory.java (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018-2023 VMware Inc. or its affiliates, All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package reactor.core.scheduler; + +import java.util.concurrent.ThreadFactory; +import java.util.function.BiConsumer; + +import reactor.util.annotation.NonNull; +import reactor.util.annotation.Nullable; + +/** + * The noop {@link VirtualThread} Reactor {@link ThreadFactory} to be + * used with {@link BoundedElasticThreadPerTaskScheduler}. + * This {@link VirtualThreadFactory} variant is included when Reactor is used with + * JDK versions lower than 21, + * and all methods raise an {@link UnsupportedOperationException}. + * An alternative variant is available for use on JDK 21+ + * where virtual threads are supported. + * + * @author Oleh Dokuka + */ +class VirtualThreadFactory implements ThreadFactory, + Thread.UncaughtExceptionHandler { + + + VirtualThreadFactory(String name, + boolean inheritThreadLocals, + @Nullable BiConsumer uncaughtExceptionHandler) { + throw new UnsupportedOperationException("Virtual Threads are not supported in JVM lower than 21"); + } + + @Override + public final Thread newThread(@NonNull Runnable runnable) { + throw new UnsupportedOperationException("Virtual Threads are not supported in JVM lower than 21"); + } + + @Override + public void uncaughtException(Thread t, Throwable e) { + throw new UnsupportedOperationException("Virtual Threads are not supported in JVM lower than 21"); + } +} Index: 3rdParty_sources/reactor/reactor/util/concurrent/MpscLinkedQueue.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/util/concurrent/MpscLinkedQueue.java (.../MpscLinkedQueue.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/util/concurrent/MpscLinkedQueue.java (.../MpscLinkedQueue.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -63,7 +63,7 @@ * This works because each producer is guaranteed to 'plant' a new node and link the old node. No 2 * producers can get the same producer node as part of XCHG guarantee. * - * @see java.util.Queue#offer(Object) + * @see java.util.Queue#offer(java.lang.Object) */ @Override @SuppressWarnings("unchecked") @@ -92,7 +92,7 @@ * This works because each producer is guaranteed to 'plant' a new node and link the old node. No 2 * producers can get the same producer node as part of XCHG guarantee. * - * @see java.util.Queue#offer(Object) + * @see java.util.Queue#offer(java.lang.Object) * * @param e1 first element to offer * @param e2 second element to offer @@ -290,4 +290,4 @@ return next; } } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/util/context/Context.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/util/context/Context.java (.../Context.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/util/context/Context.java (.../Context.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -32,7 +32,7 @@ * might want to associate a dedicated mutable structure to a single key to represent his * own context instead of using multiple {@link #put}, which could be more costly. * Past five user key/value pair, the {@link Context} will use a copy-on-write - * implementation backed by a new {@link Map} on each {@link #put}. + * implementation backed by a new {@link java.util.Map} on each {@link #put}. * * @author Stephane Maldini */ @@ -315,4 +315,4 @@ default Context putAll(Context context) { return this.putAll(context.readOnly()); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/util/context/ContextN.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/util/context/ContextN.java (.../ContextN.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/util/context/ContextN.java (.../ContextN.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -143,7 +143,7 @@ @Override public Stream> stream() { - return entrySet().stream().map(SimpleImmutableEntry::new); + return entrySet().stream().map(AbstractMap.SimpleImmutableEntry::new); } @Override @@ -213,4 +213,4 @@ public String toString() { return "ContextN" + super.toString(); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/util/retry/ImmutableRetrySignal.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/util/retry/ImmutableRetrySignal.java (.../ImmutableRetrySignal.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/util/retry/ImmutableRetrySignal.java (.../ImmutableRetrySignal.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -20,7 +20,7 @@ import reactor.util.context.ContextView; /** - * An immutable {@link Retry.RetrySignal} that can be used for retained + * An immutable {@link reactor.util.retry.Retry.RetrySignal} that can be used for retained * copies of mutable implementations. * * @author Simon Baslé @@ -74,4 +74,4 @@ public String toString() { return "attempt #" + (failureTotalIndex + 1) + " (" + (failureSubsequentIndex + 1) + " in a row), last failure={" + failure + '}'; } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/util/retry/RetryBackoffSpec.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/util/retry/RetryBackoffSpec.java (.../RetryBackoffSpec.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/util/retry/RetryBackoffSpec.java (.../RetryBackoffSpec.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -48,8 +48,8 @@ * Only errors that match the {@link #filter(Predicate)} are retried (by default all), * and the number of attempts can also limited with {@link #maxAttempts(long)}. * When the maximum attempt of retries is reached, a runtime exception is propagated downstream which - * can be pinpointed with {@link Exceptions#isRetryExhausted(Throwable)}. The cause of - * the last attempt's failure is attached as said {@link Exceptions#retryExhausted(String, Throwable) retryExhausted} + * can be pinpointed with {@link reactor.core.Exceptions#isRetryExhausted(Throwable)}. The cause of + * the last attempt's failure is attached as said {@link reactor.core.Exceptions#retryExhausted(String, Throwable) retryExhausted} * exception's cause. This can be customized with {@link #onRetryExhaustedThrow(BiFunction)}. *

                                  * Additionally, to help dealing with bursts of transient errors in a long-lived Flux as if each burst @@ -372,14 +372,14 @@ * Set the generator for the {@link Exception} to be propagated when the maximum amount of retries * is exhausted. By default, throws an {@link Exceptions#retryExhausted(String, Throwable)} with the * message reflecting the total attempt index, transient attempt index and maximum retry count. - * The cause of the last {@link RetrySignal} is also added + * The cause of the last {@link reactor.util.retry.Retry.RetrySignal} is also added * as the exception's cause. * * * @param retryExhaustedGenerator the {@link Function} that generates the {@link Throwable} for the last - * {@link RetrySignal} + * {@link reactor.util.retry.Retry.RetrySignal} * @return a new copy of the {@link RetryBackoffSpec} which can either be further - * configured or used as {@link Retry} + * configured or used as {@link reactor.util.retry.Retry} */ public RetryBackoffSpec onRetryExhaustedThrow(BiFunction retryExhaustedGenerator) { return new RetryBackoffSpec( @@ -400,8 +400,8 @@ /** * Set the transient error mode, indicating that the strategy being built should use - * {@link RetrySignal#totalRetriesInARow()} rather than - * {@link RetrySignal#totalRetries()}. + * {@link reactor.util.retry.Retry.RetrySignal#totalRetriesInARow()} rather than + * {@link reactor.util.retry.Retry.RetrySignal#totalRetries()}. * Transient errors are errors that could occur in bursts but are then recovered from by * a retry (with one or more onNext signals) before another error occurs. *

                                  @@ -608,4 +608,4 @@ .onErrorStop() ); } -} \ No newline at end of file +} Index: 3rdParty_sources/reactor/reactor/util/retry/RetrySpec.java =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c --- 3rdParty_sources/reactor/reactor/util/retry/RetrySpec.java (.../RetrySpec.java) (revision c4ce08dc0aae7d9da822088a3d5710484f6b0402) +++ 3rdParty_sources/reactor/reactor/util/retry/RetrySpec.java (.../RetrySpec.java) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -36,8 +36,8 @@ * Only errors that match the {@link #filter(Predicate)} are retried (by default all), up to {@link #maxAttempts(long)} times. *

                                  * When the maximum attempt of retries is reached, a runtime exception is propagated downstream which - * can be pinpointed with {@link Exceptions#isRetryExhausted(Throwable)}. The cause of - * the last attempt's failure is attached as said {@link Exceptions#retryExhausted(String, Throwable) retryExhausted} + * can be pinpointed with {@link reactor.core.Exceptions#isRetryExhausted(Throwable)}. The cause of + * the last attempt's failure is attached as said {@link reactor.core.Exceptions#retryExhausted(String, Throwable) retryExhausted} * exception's cause. This can be customized with {@link #onRetryExhaustedThrow(BiFunction)}. *

                                  * Additionally, to help dealing with bursts of transient errors in a long-lived Flux as if each burst @@ -303,10 +303,10 @@ * Set the generator for the {@link Exception} to be propagated when the maximum amount of retries * is exhausted. By default, throws an {@link Exceptions#retryExhausted(String, Throwable)} with the * message reflecting the total attempt index, transient attempt index and maximum retry count. - * The cause of the last {@link RetrySignal} is also added as the exception's cause. + * The cause of the last {@link reactor.util.retry.Retry.RetrySignal} is also added as the exception's cause. * * @param retryExhaustedGenerator the {@link Function} that generates the {@link Throwable} for the last - * {@link RetrySignal} + * {@link reactor.util.retry.Retry.RetrySignal} * @return a new copy of the {@link RetrySpec} which can either be further configured or used as {@link Retry} */ public RetrySpec onRetryExhaustedThrow(BiFunction retryExhaustedGenerator) { @@ -324,8 +324,8 @@ /** * Set the transient error mode, indicating that the strategy being built should use - * {@link RetrySignal#totalRetriesInARow()} rather than - * {@link RetrySignal#totalRetries()}. + * {@link reactor.util.retry.Retry.RetrySignal#totalRetriesInARow()} rather than + * {@link reactor.util.retry.Retry.RetrySignal#totalRetries()}. * Transient errors are errors that could occur in bursts but are then recovered from by * a retry (with one or more onNext signals) before another error occurs. *

                                  @@ -413,4 +413,4 @@ return preRetryMono.then(originalCompanion).flatMap(postRetryMono::thenReturn).contextWrite(cv); } -} \ No newline at end of file +} Index: idea_project/.idea/libraries/3rdParty.xml =================================================================== diff -u -r7a52ff105bdf91d903cd180e6b5bbf7bd2810b71 -r683b1a0cbc595fe30e200900d081c88105aae63c --- idea_project/.idea/libraries/3rdParty.xml (.../3rdParty.xml) (revision 7a52ff105bdf91d903cd180e6b5bbf7bd2810b71) +++ idea_project/.idea/libraries/3rdParty.xml (.../3rdParty.xml) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -13,7 +13,6 @@ - @@ -56,6 +55,7 @@ + Index: lams_build/lib/reactor/reactor-core-3.5.11.jar =================================================================== diff -u -rc4ce08dc0aae7d9da822088a3d5710484f6b0402 -r683b1a0cbc595fe30e200900d081c88105aae63c Binary files differ Index: lams_build/lib/reactor/reactor-core-3.6.4.jar =================================================================== diff -u Binary files differ Index: lams_build/lib/reactor/reactor.module.xml =================================================================== diff -u -r5661c79b661c18221c0eb5e32fe7ec54110e5a65 -r683b1a0cbc595fe30e200900d081c88105aae63c --- lams_build/lib/reactor/reactor.module.xml (.../reactor.module.xml) (revision 5661c79b661c18221c0eb5e32fe7ec54110e5a65) +++ lams_build/lib/reactor/reactor.module.xml (.../reactor.module.xml) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) @@ -24,7 +24,7 @@ - +