io.reactivex.rxjava3.internal.util.EndConsumerHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of redisson-all Show documentation
Show all versions of redisson-all Show documentation
Easy Redis Java client and Real-Time Data Platform. Valkey compatible. Sync/Async/RxJava3/Reactive API. Client side caching. Over 50 Redis based Java objects and services: JCache API, Apache Tomcat, Hibernate, Spring, Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Scheduler, RPC
/*
* Copyright (c) 2016-present, RxJava Contributors.
*
* 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
*
* http://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 io.reactivex.rxjava3.internal.util;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import org.reactivestreams.Subscription;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.exceptions.ProtocolViolationException;
import io.reactivex.rxjava3.internal.disposables.DisposableHelper;
import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper;
import io.reactivex.rxjava3.plugins.RxJavaPlugins;
/**
* Utility class to help report multiple subscriptions with the same
* consumer type instead of the internal "Disposable already set!" message
* that is practically reserved for internal operators and indicate bugs in them.
*/
public final class EndConsumerHelper {
/**
* Utility class.
*/
private EndConsumerHelper() {
throw new IllegalStateException("No instances!");
}
/**
* Ensures that the upstream Disposable is null and returns true, otherwise
* disposes the next Disposable and if the upstream is not the shared
* disposed instance, reports a ProtocolViolationException due to
* multiple subscribe attempts.
* @param upstream the upstream current value
* @param next the Disposable to check for nullness and dispose if necessary
* @param observer the class of the consumer to have a personalized
* error message if the upstream already contains a non-cancelled Disposable.
* @return true if successful, false if the upstream was non null
*/
public static boolean validate(Disposable upstream, Disposable next, Class> observer) {
Objects.requireNonNull(next, "next is null");
if (upstream != null) {
next.dispose();
if (upstream != DisposableHelper.DISPOSED) {
reportDoubleSubscription(observer);
}
return false;
}
return true;
}
/**
* Atomically updates the target upstream AtomicReference from null to the non-null
* next Disposable, otherwise disposes next and reports a ProtocolViolationException
* if the AtomicReference doesn't contain the shared disposed indicator.
* @param upstream the target AtomicReference to update
* @param next the Disposable to set on it atomically
* @param observer the class of the consumer to have a personalized
* error message if the upstream already contains a non-cancelled Disposable.
* @return true if successful, false if the content of the AtomicReference was non null
*/
public static boolean setOnce(AtomicReference upstream, Disposable next, Class> observer) {
Objects.requireNonNull(next, "next is null");
if (!upstream.compareAndSet(null, next)) {
next.dispose();
if (upstream.get() != DisposableHelper.DISPOSED) {
reportDoubleSubscription(observer);
}
return false;
}
return true;
}
/**
* Ensures that the upstream Subscription is null and returns true, otherwise
* cancels the next Subscription and if the upstream is not the shared
* cancelled instance, reports a ProtocolViolationException due to
* multiple subscribe attempts.
* @param upstream the upstream current value
* @param next the Subscription to check for nullness and cancel if necessary
* @param subscriber the class of the consumer to have a personalized
* error message if the upstream already contains a non-cancelled Subscription.
* @return true if successful, false if the upstream was non null
*/
public static boolean validate(Subscription upstream, Subscription next, Class> subscriber) {
Objects.requireNonNull(next, "next is null");
if (upstream != null) {
next.cancel();
if (upstream != SubscriptionHelper.CANCELLED) {
reportDoubleSubscription(subscriber);
}
return false;
}
return true;
}
/**
* Atomically updates the target upstream AtomicReference from null to the non-null
* next Subscription, otherwise cancels next and reports a ProtocolViolationException
* if the AtomicReference doesn't contain the shared cancelled indicator.
* @param upstream the target AtomicReference to update
* @param next the Subscription to set on it atomically
* @param subscriber the class of the consumer to have a personalized
* error message if the upstream already contains a non-cancelled Subscription.
* @return true if successful, false if the content of the AtomicReference was non null
*/
public static boolean setOnce(AtomicReference upstream, Subscription next, Class> subscriber) {
Objects.requireNonNull(next, "next is null");
if (!upstream.compareAndSet(null, next)) {
next.cancel();
if (upstream.get() != SubscriptionHelper.CANCELLED) {
reportDoubleSubscription(subscriber);
}
return false;
}
return true;
}
/**
* Builds the error message with the consumer class.
* @param consumer the class of the consumer
* @return the error message string
*/
public static String composeMessage(String consumer) {
return "It is not allowed to subscribe with a(n) " + consumer + " multiple times. "
+ "Please create a fresh instance of " + consumer + " and subscribe that to the target source instead.";
}
/**
* Report a ProtocolViolationException with a personalized message referencing
* the simple type name of the consumer class and report it via
* RxJavaPlugins.onError.
* @param consumer the class of the consumer
*/
public static void reportDoubleSubscription(Class> consumer) {
RxJavaPlugins.onError(new ProtocolViolationException(composeMessage(consumer.getName())));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy