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

io.reactivex.mantis.remote.observable.ServeNestedObservable Maven / Gradle / Ivy

There is a newer version: 3.1.4
Show newest version
/*
 * Copyright 2019 Netflix, Inc.
 *
 * 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.mantis.remote.observable;

import io.mantisrx.common.codec.Encoder;
import io.reactivex.mantis.remote.observable.filter.ServerSideFilters;
import io.reactivex.mantis.remote.observable.slotting.RoundRobin;
import io.reactivex.mantis.remote.observable.slotting.SlottingStrategy;
import java.util.Map;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.functions.Action0;
import rx.functions.Func1;


public class ServeNestedObservable extends ServeConfig {

    private Encoder encoder;

    public ServeNestedObservable(Builder builder) {
        super(builder.name, builder.slottingStrategy, builder.filterFunction,
                builder.maxWriteAttempts);
        this.encoder = builder.encoder;
        applySlottingSideEffectToObservable(builder.observable);
    }

    private void applySlottingSideEffectToObservable(Observable> o) {

        final Observable withSideEffects =
                Observable.merge(o)
                        .doOnEach(new Observer() {
                            @Override
                            public void onCompleted() {
                                slottingStrategy.completeAllConnections();
                            }

                            @Override
                            public void onError(Throwable e) {
                                slottingStrategy.errorAllConnections(e);
                            }

                            @Override
                            public void onNext(T value) {
                                slottingStrategy.writeOnSlot(null, value);
                            }
                        });

        final MutableReference subscriptionRef = new MutableReference<>();
        slottingStrategy.registerDoAfterFirstConnectionAdded(new Action0() {
            @Override
            public void call() {
                subscriptionRef.setValue(withSideEffects.subscribe());
            }
        });

        slottingStrategy.registerDoAfterLastConnectionRemoved(new Action0() {
            @Override
            public void call() {
                subscriptionRef.getValue().unsubscribe();
            }
        });
    }

    public Encoder getEncoder() {
        return encoder;
    }

    public static class Builder {

        private String name;
        private Observable> observable;
        private SlottingStrategy slottingStrategy = new RoundRobin<>();
        private Encoder encoder;
        private Func1, Func1> filterFunction = ServerSideFilters.noFiltering();
        private int maxWriteAttempts = 3;

        public Builder name(String name) {
            if (name != null && name.length() > 127) {
                throw new IllegalArgumentException("Observable name must be less than 127 characters");
            }
            this.name = name;
            return this;
        }

        public Builder observable(Observable> observable) {
            this.observable = observable;
            return this;
        }

        public Builder maxWriteAttempts(int maxWriteAttempts) {
            this.maxWriteAttempts = maxWriteAttempts;
            return this;
        }


        public Builder slottingStrategy(SlottingStrategy slottingStrategy) {
            this.slottingStrategy = slottingStrategy;
            return this;
        }

        public Builder encoder(Encoder encoder) {
            this.encoder = encoder;
            return this;
        }

        public Builder serverSideFilter(
                Func1, Func1> filterFunc) {
            this.filterFunction = filterFunc;
            return this;
        }

        public ServeNestedObservable build() {
            return new ServeNestedObservable(this);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy