All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hu.akarnokd.rxjava2.operators.FlowableFlatMapAsync Maven / Gradle / Ivy

There is a newer version: 0.20.10
Show newest version
/*
 * Copyright 2016-2018 David Karnok
 *
 * 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 hu.akarnokd.rxjava2.operators;

import org.reactivestreams.*;

import hu.akarnokd.rxjava2.operators.FlowableFlatMapSync.*;
import io.reactivex.*;
import io.reactivex.functions.Function;
import io.reactivex.internal.fuseable.SimpleQueue;
import io.reactivex.plugins.RxJavaPlugins;

/**
 * FlatMap a bounded number of inner, non-trivial flows (unbound not supported).
 *
 * @param  the input value type
 * @param  the result value type
 *
 * @since 0.16.0
 */
final class FlowableFlatMapAsync extends Flowable implements FlowableTransformer {

    final Publisher source;

    final Function> mapper;

    final int maxConcurrency;

    final int bufferSize;

    final boolean depthFirst;

    final Scheduler scheduler;

    FlowableFlatMapAsync(Publisher source, Function> mapper,
            int maxConcurrency, int bufferSize, boolean depthFirst, Scheduler scheduler) {
        this.source = source;
        this.mapper = mapper;
        this.maxConcurrency = maxConcurrency;
        this.bufferSize = bufferSize;
        this.depthFirst = depthFirst;
        this.scheduler = scheduler;
    }

    @Override
    protected void subscribeActual(Subscriber s) {
        source.subscribe(new FlatMapOuterSubscriber(s, mapper, maxConcurrency, bufferSize, depthFirst, scheduler.createWorker()));
    }

    @Override
    public Publisher apply(Flowable upstream) {
        return new FlowableFlatMapAsync(upstream, mapper, maxConcurrency, bufferSize, depthFirst, scheduler);
    }

    static final class FlatMapOuterSubscriber extends BaseFlatMapOuterSubscriber implements Runnable {
        private static final long serialVersionUID = -5109342841608286301L;

        final Scheduler.Worker worker;

        FlatMapOuterSubscriber(Subscriber actual,
                Function> mapper, int maxConcurrency, int bufferSize,
                boolean depthFirst, Scheduler.Worker worker) {
            super(actual, mapper, maxConcurrency, bufferSize, depthFirst);
            this.worker = worker;
        }

        @Override
        public void drain() {
            if (getAndIncrement() == 0) {
                worker.schedule(this);
            }
        }

        @Override
        public void run() {
            if (depthFirst) {
                depthFirst();
            } else {
                breadthFirst();
            }
        }

        @Override
        void cleanupAfter() {
            worker.dispose();
        }

        @Override
        public void innerNext(FlatMapInnerSubscriber inner, R item) {
            SimpleQueue q = inner.queue();
            q.offer(item);
            drain();
        }

        @Override
        public void innerError(FlatMapInnerSubscriber inner, Throwable ex) {
            remove(inner);
            if (error.addThrowable(ex)) {
                inner.done = true;
                done = true;
                upstream.cancel();
                cancelInners();
                drain();
            } else {
                RxJavaPlugins.onError(ex);
            }
        }

        @Override
        public void innerComplete(FlatMapInnerSubscriber inner) {
            inner.done = true;
            drain();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy