
org.infinispan.CachePublisher Maven / Gradle / Ivy
package org.infinispan;
import java.util.Set;
import java.util.concurrent.CompletionStage;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import org.infinispan.commons.util.Experimental;
import org.infinispan.commons.util.IntSet;
import org.infinispan.configuration.cache.StateTransferConfiguration;
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.reactive.publisher.PublisherReducers;
import org.infinispan.reactive.publisher.PublisherTransformers;
import org.infinispan.reactive.publisher.impl.SegmentPublisherSupplier;
import org.infinispan.util.function.SerializableFunction;
import org.reactivestreams.Publisher;
/**
* Publisher to be used for non-blocking operations across the cache data set. Note that implementations must use
* the context of the Cache and the current thread it is invoked on. This means any current invocation context or
* {@link org.infinispan.context.Flag}s must be adhered to.
*
* A CachePublisher is immutable and any method that returns a CachePublisher may return a new instance.
*
* Note that any {@link Function} passed as an argument to any method on this interface will be marshalled and ran
* on the remote node. This means any state these Functions may reference will also be marshalled and these functions
* must not have any side effects.
*
* The {@link PublisherReducers} and {@link PublisherTransformers} classes have utility methods that can be used as
* functions as necessary. Note that any arguments to these methods must also be
* marshallable still.
*
* Note that any processor or data observed from the returned Publisher or Stage will be performed solely in the subscriber's
* node and thus can use data that cannot be marshalled and may have side effects as needed.
* @param key type in the cache
* @param value type in the cache
*
* This API is currently Experimental and may be changed or even removed later, use at your own risk.
*/
@Experimental
public interface CachePublisher {
/**
* Configures reduction methods to operate in parallel across nodes. This only affects methods
* like {@link #entryReduction(Function, Function)} and {@link #keyReduction(Function, Function)}.
* The {@link #entryPublisher(Function)} and {@link #keyPublisher(SerializableFunction)} are not affected
* by this setting. Defaults to sequential.
*
* Care should be taken when setting this as it may cause adverse performance in some use cases.
* @return a publisher that will perform reduction methods in parallel
*/
CachePublisher parallelReduction();
/**
* Configures reduction methods to operate in sequential across nodes. This only affects methods
* like {@link #entryReduction(Function, Function)} and {@link #keyReduction(Function, Function)}.
* The {@link #entryPublisher(Function)} and {@link #keyPublisher(SerializableFunction)} are not affected
* by this setting. Defaults to sequential.
* @return a publisher that will perform reduction methods in sequential
*/
CachePublisher sequentialReduction();
/**
* Configures publisher methods chunk size when retrieving remote values. This only affects methods like
* {@link #entryPublisher(Function)} and {@link #keyPublisher(Function)}. The
* {@link #entryReduction(Function, Function)} and {@link #keyReduction(Function, Function)} methods are unaffected.
* Defaults to the cache's configured {@link StateTransferConfiguration#chunkSize()}.
* @param batchSize the size of the batch to use when retrieving remote entries
* @return a publisher that will perform publish methods with the given batch size
* @throws IllegalArgumentException if the provided value is 0 or less
*/
CachePublisher batchSize(int batchSize);
/**
* Configures the publisher to only publish keys or values that map to the given keys in the provided
* Set. Defaults to "all" keys, which can be done by invoking {@link #withAllKeys()}.
*
* Note that if this and {@link #withSegments(IntSet)} are both used, then a key is only returned if it is also maps to
* a provided segment.
* @param keys set of keys that should only be used
* @return a publisher that will filter published values based on the given keys
* @throws NullPointerException if the provided Set is null
*/
CachePublisher withKeys(Set extends K> keys);
/**
* Configures a publisher to publish all keys or values, overriding if {@link #withKeys(Set)} was invoked.
* @return a publisher that will return all keys or values.
*/
CachePublisher withAllKeys();
/**
* Configures the publisher to only publish keys or values that map to a given segment in the provided
* IntSet. The {@link org.infinispan.commons.util.IntSets} is recommended to be used. Defaults to "all" segments.
*
* Note that if this and {@link #withKeys(Set)} are both used, then a key is only returned if it is also maps to
* a provided segment.
* @param segments determines what entries should be evaluated by only using ones that map to the given segments
* @return a publisher that will filter published values based on the given segments
* @throws NullPointerException if the provided IntSet is null
*/
CachePublisher withSegments(IntSet segments);
/**
* Configures the publisher to publish value(s) irrespective of their mapped segment. Defaults to "all" segments.
* @return a publisher that will publish all items irrespective of its segment
*/
CachePublisher withAllSegments();
/**
* Allows the caller to configure what level of consistency is required when retrieving data. At most is the weakest
* guarantee which ensures that data in a segment will be read once in a stable topology, but if there is a concurrent
* topology update a given segment or a portion of its data may not be returned.
*
* The default data consistency is {@link #exactlyOnce()}.
*/
CachePublisher atMostOnce();
/**
* Allows the caller to configure what level of consistency is required when retrieving data. At least ensures
* that data in a segment will be read once in a stable topology, but if there is a concurrent
* topology update a given segment or a portion of its data may be returned multiple times.
*
* The default data consistency is {@link #exactlyOnce()}.
* @return a publisher that will provide at least once data semantics
*/
CachePublisher atLeastOnce();
/**
* Allows the caller to configure what level of consistency is required when retrieving data. Exactly once ensures
* the highest level of guarantee so that even under a topology all data is returned once.
*
* Exactly once is the default data consistency level.
* @return a publisher that will provide exactly once data semantics
*/
CachePublisher exactlyOnce();
/**
* Same as {@link #entryReduction(Function, Function)} except that the source publisher provided to the transformer
* is made up of keys only.
* @param return value type
* @return CompletionStage that contains the resulting value when complete
* @throws NullPointerException if either the transformer or finalizer is null
*/
CompletionStage keyReduction(Function super Publisher, ? extends CompletionStage> transformer,
Function super Publisher, ? extends CompletionStage> finalizer);
/**
* Same as {@link #keyReduction(Function, Function)} except that the Functions must also implement Serializable
.
*
* The compiler will pick this overload for lambda parameters, making them Serializable
.
* @param return value type
* @return CompletionStage that contains the resulting value when complete
* @throws NullPointerException if either the transformer or finalizer is null
*/
CompletionStage keyReduction(SerializableFunction super Publisher, ? extends CompletionStage> transformer,
SerializableFunction super Publisher, ? extends CompletionStage> finalizer);
/**
* Performs the given transformer and finalizer on data in the cache, resulting in a single value.
* Depending on the deliveryGuarantee the transformer may be invoked 1..numSegments times. It
* could be that the transformer is invoked for every segment and produces a result. All of these results
* are then fed into the finalizer to produce a final result. If publisher is parallel the finalizer
* will be invoked on each node to ensure there is only a single result per node.
*
* If the provided transformer internally uses a reduction with a default value, that value must be its identity value.
* This is the same as can be seen at {@link java.util.stream.Stream#reduce(Object, BinaryOperator)}.
* Then as long as the finalizer can handle the identity value it will be properly reduced.
* @param transformer reduces the given publisher of data eventually into a single value.
* @param finalizer reduces all the single values produced by the transformer or this finalizer into one final value.
* @return CompletionStage that contains the resulting value when complete
* @param return value type
* @throws NullPointerException if either the transformer or finalizer is null
*/
CompletionStage entryReduction(Function super Publisher>, ? extends CompletionStage> transformer,
Function super Publisher, ? extends CompletionStage> finalizer);
/**
* Same as {@link #entryReduction(Function, Function)} except that the Functions must also implement Serializable
.
*
* The compiler will pick this overload for lambda parameters, making them Serializable
.
* @param transformer reduces the given publisher of data eventually into a single value.
* @param finalizer reduces all the single values produced by the transformer or this finalizer into one final value.
* @return CompletionStage that contains the resulting value when complete
* @param return value type
* @throws NullPointerException if either the transformer or finalizer is null
*/
CompletionStage entryReduction(SerializableFunction super Publisher>, ? extends CompletionStage> transformer,
SerializableFunction super Publisher, ? extends CompletionStage> finalizer);
/**
* Same as {@link #entryPublisher(Function)} except that the source publisher provided to the transformer is
* made up of keys only.
* @param return value type
* @return Publisher that when subscribed to will return the results and notify of segment completion if necessary
* @throws NullPointerException if either the transformer is null
*/
SegmentPublisherSupplier keyPublisher(Function super Publisher, ? extends Publisher> transformer);
/**
* Same as {@link #keyPublisher(Function)} except that the Function must also implement Serializable
.
*
* The compiler will pick this overload for lambda parameters, making them Serializable
.
* @param return value type
* @return Publisher that when subscribed to will return the results and notify of segment completion if necessary
* @throws NullPointerException if either the transformer is null
*/
SegmentPublisherSupplier keyPublisher(SerializableFunction super Publisher, ? extends Publisher> transformer);
/**
* Performs the given transformer on data in the cache, resulting in multiple values. If a single
* value is desired, the user should use {@link #entryReduction(Function, Function)}
* instead as it can optimize some things. Depending on the deliveryGuarantee the transformer may be
* invoked 1..numSegments times per node. Results from a given node will retrieve values up to
* {@code batchSize} values until some are consumed.
*
* For example when using RxJava and using an intermediate operation such as
* {@link io.reactivex.rxjava3.core.Flowable#switchIfEmpty(Publisher)} this can add elements if the given Publisher
* is empty, and it is very possible that a segment may not have entries and therefore may add the elements the
* switched Publisher returns multiple times.
*
* Methods that add elements to the returned Publisher are fine as long as they are tied to a specific entry, for
* example {@link io.reactivex.rxjava3.core.Flowable#flatMap(io.reactivex.rxjava3.functions.Function)} which can reproduce
* the same elements when provided the same input entry from the cache.
*
* @param transformer transform the given stream of data into something else (requires non null)
* @return Publisher that when subscribed to will return the results and notify of segment completion if necessary
* @param return value type
* @throws NullPointerException if either the transformer is null
*/
SegmentPublisherSupplier entryPublisher(Function super Publisher>, ? extends Publisher> transformer);
/**
* Same as {@link #entryPublisher(Function)} except that the Function must also implement Serializable
.
*
* The compiler will pick this overload for lambda parameters, making them Serializable
.
* @param transformer transform the given stream of data into something else (requires non null)
* @return Publisher that when subscribed to will return the results and notify of segment completion if necessary
* @param return value type
* @throws NullPointerException if either the transformer is null
*/
SegmentPublisherSupplier entryPublisher(SerializableFunction super Publisher>, ? extends Publisher> transformer);
}