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

io.reactivex.mantis.remote.observable.ServeObservable 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 java.util.Map;

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 rx.Observable;
import rx.Subscription;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func1;


public class ServeObservable extends ServeConfig {

    private Encoder encoder;
    private Observable observable;
    private boolean subscriptionPerConnection;
    private boolean isHotStream;

    public ServeObservable(Builder builder) {
        super(builder.name, builder.slottingStrategy,
                builder.filterFunction, builder.maxWriteAttempts);
        this.encoder = builder.encoder;
        this.subscriptionPerConnection = builder.subscriptionPerConnection;
        this.isHotStream = builder.isHotStream;
        this.observable = builder.observable;
        if (!builder.subscriptionPerConnection) {
            applySlottingSideEffectToObservable(builder.observable);
        }
    }

    public boolean isSubscriptionPerConnection() {
        return subscriptionPerConnection;
    }

    public Observable getObservable() {
        return observable;
    }

    public boolean isHotStream() {
        return isHotStream;
    }

    private void applySlottingSideEffectToObservable(Observable o) {
        final Observable withSideEffects =
                o
                        .doOnNext(new Action1() {
                            @Override
                            public void call(T t) {
                                slottingStrategy.writeOnSlot(null, t); // null key
                            }
                        })
                        .doOnTerminate(new Action0() {
                            @Override
                            public void call() {
                                slottingStrategy.completeAllConnections();
                            }
                        });

        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 {

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

        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(Observable observable) {
            this.observable = observable;
            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 ServeObservable build() {
            return new ServeObservable(this);
        }

        public Builder subscriptionPerConnection() {
            subscriptionPerConnection = true;
            return this;
        }

        public Builder hotStream() {
            isHotStream = true;
            return this;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy