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
/*
* Copyright (c) 2020-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.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() {
return wrapOne(new SinkOneMulticast<>());
}
@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) {
if (historySize <= 0) {
throw new IllegalArgumentException("historySize must be > 0");
}
@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) {
if (historySize <= 0) {
throw new IllegalArgumentException("historySize must be > 0");
}
@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) {
if (historySize <= 0) {
throw new IllegalArgumentException("historySize must be > 0");
}
@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