Search in sources :

Example 1 with MantisGroup

use of io.mantisrx.common.MantisGroup in project mantis by Netflix.

the class StageExecutors method executeMantisGroups.

@SuppressWarnings("unchecked")
private static <K, T, R> Observable<Observable<R>> executeMantisGroups(Observable<Observable<MantisGroup<K, T>>> go, final Computation computation, final Context context, final long groupTakeUntil) {
    logger.info("initializing {}", computation.getClass().getCanonicalName());
    computation.init(context);
    // from groups to observable
    final Func2<Context, Observable<MantisGroup<K, T>>, Observable<R>> c = (Func2<Context, Observable<MantisGroup<K, T>>, Observable<R>>) computation;
    return go.lift(new MonitorOperator<>("worker_stage_outer")).map((Func1<Observable<MantisGroup<K, T>>, Observable<R>>) group -> c.call(context, group.lift(new MonitorOperator<>("worker_stage_inner_input"))).lift(new MonitorOperator("worker_stage_inner_output")));
}
Also used : Context(io.mantisrx.runtime.Context) Index(io.mantisrx.runtime.source.Index) StageConfig(io.mantisrx.runtime.StageConfig) MantisRxSingleThreadScheduler(io.mantisrx.runtime.scheduler.MantisRxSingleThreadScheduler) MetricsRegistry(io.mantisrx.common.metrics.MetricsRegistry) LoggerFactory(org.slf4j.LoggerFactory) Action1(rx.functions.Action1) Observable(rx.Observable) Computation(io.mantisrx.runtime.computation.Computation) ServiceRegistry(io.mantisrx.server.core.ServiceRegistry) Func1(rx.functions.Func1) Func2(rx.functions.Func2) GroupToGroup(io.mantisrx.runtime.GroupToGroup) GroupedObservableUtils(io.reactivx.mantis.operators.GroupedObservableUtils) Schedulers(rx.schedulers.Schedulers) GroupToScalar(io.mantisrx.runtime.GroupToScalar) RxMetrics(io.reactivex.mantis.remote.observable.RxMetrics) KeyToScalar(io.mantisrx.runtime.KeyToScalar) Metrics(io.mantisrx.common.metrics.Metrics) Counter(io.mantisrx.common.metrics.Counter) Groups(io.mantisrx.runtime.Groups) Logger(org.slf4j.Logger) RxThreadFactory(rx.internal.util.RxThreadFactory) ScalarToKey(io.mantisrx.runtime.ScalarToKey) SourceHolder(io.mantisrx.runtime.SourceHolder) KeyToKey(io.mantisrx.runtime.KeyToKey) Context(io.mantisrx.runtime.Context) STAGE_CONCURRENCY(io.mantisrx.runtime.parameter.ParameterUtils.STAGE_CONCURRENCY) TimeUnit(java.util.concurrent.TimeUnit) GroupedObservable(rx.observables.GroupedObservable) ScalarToScalar(io.mantisrx.runtime.ScalarToScalar) Action0(rx.functions.Action0) ScalarToGroup(io.mantisrx.runtime.ScalarToGroup) SinkHolder(io.mantisrx.runtime.SinkHolder) MantisMarker(io.mantisrx.runtime.markers.MantisMarker) MantisGroup(io.mantisrx.common.MantisGroup) MonitorOperator(io.mantisrx.common.metrics.rx.MonitorOperator) MonitorOperator(io.mantisrx.common.metrics.rx.MonitorOperator) MantisGroup(io.mantisrx.common.MantisGroup) Observable(rx.Observable) GroupedObservable(rx.observables.GroupedObservable) Func2(rx.functions.Func2)

Example 2 with MantisGroup

use of io.mantisrx.common.MantisGroup in project mantis by Netflix.

the class StageExecutors method executeMantisGroupsInParallel.

/**
 * @param go
 * @param computation
 *
 * @return untyped to support multiple callers return types
 */
@SuppressWarnings("unchecked")
private static <K, T, R> Observable<Observable<R>> executeMantisGroupsInParallel(Observable<Observable<MantisGroup<K, T>>> go, Computation computation, final Context context, final boolean applyTimeoutToInners, final long timeout, final int concurrency) {
    logger.info("initializing {}", computation.getClass().getCanonicalName());
    computation.init(context);
    // from groups to observable
    final Func2<Context, Observable<MantisGroup<K, T>>, Observable<R>> c = (Func2<Context, Observable<MantisGroup<K, T>>, Observable<R>>) computation;
    if (concurrency == StageConfig.DEFAULT_STAGE_CONCURRENCY) {
        return go.lift(new MonitorOperator<>("worker_stage_outer")).map(observable -> c.call(context, observable.observeOn(Schedulers.computation()).lift(new MonitorOperator<>("worker_stage_inner_input"))).lift(new MonitorOperator<>("worker_stage_inner_output")));
    } else {
        final MantisRxSingleThreadScheduler[] mantisRxSingleThreadSchedulers = new MantisRxSingleThreadScheduler[concurrency];
        RxThreadFactory rxThreadFactory = new RxThreadFactory("MantisRxSingleThreadScheduler-");
        logger.info("creating {} Mantis threads", concurrency);
        for (int i = 0; i < concurrency; i++) {
            mantisRxSingleThreadSchedulers[i] = new MantisRxSingleThreadScheduler(rxThreadFactory);
        }
        return go.lift(new MonitorOperator<>("worker_stage_outer")).map(observable -> observable.groupBy(e -> Math.abs(e.getKeyValue().hashCode()) % concurrency).flatMap(gbo -> c.call(context, gbo.observeOn(mantisRxSingleThreadSchedulers[gbo.getKey().intValue()]).lift(new MonitorOperator<MantisGroup<K, T>>("worker_stage_inner_input"))).lift(new MonitorOperator<R>("worker_stage_inner_output"))));
    }
}
Also used : Context(io.mantisrx.runtime.Context) Index(io.mantisrx.runtime.source.Index) StageConfig(io.mantisrx.runtime.StageConfig) MantisRxSingleThreadScheduler(io.mantisrx.runtime.scheduler.MantisRxSingleThreadScheduler) MetricsRegistry(io.mantisrx.common.metrics.MetricsRegistry) LoggerFactory(org.slf4j.LoggerFactory) Action1(rx.functions.Action1) Observable(rx.Observable) Computation(io.mantisrx.runtime.computation.Computation) ServiceRegistry(io.mantisrx.server.core.ServiceRegistry) Func1(rx.functions.Func1) Func2(rx.functions.Func2) GroupToGroup(io.mantisrx.runtime.GroupToGroup) GroupedObservableUtils(io.reactivx.mantis.operators.GroupedObservableUtils) Schedulers(rx.schedulers.Schedulers) GroupToScalar(io.mantisrx.runtime.GroupToScalar) RxMetrics(io.reactivex.mantis.remote.observable.RxMetrics) KeyToScalar(io.mantisrx.runtime.KeyToScalar) Metrics(io.mantisrx.common.metrics.Metrics) Counter(io.mantisrx.common.metrics.Counter) Groups(io.mantisrx.runtime.Groups) Logger(org.slf4j.Logger) RxThreadFactory(rx.internal.util.RxThreadFactory) ScalarToKey(io.mantisrx.runtime.ScalarToKey) SourceHolder(io.mantisrx.runtime.SourceHolder) KeyToKey(io.mantisrx.runtime.KeyToKey) Context(io.mantisrx.runtime.Context) STAGE_CONCURRENCY(io.mantisrx.runtime.parameter.ParameterUtils.STAGE_CONCURRENCY) TimeUnit(java.util.concurrent.TimeUnit) GroupedObservable(rx.observables.GroupedObservable) ScalarToScalar(io.mantisrx.runtime.ScalarToScalar) Action0(rx.functions.Action0) ScalarToGroup(io.mantisrx.runtime.ScalarToGroup) SinkHolder(io.mantisrx.runtime.SinkHolder) MantisMarker(io.mantisrx.runtime.markers.MantisMarker) MantisGroup(io.mantisrx.common.MantisGroup) MonitorOperator(io.mantisrx.common.metrics.rx.MonitorOperator) MantisRxSingleThreadScheduler(io.mantisrx.runtime.scheduler.MantisRxSingleThreadScheduler) MantisGroup(io.mantisrx.common.MantisGroup) Observable(rx.Observable) GroupedObservable(rx.observables.GroupedObservable) MonitorOperator(io.mantisrx.common.metrics.rx.MonitorOperator) RxThreadFactory(rx.internal.util.RxThreadFactory) Func2(rx.functions.Func2)

Example 3 with MantisGroup

use of io.mantisrx.common.MantisGroup in project mantis by Netflix.

the class RemoteObservable method createTcpConnectionToGOServer.

private static <K, V> Observable<MantisGroup<K, V>> createTcpConnectionToGOServer(final ConnectToGroupedObservable<K, V> params, final RemoteUnsubscribe remoteUnsubscribe, final RxMetrics metrics, final Action0 connectionDisconnectCallback, Observable<Integer> closeTrigger, final SpscArrayQueue<MantisGroup<?, ?>> inputQueue) {
    final Decoder<K> keyDecoder = params.getKeyDecoder();
    final Decoder<V> valueDecoder = params.getValueDecoder();
    loadFastProperties();
    return RxNetty.createTcpClient(params.getHost(), params.getPort(), new PipelineConfiguratorComposite<RemoteRxEvent, List<RemoteRxEvent>>(new PipelineConfigurator<RemoteRxEvent, List<RemoteRxEvent>>() {

        @Override
        public void configureNewPipeline(ChannelPipeline pipeline) {
            if (enableNettyLogging) {
                // uncomment to enable debug logging
                pipeline.addFirst(new LoggingHandler(LogLevel.ERROR));
            }
            if (enableHeartBeating) {
                pipeline.addLast("idleStateHandler", new IdleStateHandler(10, 2, 0));
                pipeline.addLast("heartbeat", new HeartbeatHandler());
            }
            if (enableCompression) {
                pipeline.addLast("gzipInflater", new JdkZlibEncoder(ZlibWrapper.GZIP));
                pipeline.addLast("gzipDeflater", new JdkZlibDecoder(ZlibWrapper.GZIP));
            }
            // 4 bytes to encode length
            pipeline.addLast("frameEncoder", new LengthFieldPrepender(4));
            // max frame = half MB
            pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(maxFrameLength, 0, 4, 0, 4));
        }
    }, new BatchedRxEventPipelineConfigurator())).connect().flatMap(new Func1<ObservableConnection<RemoteRxEvent, List<RemoteRxEvent>>, Observable<RemoteRxEvent>>() {

        @Override
        public Observable<RemoteRxEvent> call(final ObservableConnection<RemoteRxEvent, List<RemoteRxEvent>> connection) {
            // send subscribe event to server
            connection.writeAndFlush(RemoteRxEvent.subscribed(params.getName(), params.getSubscribeParameters()));
            remoteUnsubscribe.setConnection(connection);
            return connection.getInput().lift(new DropOperator<RemoteRxEvent>("incoming_" + RemoteObservable.class.getCanonicalName() + "_createTcpConnectionToServerGroups"));
        }
    }).doOnCompleted(new Action0() {

        @Override
        public void call() {
            // connection completed
            logger.warn("Detected connection completed when trying to connect to host: " + params.getHost() + " port: " + params.getPort());
            connectionDisconnectCallback.call();
        }
    }).onErrorResumeNext(new Func1<Throwable, Observable<RemoteRxEvent>>() {

        @Override
        public Observable<RemoteRxEvent> call(Throwable t1) {
            logger.warn("Detected connection error when trying to connect to host: " + params.getHost() + " port: " + params.getPort(), t1);
            connectionDisconnectCallback.call();
            // complete if error occurs
            return Observable.empty();
        }
    }).takeUntil(closeTrigger).filter(new Func1<RemoteRxEvent, Boolean>() {

        @Override
        public Boolean call(RemoteRxEvent rxEvent) {
            return (rxEvent.getType() == RemoteRxEvent.Type.next);
        }
    }).map(new Func1<RemoteRxEvent, Notification<byte[]>>() {

        @Override
        public Notification<byte[]> call(RemoteRxEvent rxEvent) {
            metrics.incrementNextCount();
            return Notification.createOnNext(rxEvent.getData());
        }
    }).<byte[]>dematerialize().map(new Func1<byte[], MantisGroup<K, V>>() {

        @Override
        public MantisGroup<K, V> call(byte[] bytes) {
            ByteBuffer buff = ByteBuffer.wrap((byte[]) bytes);
            // ignore notification type in key selector
            buff.get();
            int keyLength = buff.getInt();
            byte[] key = new byte[keyLength];
            buff.get(key);
            K keyVal = keyDecoder.decode(key);
            V value = null;
            buff = ByteBuffer.wrap((byte[]) bytes);
            byte notificationType = buff.get();
            if (notificationType == 1) {
                // int keyLength = buff.getInt();
                int end = buff.limit();
                int dataLength = end - 4 - 1 - keyLength;
                byte[] valueBytes = new byte[dataLength];
                buff.position(4 + 1 + keyLength);
                buff.get(valueBytes, 0, dataLength);
                value = valueDecoder.decode(valueBytes);
            } else {
                throw new RuntimeException("Notification encoding not support: " + notificationType);
            }
            return new MantisGroup<K, V>(keyVal, value);
        }
    }).doOnEach(new Observer<MantisGroup<K, V>>() {

        @Override
        public void onCompleted() {
            logger.info("RemoteRxEvent, name: " + params.getName() + " onCompleted()");
        }

        @Override
        public void onError(Throwable e) {
            logger.error("RemoteRxEvent, name: " + params.getName() + " onError()", e);
        }

        @Override
        public void onNext(MantisGroup<K, V> group) {
            if (logger.isDebugEnabled()) {
                logger.debug("RemoteRxEvent, name: " + params.getName() + " new key: " + group.getKeyValue());
            }
        }
    });
}
Also used : LoggingHandler(io.netty.handler.logging.LoggingHandler) DropOperator(io.reactivx.mantis.operators.DropOperator) LengthFieldPrepender(io.netty.handler.codec.LengthFieldPrepender) List(java.util.List) JdkZlibEncoder(io.netty.handler.codec.compression.JdkZlibEncoder) Func1(rx.functions.Func1) LengthFieldBasedFrameDecoder(io.netty.handler.codec.LengthFieldBasedFrameDecoder) Action0(rx.functions.Action0) ObservableConnection(mantis.io.reactivex.netty.channel.ObservableConnection) MantisGroup(io.mantisrx.common.MantisGroup) ByteBuffer(java.nio.ByteBuffer) ChannelPipeline(io.netty.channel.ChannelPipeline) Observable(rx.Observable) GroupedObservable(rx.observables.GroupedObservable) PipelineConfigurator(mantis.io.reactivex.netty.pipeline.PipelineConfigurator) JdkZlibDecoder(io.netty.handler.codec.compression.JdkZlibDecoder) IdleStateHandler(io.netty.handler.timeout.IdleStateHandler)

Example 4 with MantisGroup

use of io.mantisrx.common.MantisGroup in project mantis by Netflix.

the class StageExecutors method executeIntermediate.

@SuppressWarnings({ "rawtypes", "unchecked" })
public static <T, R> void executeIntermediate(WorkerConsumer consumer, final StageConfig<T, R> stage, WorkerPublisher publisher, final Context context) {
    if (consumer == null) {
        throw new IllegalArgumentException("consumer cannot be null");
    }
    if (stage == null) {
        throw new IllegalArgumentException("stage cannot be null");
    }
    if (publisher == null) {
        throw new IllegalArgumentException("producer cannot be null");
    }
    Observable<?> toSink = null;
    if (stage instanceof ScalarToScalar) {
        ScalarToScalar scalarStage = (ScalarToScalar) stage;
        Observable<Observable<T>> source = consumer.start(scalarStage);
        toSink = setupScalarToScalarStage(scalarStage, source, context);
    } else if (stage instanceof ScalarToKey) {
        ScalarToKey scalarStage = (ScalarToKey) stage;
        Observable<Observable<T>> source = consumer.start(scalarStage);
        toSink = setupScalarToKeyStage(scalarStage, source, context);
    } else // NJ
    if (stage instanceof ScalarToGroup) {
        ScalarToGroup scalarStage = (ScalarToGroup) stage;
        Observable<Observable<T>> source = consumer.start(scalarStage);
        toSink = setupScalarToGroupStage(scalarStage, source, context);
    } else if (stage instanceof KeyToKey) {
        KeyToKey keyToKey = (KeyToKey) stage;
        Observable<Observable<GroupedObservable<String, T>>> source = consumer.start(keyToKey);
        toSink = setupKeyToKeyStage(keyToKey, source, context);
    } else if (stage instanceof GroupToGroup) {
        GroupToGroup groupToGroup = (GroupToGroup) stage;
        Observable<Observable<MantisGroup<String, T>>> source = consumer.start(groupToGroup);
        toSink = setupGroupToGroupStage(groupToGroup, source, context);
    } else if (stage instanceof KeyToScalar) {
        KeyToScalar scalarToKey = (KeyToScalar) stage;
        Observable<Observable<MantisGroup<String, T>>> source = consumer.start(scalarToKey);
        toSink = setupKeyToScalarStage(scalarToKey, source, context);
    } else if (stage instanceof GroupToScalar) {
        GroupToScalar groupToScalar = (GroupToScalar) stage;
        Observable<Observable<MantisGroup<String, T>>> source = consumer.start(groupToScalar);
        toSink = setupGroupToScalarStage(groupToScalar, source, context);
    }
    publisher.start(stage, toSink);
}
Also used : ScalarToGroup(io.mantisrx.runtime.ScalarToGroup) ScalarToKey(io.mantisrx.runtime.ScalarToKey) MantisGroup(io.mantisrx.common.MantisGroup) KeyToScalar(io.mantisrx.runtime.KeyToScalar) Observable(rx.Observable) GroupedObservable(rx.observables.GroupedObservable) GroupToScalar(io.mantisrx.runtime.GroupToScalar) ScalarToScalar(io.mantisrx.runtime.ScalarToScalar) GroupToGroup(io.mantisrx.runtime.GroupToGroup) KeyToKey(io.mantisrx.runtime.KeyToKey) GroupedObservable(rx.observables.GroupedObservable)

Example 5 with MantisGroup

use of io.mantisrx.common.MantisGroup in project mantis by Netflix.

the class ObservableTrigger method mantisGroupTrigger.

private static <K, V> PushTrigger<KeyValuePair<K, V>> mantisGroupTrigger(final String name, final Observable<MantisGroup<K, V>> o, final Action0 doOnComplete, final Action1<Throwable> doOnError, final long groupExpirySeconds, final Func1<K, byte[]> keyEncoder, final HashFunction hashFunction) {
    final AtomicReference<Subscription> subRef = new AtomicReference<>();
    final Gauge subscriptionActive;
    Metrics metrics = new Metrics.Builder().name("ObservableTrigger_" + name).addGauge("subscriptionActive").build();
    subscriptionActive = metrics.getGauge("subscriptionActive");
    Action1<MonitoredQueue<KeyValuePair<K, V>>> doOnStart = new Action1<MonitoredQueue<KeyValuePair<K, V>>>() {

        @Override
        public void call(final MonitoredQueue<KeyValuePair<K, V>> queue) {
            subRef.set(o.doOnSubscribe(() -> {
                logger.info("Subscription is ACTIVE for observable trigger with name: " + name);
                subscriptionActive.set(1);
            }).doOnUnsubscribe(() -> {
                logger.info("Subscription is INACTIVE for observable trigger with name: " + name);
                subscriptionActive.set(0);
            }).map((MantisGroup<K, V> data) -> {
                final byte[] keyBytes = keyEncoder.call(data.getKeyValue());
                final long keyBytesHashed = hashFunction.computeHash(keyBytes);
                return (new KeyValuePair<K, V>(keyBytesHashed, keyBytes, data.getValue()));
            }).subscribe((KeyValuePair<K, V> data) -> {
                queue.write(data);
            }, (Throwable e) -> {
                logger.warn("Observable used to push data errored, on server with name: " + name, e);
                if (doOnError != null) {
                    doOnError.call(e);
                }
            }, () -> {
                logger.info("Observable used to push data completed, on server with name: " + name);
                if (doOnComplete != null) {
                    doOnComplete.call();
                }
            }));
        }
    };
    Action1<MonitoredQueue<KeyValuePair<K, V>>> doOnStop = new Action1<MonitoredQueue<KeyValuePair<K, V>>>() {

        @Override
        public void call(MonitoredQueue<KeyValuePair<K, V>> t1) {
            if (subRef.get() != null) {
                logger.warn("Connections from next stage has dropped to 0. Do not propagate unsubscribe");
            // subRef.get().unsubscribe();
            }
        }
    };
    return new PushTrigger<>(doOnStart, doOnStop, metrics);
}
Also used : Action1(rx.functions.Action1) AtomicReference(java.util.concurrent.atomic.AtomicReference) MantisGroup(io.mantisrx.common.MantisGroup) Gauge(io.mantisrx.common.metrics.Gauge) Metrics(io.mantisrx.common.metrics.Metrics) Subscription(rx.Subscription)

Aggregations

MantisGroup (io.mantisrx.common.MantisGroup)5 Observable (rx.Observable)4 GroupedObservable (rx.observables.GroupedObservable)4 Metrics (io.mantisrx.common.metrics.Metrics)3 GroupToGroup (io.mantisrx.runtime.GroupToGroup)3 GroupToScalar (io.mantisrx.runtime.GroupToScalar)3 KeyToKey (io.mantisrx.runtime.KeyToKey)3 KeyToScalar (io.mantisrx.runtime.KeyToScalar)3 ScalarToGroup (io.mantisrx.runtime.ScalarToGroup)3 ScalarToKey (io.mantisrx.runtime.ScalarToKey)3 ScalarToScalar (io.mantisrx.runtime.ScalarToScalar)3 Action0 (rx.functions.Action0)3 Action1 (rx.functions.Action1)3 Func1 (rx.functions.Func1)3 Counter (io.mantisrx.common.metrics.Counter)2 MetricsRegistry (io.mantisrx.common.metrics.MetricsRegistry)2 MonitorOperator (io.mantisrx.common.metrics.rx.MonitorOperator)2 Context (io.mantisrx.runtime.Context)2 Groups (io.mantisrx.runtime.Groups)2 SinkHolder (io.mantisrx.runtime.SinkHolder)2