io.reactivex.flowable.internal.operators.FlowableSubscribeOn Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rxjava3-flowable Show documentation
Show all versions of rxjava3-flowable Show documentation
rxjava3-flowable developed by David Karnok
The newest version!
/**
* Copyright (c) 2016-present, RxJava Contributors.
*
* 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
*
* http://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 io.reactivex.flowable.internal.operators;
import java.util.concurrent.atomic.*;
import org.reactivestreams.*;
import hu.akarnokd.reactivestreams.extensions.RelaxedSubscriber;
import io.reactivex.common.Scheduler;
import io.reactivex.flowable.Flowable;
import io.reactivex.flowable.internal.subscriptions.SubscriptionHelper;
import io.reactivex.flowable.internal.utils.BackpressureHelper;
/**
* Subscribes to the source Flowable on the specified Scheduler and makes
* sure downstream requests are scheduled there as well.
*
* @param the value type emitted
*/
public final class FlowableSubscribeOn extends AbstractFlowableWithUpstream {
final Scheduler scheduler;
final boolean nonScheduledRequests;
public FlowableSubscribeOn(Flowable source, Scheduler scheduler, boolean nonScheduledRequests) {
super(source);
this.scheduler = scheduler;
this.nonScheduledRequests = nonScheduledRequests;
}
@Override
public void subscribeActual(final Subscriber super T> s) {
Scheduler.Worker w = scheduler.createWorker();
final SubscribeOnSubscriber sos = new SubscribeOnSubscriber(s, w, source, nonScheduledRequests);
s.onSubscribe(sos);
w.schedule(sos);
}
static final class SubscribeOnSubscriber extends AtomicReference
implements RelaxedSubscriber, Subscription, Runnable {
private static final long serialVersionUID = 8094547886072529208L;
final Subscriber super T> actual;
final Scheduler.Worker worker;
final AtomicReference s;
final AtomicLong requested;
final boolean nonScheduledRequests;
Publisher source;
SubscribeOnSubscriber(Subscriber super T> actual, Scheduler.Worker worker, Publisher source, boolean nonScheduledRequests) {
this.actual = actual;
this.worker = worker;
this.source = source;
this.s = new AtomicReference();
this.requested = new AtomicLong();
this.nonScheduledRequests = nonScheduledRequests;
}
@Override
public void run() {
lazySet(Thread.currentThread());
Publisher src = source;
source = null;
src.subscribe(this);
}
@Override
public void onSubscribe(Subscription s) {
if (SubscriptionHelper.setOnce(this.s, s)) {
long r = requested.getAndSet(0L);
if (r != 0L) {
requestUpstream(r, s);
}
}
}
@Override
public void onNext(T t) {
actual.onNext(t);
}
@Override
public void onError(Throwable t) {
actual.onError(t);
worker.dispose();
}
@Override
public void onComplete() {
actual.onComplete();
worker.dispose();
}
@Override
public void request(final long n) {
if (SubscriptionHelper.validate(n)) {
Subscription s = this.s.get();
if (s != null) {
requestUpstream(n, s);
} else {
BackpressureHelper.add(requested, n);
s = this.s.get();
if (s != null) {
long r = requested.getAndSet(0L);
if (r != 0L) {
requestUpstream(r, s);
}
}
}
}
}
void requestUpstream(final long n, final Subscription s) {
if (nonScheduledRequests || Thread.currentThread() == get()) {
s.request(n);
} else {
worker.schedule(new Request(s, n));
}
}
@Override
public void cancel() {
SubscriptionHelper.cancel(s);
worker.dispose();
}
static final class Request implements Runnable {
private final Subscription s;
private final long n;
Request(Subscription s, long n) {
this.s = s;
this.n = n;
}
@Override
public void run() {
s.request(n);
}
}
}
}