use of org.reactivestreams.Subscription in project reactor-core by reactor.
the class MonoProcessor method onError.
@Override
public final void onError(Throwable cause) {
Subscription s = subscription;
if ((source != null && s == null) || this.error != null) {
Operators.onErrorDroppedMulticast(cause);
return;
}
this.error = cause;
subscription = null;
source = null;
int state = this.state;
for (; ; ) {
if (state != STATE_READY && state != STATE_SUBSCRIBED && state != STATE_POST_SUBSCRIBED) {
Operators.onErrorDroppedMulticast(cause);
return;
}
if (STATE.compareAndSet(this, state, STATE_ERROR)) {
waitStrategy.signalAllWhenBlocking();
break;
}
state = this.state;
}
if (WIP.getAndIncrement(this) == 0) {
drainLoop();
}
}
use of org.reactivestreams.Subscription in project reactor-core by reactor.
the class MonoProcessor method drainLoop.
@SuppressWarnings("unchecked")
final void drainLoop() {
int missed = 1;
int state;
for (; ; ) {
state = this.state;
if (state > STATE_POST_SUBSCRIBED) {
Processor<O, O> p = PROCESSOR.getAndSet(this, NOOP_PROCESSOR);
if (p != NOOP_PROCESSOR && p != null) {
switch(state) {
case STATE_COMPLETE_NO_VALUE:
p.onComplete();
break;
case STATE_SUCCESS_VALUE:
p.onNext(value);
p.onComplete();
break;
case STATE_ERROR:
p.onError(error);
break;
}
return;
}
}
Subscription subscription = this.subscription;
if (subscription != null && state == STATE_CANCELLED) {
FluxProcessor<O, O> p = PROCESSOR.getAndSet(this, NOOP_PROCESSOR);
if (p != NOOP_PROCESSOR) {
this.subscription = null;
this.source = null;
subscription.cancel();
// we need p = null as a 3rd possible value to detect the case were we should null out the source/subscription
if (p != null) {
p.dispose();
}
return;
}
}
if (state == STATE_SUBSCRIBED && STATE.compareAndSet(this, STATE_SUBSCRIBED, STATE_POST_SUBSCRIBED)) {
Processor<O, O> p = PROCESSOR.get(this);
if (p != null && p != NOOP_PROCESSOR) {
p.onSubscribe(this);
}
}
missed = WIP.addAndGet(this, -missed);
if (missed == 0) {
break;
}
}
}
use of org.reactivestreams.Subscription in project reactor-core by reactor.
the class MonoProcessor method onNext.
@Override
public final void onNext(O value) {
Subscription s = subscription;
if (value != null && ((source != null && s == null) || this.value != null)) {
Operators.onNextDroppedMulticast(value);
return;
}
subscription = null;
final int finalState;
if (value != null) {
finalState = STATE_SUCCESS_VALUE;
this.value = value;
if (s != null && !(source instanceof Mono)) {
s.cancel();
}
} else {
// shouldn't happen
finalState = STATE_COMPLETE_NO_VALUE;
}
source = null;
int state = this.state;
for (; ; ) {
if (state != STATE_READY && state != STATE_SUBSCRIBED && state != STATE_POST_SUBSCRIBED) {
if (value != null) {
Operators.onNextDroppedMulticast(value);
}
return;
}
if (STATE.compareAndSet(this, state, finalState)) {
waitStrategy.signalAllWhenBlocking();
break;
}
state = this.state;
}
if (WIP.getAndIncrement(this) == 0) {
drainLoop();
}
}
use of org.reactivestreams.Subscription in project reactor-core by reactor.
the class FluxBufferBoundaryTest method scanOther.
@Test
public void scanOther() {
FluxBufferBoundary.BufferBoundaryMain<String, Integer, List<String>> main = new FluxBufferBoundary.BufferBoundaryMain<>(null, null, ArrayList::new);
FluxBufferBoundary.BufferBoundaryOther<Integer> test = new FluxBufferBoundary.BufferBoundaryOther<>(main);
Subscription parent = Operators.emptySubscription();
test.onSubscribe(parent);
// the request is not tracked when there is a parent
test.request(2);
assertThat(test.scan(Scannable.Attr.REQUESTED_FROM_DOWNSTREAM)).isEqualTo(0L);
assertThat(test.scan(Scannable.Attr.PARENT)).isSameAs(parent);
assertThat(test.scan(Scannable.Attr.ACTUAL)).isSameAs(main);
assertThat(test.scan(Scannable.Attr.CANCELLED)).isFalse();
test.cancel();
assertThat(test.scan(Scannable.Attr.CANCELLED)).isTrue();
}
use of org.reactivestreams.Subscription in project reactor-core by reactor.
the class FluxBufferPredicateTest method scanMain.
@Test
public void scanMain() {
CoreSubscriber<? super List> actual = new LambdaSubscriber<>(null, e -> {
}, null, sub -> sub.request(100));
List<String> initialBuffer = Arrays.asList("foo", "bar");
FluxBufferPredicate.BufferPredicateSubscriber<String, List<String>> test = new FluxBufferPredicate.BufferPredicateSubscriber<>(actual, initialBuffer, ArrayList::new, s -> s.length() < 5, FluxBufferPredicate.Mode.WHILE);
Subscription parent = Operators.emptySubscription();
test.onSubscribe(parent);
Assertions.assertThat(test.scan(Scannable.Attr.CAPACITY)).isEqualTo(2);
Assertions.assertThat(test.scan(Scannable.Attr.REQUESTED_FROM_DOWNSTREAM)).isEqualTo(100L);
Assertions.assertThat(test.scan(Scannable.Attr.PARENT)).isSameAs(parent);
Assertions.assertThat(test.scan(Scannable.Attr.ACTUAL)).isSameAs(actual);
Assertions.assertThat(test.scan(Scannable.Attr.CANCELLED)).isFalse();
Assertions.assertThat(test.scan(Scannable.Attr.TERMINATED)).isFalse();
test.onError(new IllegalStateException("boom"));
Assertions.assertThat(test.scan(Scannable.Attr.TERMINATED)).isTrue();
}
Aggregations