reactor.core.publisher.FluxMerge Maven / Gradle / Ivy
Show all versions of redisson-all Show documentation
/*
* 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.
* 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.Objects;
import java.util.Queue;
import java.util.function.IntFunction;
import java.util.function.Supplier;
import org.reactivestreams.Publisher;
import reactor.core.CoreSubscriber;
/**
* Merges a fixed array of Publishers.
* @param the element type of the publishers
* @see Reactive-Streams-Commons
*/
final class FluxMerge extends Flux implements SourceProducer {
final Publisher extends T>[] sources;
final boolean delayError;
final int maxConcurrency;
final Supplier extends Queue> mainQueueSupplier;
final int prefetch;
final Supplier extends Queue> innerQueueSupplier;
FluxMerge(Publisher extends T>[] sources,
boolean delayError, int maxConcurrency,
Supplier extends Queue> mainQueueSupplier,
int prefetch, Supplier extends Queue> innerQueueSupplier) {
if (prefetch <= 0) {
throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch);
}
if (maxConcurrency <= 0) {
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;
this.mainQueueSupplier = Objects.requireNonNull(mainQueueSupplier, "mainQueueSupplier");
this.innerQueueSupplier = Objects.requireNonNull(innerQueueSupplier, "innerQueueSupplier");
}
@Override
public void subscribe(CoreSubscriber super T> actual) {
FluxFlatMap.FlatMapMain, T> merger = new FluxFlatMap.FlatMapMain<>(
actual, identityFunction(), delayError, maxConcurrency, mainQueueSupplier, prefetch,
innerQueueSupplier);
merger.onSubscribe(new FluxArray.ArraySubscription<>(merger, sources));
}
/**
* Returns a new instance which has the additional source to be merged together with
* the current array of sources.
*
* This operation doesn't change the current FluxMerge instance.
*
* @param source the new source to merge with the others
* @param newQueueSupplier a function that should return a new queue supplier based on the change in the maxConcurrency value
* @return the new FluxMerge instance
*/
FluxMerge mergeAdditionalSource(Publisher extends T> source, IntFunction>> newQueueSupplier) {
int n = sources.length;
@SuppressWarnings("unchecked")
Publisher extends T>[] newArray = new Publisher[n + 1];
System.arraycopy(sources, 0, newArray, 0, n);
newArray[n] = source;
// increase the maxConcurrency because if merged separately, it would have run concurrently anyway
Supplier extends Queue> newMainQueue;
int mc = maxConcurrency;
if (mc != Integer.MAX_VALUE) {
mc++;
newMainQueue = newQueueSupplier.apply(mc);
} else {
newMainQueue = mainQueueSupplier;
}
return new FluxMerge<>(newArray, delayError, mc, newMainQueue, prefetch, innerQueueSupplier);
}
@Override
public Object scanUnsafe(Attr key) {
if (key == Attr.DELAY_ERROR) return delayError;
if (key == Attr.PREFETCH) return prefetch;
if (key == Attr.RUN_STYLE) return Attr.RunStyle.SYNC;
return SourceProducer.super.scanUnsafe(key);
}
}