All Downloads are FREE. Search and download functionalities are using the official Maven repository.

reactor.core.Fuseable Maven / Gradle / Ivy

Go to download

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

There is a newer version: 3.40.2
Show newest version
/*
 * Copyright (c) 2016-2021 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;

import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.Callable;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.util.annotation.Nullable;

/**
 * A micro API for stream fusion, in particular marks producers that support a {@link QueueSubscription}.
 */
public interface Fuseable {

	/** Indicates the QueueSubscription can't support the requested mode. */
	int NONE = 0;
	/** Indicates the QueueSubscription can perform sync-fusion. */
	int SYNC = 1;
	/** Indicates the QueueSubscription can perform only async-fusion. */
	int ASYNC = 2;
	/** Indicates the QueueSubscription should decide what fusion it performs (input only). */
	int ANY = 3;
	/**
	 * Indicates that the queue will be drained from another thread
	 * thus any queue-exit computation may be invalid at that point.
	 * 

* For example, an {@code asyncSource.map().publishOn().subscribe()} sequence where {@code asyncSource} * is async-fuseable: publishOn may fuse the whole sequence into a single Queue. That in turn * could invoke the mapper function from its {@code poll()} method from another thread, * whereas the unfused sequence would have invoked the mapper on the previous thread. * If such mapper invocation is costly, it would escape its thread boundary this way. */ int THREAD_BARRIER = 0b100; //4 /** * Attempt to convert a fusion mode int code into a human-readable representation. * Note that this can include the {@link #THREAD_BARRIER} flag, as an appended {@code +THREAD_BARRIER}. *

* This method accepts {@code -1} as a special code, mainly for the benefit of supporting testing scenarios where * fusion can be entirely deactivated (returns {@code Disabled}). * Other negative values and unknown positive codes on the other hand return {@code Unknown(x)}. *

* Note that as this is a human-facing representation, the different values could evolve in the future. * As such, never compare the returned string to a constant, but always use this method on both sides of * a comparison. * * @param mode the fusion mode int code * @return a human-readable {@link String} representation of the code */ static String fusionModeName(int mode) { return fusionModeName(mode, false); } /** * Attempt to convert a fusion mode int code into a human-readable representation. * Note that this can include the {@link #THREAD_BARRIER} flag, as an appended {@code +THREAD_BARRIER}, * unless the {@code ignoreThreadBarrier} parameter is set to {@literal true}. *

* This method accepts {@code -1} as a special code, mainly for the benefit of supporting testing scenarios where * fusion can be entirely deactivated (returns {@code Disabled}). * Other negative values and unknown positive codes on the other hand return {@code Unknown(x)}. *

* Note that as this is a human-facing representation, the different values could evolve in the future. * As such, never compare the returned string to a constant, but always use this method on both sides of * a comparison. * * @param mode the fusion mode int code * @param ignoreThreadBarrier whether or not to ignore the {@link #THREAD_BARRIER} flag in the representation * @return a human-readable {@link String} representation of the code */ static String fusionModeName(int mode, boolean ignoreThreadBarrier) { int evaluated = mode; String threadBarrierSuffix = ""; if (mode >= 0) { evaluated = mode & ~THREAD_BARRIER; //erase the THREAD_BARRIER bit; if (!ignoreThreadBarrier && (mode & THREAD_BARRIER) == THREAD_BARRIER) { threadBarrierSuffix = "+THREAD_BARRIER"; } } switch (evaluated) { case -1: return "Disabled"; //this is more specific for tests or things that can entirely skip the fusion negotiation case Fuseable.NONE: return "NONE" + threadBarrierSuffix; case Fuseable.SYNC: return "SYNC" + threadBarrierSuffix; case Fuseable.ASYNC: return "ASYNC" + threadBarrierSuffix; default: return "Unknown(" + evaluated + ")" + threadBarrierSuffix; } } /** * A subscriber variant that can immediately tell if it consumed * the value or not, directly allowing a new value to be sent if * it didn't. This avoids the usual request(1) round-trip for dropped * values. * * @param the value type */ interface ConditionalSubscriber extends CoreSubscriber { /** * Try consuming the value and return true if successful. * @param t the value to consume, not null * @return true if consumed, false if dropped and a new value can be immediately sent */ boolean tryOnNext(T t); } /** * Support contract for queue-fusion based optimizations on subscriptions. * *

    *
  • * Synchronous sources which have fixed size and can * emit their items in a pull fashion, thus avoiding the request-accounting * overhead in many cases. *
  • *
  • * Asynchronous sources which can act as a queue and subscription at * the same time, saving on allocating another queue most of the time. *
  • *
* *

* * @param the value type emitted */ interface QueueSubscription extends Queue, Subscription { String NOT_SUPPORTED_MESSAGE = "Although QueueSubscription extends Queue it is purely internal" + " and only guarantees support for poll/clear/size/isEmpty." + " Instances shouldn't be used/exposed as Queue outside of Reactor operators."; /** * Request a specific fusion mode from this QueueSubscription. *

* One should request either SYNC, ASYNC or ANY modes (never NONE) * and the implementor should return NONE, SYNC or ASYNC (never ANY). *

* For example, if a source supports only ASYNC fusion but * the intermediate operator supports only SYNC fuseable sources, * the operator may request SYNC fusion and the source can reject it via * NONE, thus the operator can return NONE as well to downstream and the * fusion doesn't happen. * * @param requestedMode the mode requested by the intermediate operator * @return the actual fusion mode activated */ int requestFusion(int requestedMode); @Override @Nullable default T peek() { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default boolean add(@Nullable T t) { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default boolean offer(@Nullable T t) { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default T remove() { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default T element() { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default boolean contains(@Nullable Object o) { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default Iterator iterator() { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default Object[] toArray() { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default T1[] toArray(T1[] a) { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default boolean remove(@Nullable Object o) { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default boolean containsAll(Collection c) { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default boolean addAll(Collection c) { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default boolean removeAll(Collection c) { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } @Override default boolean retainAll(Collection c) { throw new UnsupportedOperationException(NOT_SUPPORTED_MESSAGE); } } /** * Base class for synchronous sources which have fixed size and can * emit their items in a pull fashion, thus avoiding the request-accounting * overhead in many cases. * * @param the content value type */ interface SynchronousSubscription extends QueueSubscription { @Override default int requestFusion(int requestedMode) { if ((requestedMode & Fuseable.SYNC) != 0) { return Fuseable.SYNC; } return NONE; } } /** * Marker interface indicating that the target can return a value or null, * otherwise fail immediately and thus a viable target for assembly-time * optimizations. * * @param the value type returned */ interface ScalarCallable extends Callable { } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy