reactor.core.publisher.SinksSpecs 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
package reactor.core.publisher;
import java.time.Duration;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import reactor.core.Disposable;
import reactor.core.publisher.Sinks.Empty;
import reactor.core.publisher.Sinks.Many;
import reactor.core.publisher.Sinks.One;
import reactor.core.scheduler.Scheduler;
final class SinksSpecs {
static final Sinks.RootSpec UNSAFE_ROOT_SPEC = new RootSpecImpl(false);
static final Sinks.RootSpec DEFAULT_ROOT_SPEC = new RootSpecImpl(true);
abstract static class AbstractSerializedSink {
volatile int wip;
static final AtomicIntegerFieldUpdater WIP =
AtomicIntegerFieldUpdater.newUpdater(AbstractSerializedSink.class, "wip");
volatile Thread lockedAt;
static final AtomicReferenceFieldUpdater LOCKED_AT =
AtomicReferenceFieldUpdater.newUpdater(AbstractSerializedSink.class, Thread.class, "lockedAt");
boolean tryAcquire(Thread currentThread) {
if (WIP.get(this) == 0 && WIP.compareAndSet(this, 0, 1)) {
// lazySet in thread A here is ok because:
// 1. initial state is `null`
// 2. `LOCKED_AT.get(this) != currentThread` from a different thread B could see outdated null or an outdated old thread
// 3. but that old thread cannot be B: since we're in thread B, it must have executed the compareAndSet which would have loaded the update from A
// 4. Seeing `null` or `C` is equivalent from seeing `A` from the perspective of the condition (`!= currentThread` is still true in all three cases)
LOCKED_AT.lazySet(this, currentThread);
}
else {
if (LOCKED_AT.get(this) != currentThread) {
return false;
}
WIP.incrementAndGet(this);
}
return true;
}
}
static final class RootSpecImpl implements Sinks.RootSpec,
Sinks.ManySpec,
Sinks.MulticastSpec,
Sinks.MulticastReplaySpec {
final boolean serialized;
final Sinks.UnicastSpec unicastSpec; //needed because UnicastSpec method names overlap with MulticastSpec
RootSpecImpl(boolean serialized) {
this.serialized = serialized;
//there will only be as many instances of UnicastSpecImpl as there are RootSpecImpl instances (2)
this.unicastSpec = new UnicastSpecImpl(serialized);
}
& ContextHolder> Empty wrapEmpty(EMPTY original) {
if (serialized) {
return new SinkEmptySerialized<>(original, original);
}
return original;
}
& ContextHolder> One wrapOne(ONE original) {
if (serialized) {
return new SinkOneSerialized<>(original, original);
}
return original;
}
& ContextHolder> Many wrapMany(MANY original) {
if (serialized) {
return new SinkManySerialized<>(original, original);
}
return original;
}
@Override
public Sinks.ManySpec many() {
return this;
}
@Override
public Empty empty() {
return wrapEmpty(new SinkEmptyMulticast<>());
}
@Override
public One one() {
final NextProcessor original = new NextProcessor<>(null);
return wrapOne(original);
}
@Override
public Sinks.UnicastSpec unicast() {
return this.unicastSpec;
}
@Override
public Sinks.MulticastSpec multicast() {
return this;
}
@Override
public Sinks.MulticastReplaySpec replay() {
return this;
}
@Override
public Many onBackpressureBuffer() {
@SuppressWarnings("deprecation") // EmitterProcessor will be removed in 3.5.
final EmitterProcessor original = EmitterProcessor.create();
return wrapMany(original);
}
@Override
public Many onBackpressureBuffer(int bufferSize) {
@SuppressWarnings("deprecation") // EmitterProcessor will be removed in 3.5.
final EmitterProcessor original = EmitterProcessor.create(bufferSize);
return wrapMany(original);
}
@Override
public Many onBackpressureBuffer(int bufferSize, boolean autoCancel) {
@SuppressWarnings("deprecation") // EmitterProcessor will be removed in 3.5.
final EmitterProcessor original = EmitterProcessor.create(bufferSize, autoCancel);
return wrapMany(original);
}
@Override
public Many directAllOrNothing() {
final SinkManyBestEffort original = SinkManyBestEffort.createAllOrNothing();
return wrapMany(original);
}
@Override
public Many directBestEffort() {
final SinkManyBestEffort original = SinkManyBestEffort.createBestEffort();
return wrapMany(original);
}
@Override
public Many all() {
@SuppressWarnings("deprecation") // ReplayProcessor will be removed in 3.5.
final ReplayProcessor original = ReplayProcessor.create();
return wrapMany(original);
}
@Override
public Many all(int batchSize) {
@SuppressWarnings("deprecation") // ReplayProcessor will be removed in 3.5
final ReplayProcessor original = ReplayProcessor.create(batchSize, true);
return wrapMany(original);
}
@Override
public Many latest() {
@SuppressWarnings("deprecation") // ReplayProcessor will be removed in 3.5.
final ReplayProcessor original = ReplayProcessor.cacheLast();
return wrapMany(original);
}
@Override
public Many latestOrDefault(T value) {
@SuppressWarnings("deprecation") // ReplayProcessor will be removed in 3.5.
final ReplayProcessor original = ReplayProcessor.cacheLastOrDefault(value);
return wrapMany(original);
}
@Override
public Many limit(int historySize) {
@SuppressWarnings("deprecation") // ReplayProcessor will be removed in 3.5.
final ReplayProcessor original = ReplayProcessor.create(historySize);
return wrapMany(original);
}
@Override
public Many limit(Duration maxAge) {
@SuppressWarnings("deprecation") // ReplayProcessor will be removed in 3.5.
final ReplayProcessor original = ReplayProcessor.createTimeout(maxAge);
return wrapMany(original);
}
@Override
public Many limit(Duration maxAge, Scheduler scheduler) {
@SuppressWarnings("deprecation") // ReplayProcessor will be removed in 3.5.
final ReplayProcessor original = ReplayProcessor.createTimeout(maxAge, scheduler);
return wrapMany(original);
}
@Override
public Many limit(int historySize, Duration maxAge) {
@SuppressWarnings("deprecation") // ReplayProcessor will be removed in 3.5.
final ReplayProcessor original = ReplayProcessor.createSizeAndTimeout(historySize, maxAge);
return wrapMany(original);
}
@Override
public Many limit(int historySize, Duration maxAge, Scheduler scheduler) {
@SuppressWarnings("deprecation") // ReplayProcessor will be removed in 3.5.
final ReplayProcessor original = ReplayProcessor.createSizeAndTimeout(historySize, maxAge, scheduler);
return wrapMany(original);
}
}
static final class UnicastSpecImpl implements Sinks.UnicastSpec {
final boolean serialized;
UnicastSpecImpl(boolean serialized) {
this.serialized = serialized;
}
& ContextHolder> Many wrapMany(MANY original) {
if (serialized) {
return new SinkManySerialized<>(original, original);
}
return original;
}
@Override
public Many onBackpressureBuffer() {
@SuppressWarnings("deprecation") // UnicastProcessor will be removed in 3.5.
final UnicastProcessor original = UnicastProcessor.create();
return wrapMany(original);
}
@Override
public Many onBackpressureBuffer(Queue queue) {
@SuppressWarnings("deprecation") // UnicastProcessor will be removed in 3.5.
final UnicastProcessor original = UnicastProcessor.create(queue);
return wrapMany(original);
}
@Override
public Many onBackpressureBuffer(Queue queue, Disposable endCallback) {
@SuppressWarnings("deprecation") // UnicastProcessor will be removed in 3.5.
final UnicastProcessor original = UnicastProcessor.create(queue, endCallback);
return wrapMany(original);
}
@Override
public Many onBackpressureError() {
final UnicastManySinkNoBackpressure original = UnicastManySinkNoBackpressure.create();
return wrapMany(original);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy