Search in sources :

Example 6 with Endpoint

use of io.mantisrx.common.network.Endpoint in project mantis by Netflix.

the class StageExecutorsGroupByTest method testExecuteIntermediatStage.

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testExecuteIntermediatStage() throws InterruptedException {
    // Note, this test has a timing issue, client starts
    // sending data before server is ready, resulting
    // in a RST (connection reset by peer)
    TestGroupByJob provider = new TestGroupByJob();
    Job<Pair> job = provider.getJobInstance();
    List<StageConfig<?, ?>> stages = job.getStages();
    PortSelectorWithinRange portSelector = new PortSelectorWithinRange(8000, 9000);
    final int publishPort = portSelector.acquirePort();
    final int consumerPort = portSelector.acquirePort();
    Observable<Observable<GroupedObservable<String, Integer>>> go = Observable.just(Observable.range(0, 10).groupBy(new Func1<Integer, String>() {

        @Override
        public String call(Integer t1) {
            if ((t1 % 2) == 0) {
                return "even";
            } else {
                return "odd";
            }
        }
    }));
    // mimic previous stage with a server
    ServeGroupedObservable<String, Integer> config = new ServeGroupedObservable.Builder<String, Integer>().keyEncoder(Codecs.string()).valueEncoder(Codecs.integer()).observable(go).build();
    RemoteRxServer server = new RemoteRxServer.Builder().addObservable(config).port(consumerPort).build();
    server.start();
    EndpointInjector staticEndpoints = new EndpointInjector() {

        @Override
        public Observable<EndpointChange> deltas() {
            return Observable.create(new OnSubscribe<EndpointChange>() {

                @Override
                public void call(Subscriber<? super EndpointChange> subscriber) {
                    subscriber.onNext(new EndpointChange(EndpointChange.Type.add, new Endpoint("localhost", consumerPort, "0")));
                    subscriber.onNext(new EndpointChange(EndpointChange.Type.add, new Endpoint("localhost", consumerPort, "1")));
                    subscriber.onCompleted();
                }
            });
        }
    };
    WorkerConsumer consumer = new WorkerConsumerRemoteObservable(null, staticEndpoints);
    WorkerPublisher producer = new WorkerPublisherRemoteObservable(publishPort, null, Observable.just(1), null);
    // execute source
    StageExecutors.executeIntermediate(consumer, stages.get(1), producer, new Context());
    ConnectToGroupedObservable<String, Integer> connectConfig = new ConnectToGroupedObservable.Builder<String, Integer>().host("localhost").port(publishPort).keyDecoder(Codecs.string()).valueDecoder(Codecs.integer()).build();
    Iterator<GroupedObservable<String, Integer>> iter = RemoteObservable.connect(connectConfig).getObservable().toBlocking().getIterator();
    // verify numbers are grouped by even/odd
    // even is first due to zero
    GroupedObservable<String, Integer> even = iter.next();
    Assert.assertEquals("even", even.getKey());
    Iterator<Integer> evenIter = even.toBlocking().getIterator();
    Assert.assertEquals(0, evenIter.next().intValue());
    Assert.assertEquals(4, evenIter.next().intValue());
    Assert.assertEquals(16, evenIter.next().intValue());
    Assert.assertEquals(36, evenIter.next().intValue());
    GroupedObservable<String, Integer> odd = iter.next();
    Assert.assertEquals("odd", odd.getKey());
    Iterator<Integer> oddIter = odd.toBlocking().getIterator();
    Assert.assertEquals(1, oddIter.next().intValue());
    Assert.assertEquals(9, oddIter.next().intValue());
    Assert.assertEquals(25, oddIter.next().intValue());
    Assert.assertEquals(49, oddIter.next().intValue());
    // should only have two groups
    Assert.assertEquals(false, iter.hasNext());
}
Also used : EndpointChange(io.reactivex.mantis.remote.observable.EndpointChange) PortSelectorWithinRange(io.reactivex.mantis.remote.observable.PortSelectorWithinRange) ConnectToGroupedObservable(io.reactivex.mantis.remote.observable.ConnectToGroupedObservable) Endpoint(io.mantisrx.common.network.Endpoint) Func1(rx.functions.Func1) Context(io.mantisrx.runtime.Context) RemoteRxServer(io.reactivex.mantis.remote.observable.RemoteRxServer) StageConfig(io.mantisrx.runtime.StageConfig) Endpoint(io.mantisrx.common.network.Endpoint) ConnectToGroupedObservable(io.reactivex.mantis.remote.observable.ConnectToGroupedObservable) ServeGroupedObservable(io.reactivex.mantis.remote.observable.ServeGroupedObservable) RemoteObservable(io.reactivex.mantis.remote.observable.RemoteObservable) Observable(rx.Observable) GroupedObservable(rx.observables.GroupedObservable) EndpointInjector(io.reactivex.mantis.remote.observable.EndpointInjector) ConnectToGroupedObservable(io.reactivex.mantis.remote.observable.ConnectToGroupedObservable) ServeGroupedObservable(io.reactivex.mantis.remote.observable.ServeGroupedObservable) GroupedObservable(rx.observables.GroupedObservable) Test(org.junit.Test)

Example 7 with Endpoint

use of io.mantisrx.common.network.Endpoint in project mantis by Netflix.

the class StageExecutorsTest method testExecuteIntermediatStage.

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testExecuteIntermediatStage() throws InterruptedException {
    TestJob provider = new TestJob();
    Job<Integer> job = provider.getJobInstance();
    List<StageConfig<?, ?>> stages = job.getStages();
    PortSelectorWithinRange portSelector = new PortSelectorWithinRange(8000, 9000);
    final int publishPort = portSelector.acquirePort();
    final int consumerPort = portSelector.acquirePort();
    // mimic previous stage with a server
    RemoteRxServer server1 = RemoteObservable.serve(consumerPort, Observable.range(0, 10), Codecs.integer());
    server1.start();
    EndpointInjector staticEndpoints = new EndpointInjector() {

        @Override
        public Observable<EndpointChange> deltas() {
            return Observable.create(new OnSubscribe<EndpointChange>() {

                @Override
                public void call(Subscriber<? super EndpointChange> subscriber) {
                    subscriber.onNext(new EndpointChange(EndpointChange.Type.add, new Endpoint("localhost", consumerPort, "1")));
                    subscriber.onCompleted();
                }
            });
        }
    };
    WorkerConsumer consumer = new WorkerConsumerRemoteObservable(null, staticEndpoints);
    WorkerPublisher producer = new WorkerPublisherRemoteObservable(publishPort, null, Observable.just(1), null);
    // execute intermediate, flatten results
    StageExecutors.executeIntermediate(consumer, stages.get(1), producer, new Context());
    Iterator<Integer> iter = RemoteObservable.connect(new ConnectToObservable.Builder<Integer>().host("localhost").slotId("0").port(publishPort).decoder(Codecs.integer()).build()).getObservable().toBlocking().getIterator();
    // verify numbers are even
    Assert.assertEquals(0, iter.next().intValue());
    Assert.assertEquals(2, iter.next().intValue());
    Assert.assertEquals(4, iter.next().intValue());
}
Also used : Context(io.mantisrx.runtime.Context) EndpointChange(io.reactivex.mantis.remote.observable.EndpointChange) PortSelectorWithinRange(io.reactivex.mantis.remote.observable.PortSelectorWithinRange) RemoteRxServer(io.reactivex.mantis.remote.observable.RemoteRxServer) StageConfig(io.mantisrx.runtime.StageConfig) Endpoint(io.mantisrx.common.network.Endpoint) ConnectToObservable(io.reactivex.mantis.remote.observable.ConnectToObservable) Endpoint(io.mantisrx.common.network.Endpoint) EndpointInjector(io.reactivex.mantis.remote.observable.EndpointInjector) Test(org.junit.Test)

Example 8 with Endpoint

use of io.mantisrx.common.network.Endpoint in project mantis by Netflix.

the class StageExecutorsTest method testExecuteSink.

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testExecuteSink() throws InterruptedException {
    TestJob provider = new TestJob();
    Job<Integer> job = provider.getJobInstance();
    List<StageConfig<?, ?>> stages = job.getStages();
    PortSelectorWithinRange portSelector = new PortSelectorWithinRange(8000, 9000);
    final int consumerPort = portSelector.acquirePort();
    // mimic previous stage with a server
    RemoteRxServer server1 = RemoteObservable.serve(consumerPort, Observable.range(0, 10), Codecs.integer());
    server1.start();
    EndpointInjector staticEndpoints = new EndpointInjector() {

        @Override
        public Observable<EndpointChange> deltas() {
            return Observable.create(new OnSubscribe<EndpointChange>() {

                @Override
                public void call(Subscriber<? super EndpointChange> subscriber) {
                    subscriber.onNext(new EndpointChange(EndpointChange.Type.add, new Endpoint("localhost", consumerPort, "1")));
                    subscriber.onCompleted();
                }
            });
        }
    };
    Action0 noOpAction = new Action0() {

        @Override
        public void call() {
        }
    };
    Action1<Throwable> noOpError = new Action1<Throwable>() {

        @Override
        public void call(Throwable t) {
        }
    };
    WorkerConsumer consumer = new WorkerConsumerRemoteObservable(null, staticEndpoints);
    // execute source
    StageExecutors.executeSink(consumer, stages.get(1), job.getSink(), new TestPortSelector(), new RxMetrics(), new Context(), noOpAction, null, null, noOpAction, noOpError);
    Iterator<Integer> iter = provider.getItemsWritten().iterator();
    // verify numbers are even
    Assert.assertEquals(0, iter.next().intValue());
    Assert.assertEquals(2, iter.next().intValue());
    Assert.assertEquals(4, iter.next().intValue());
}
Also used : Context(io.mantisrx.runtime.Context) Action0(rx.functions.Action0) Action1(rx.functions.Action1) EndpointChange(io.reactivex.mantis.remote.observable.EndpointChange) PortSelectorWithinRange(io.reactivex.mantis.remote.observable.PortSelectorWithinRange) RemoteRxServer(io.reactivex.mantis.remote.observable.RemoteRxServer) StageConfig(io.mantisrx.runtime.StageConfig) Endpoint(io.mantisrx.common.network.Endpoint) Endpoint(io.mantisrx.common.network.Endpoint) RxMetrics(io.reactivex.mantis.remote.observable.RxMetrics) EndpointInjector(io.reactivex.mantis.remote.observable.EndpointInjector) Test(org.junit.Test)

Example 9 with Endpoint

use of io.mantisrx.common.network.Endpoint in project mantis by Netflix.

the class DynamicConnectionSet method observables.

public Observable<Observable<T>> observables() {
    return endpointInjector.deltas().doOnCompleted(() -> logger.info("onComplete on injector deltas")).doOnError(t -> logger.error("caught unexpected error {}", t.getMessage(), t)).doOnSubscribe(new Action0() {

        @Override
        public void call() {
            logger.info("Subscribing, clearing active connection set");
            resetActiveConnections();
        }
    }).groupBy(new Func1<EndpointChange, String>() {

        @Override
        public String call(EndpointChange t1) {
            return Endpoint.uniqueHost(t1.getEndpoint().getHost(), t1.getEndpoint().getPort(), t1.getEndpoint().getSlotId());
        }
    }).flatMap(new Func1<GroupedObservable<String, EndpointChange>, Observable<Observable<T>>>() {

        @Override
        public Observable<Observable<T>> call(final GroupedObservable<String, EndpointChange> group) {
            final PublishSubject<Integer> closeConnectionTrigger = PublishSubject.create();
            return group.doOnNext(new Action1<EndpointChange>() {

                @Override
                public void call(EndpointChange change) {
                    // side effect to force complete
                    if (EndpointChange.Type.complete == change.getType() && activeConnectionsContains(group.getKey(), change.getEndpoint())) {
                        logger.info("Received complete request, removing connection from active set, " + change.getEndpoint().getHost() + " port: " + change.getEndpoint().getPort() + " id: " + change.getEndpoint().getSlotId());
                        forceCompletedConnections.increment();
                        removeConnection(group.getKey(), change.getEndpoint());
                        closeConnectionTrigger.onNext(1);
                    }
                }
            }).filter(new Func1<EndpointChange, Boolean>() {

                @Override
                public Boolean call(EndpointChange change) {
                    // active connection check is to ensure
                    // latent adds are not allowed.  This can
                    // occur if dynamicConnection set
                    // and reconciliator are chained together.
                    // Reconciliator will "see" changes
                    // before dynamic connection set add will
                    // assume connection is missing from set
                    boolean contains = activeConnectionsContains(group.getKey(), change.getEndpoint());
                    if (contains) {
                        logger.info("Skipping latent add for endpoint, already in active set: " + change);
                    }
                    return EndpointChange.Type.add == change.getType() && !contains;
                }
            }).map(new Func1<EndpointChange, Observable<T>>() {

                @Override
                public Observable<T> call(final EndpointChange toAdd) {
                    logger.info("Received add request, adding connection to active set, " + toAdd.getEndpoint().getHost() + " port: " + toAdd.getEndpoint().getPort() + ", with client id: " + toAdd.getEndpoint().getSlotId());
                    addConnection(group.getKey(), toAdd.getEndpoint());
                    Action0 disconnectCallback = new Action0() {

                        @Override
                        public void call() {
                            int timeToWait = random.nextInt((maxTimeoutOnUnexpectedTerminateSec - minTimeoutOnUnexpectedTerminateSec) + 1) + minTimeoutOnUnexpectedTerminateSec;
                            logger.info("Connection disconnected, waiting " + timeToWait + " seconds before removing from active set of connections: " + toAdd);
                            Observable.timer(timeToWait, TimeUnit.SECONDS).doOnCompleted(new Action0() {

                                @Override
                                public void call() {
                                    logger.warn("Removing connection from active set, " + toAdd);
                                    closedConnections.increment();
                                    removeConnection(group.getKey(), toAdd.getEndpoint());
                                }
                            }).subscribe();
                        }
                    };
                    RemoteRxConnection<T> connection = toObservableFunc.call(toAdd.getEndpoint(), disconnectCallback, closeConnectionTrigger);
                    return connection.getObservable().doOnCompleted(toAdd.getEndpoint().getCompletedCallback()).doOnError(toAdd.getEndpoint().getErrorCallback());
                }
            });
        }
    });
}
Also used : SpscArrayQueue(org.jctools.queues.SpscArrayQueue) Logger(org.slf4j.Logger) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Endpoint(io.mantisrx.common.network.Endpoint) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) HashMap(java.util.HashMap) Random(java.util.Random) ConnectionSet(io.reactivex.mantis.remote.observable.reconciliator.ConnectionSet) Observer(rx.Observer) Action1(rx.functions.Action1) Observable(rx.Observable) HashSet(java.util.HashSet) TimeUnit(java.util.concurrent.TimeUnit) Lock(java.util.concurrent.locks.Lock) Func1(rx.functions.Func1) GroupedObservable(rx.observables.GroupedObservable) Action0(rx.functions.Action0) Func3(rx.functions.Func3) Gauge(io.mantisrx.common.metrics.Gauge) Map(java.util.Map) MantisGroup(io.mantisrx.common.MantisGroup) Metrics(io.mantisrx.common.metrics.Metrics) PublishSubject(rx.subjects.PublishSubject) Action0(rx.functions.Action0) Action1(rx.functions.Action1) Observable(rx.Observable) GroupedObservable(rx.observables.GroupedObservable) Endpoint(io.mantisrx.common.network.Endpoint) PublishSubject(rx.subjects.PublishSubject) Func1(rx.functions.Func1) GroupedObservable(rx.observables.GroupedObservable)

Example 10 with Endpoint

use of io.mantisrx.common.network.Endpoint in project mantis by Netflix.

the class Reconciliator method startReconciliation.

private void startReconciliation() {
    if (startedReconciliation.compareAndSet(false, true)) {
        logger.info("Starting reconciliation for name: " + name);
        running.increment();
        subscription = Observable.combineLatest(currentExpectedSet, connectionSet.activeConnections(), new Func2<Set<Endpoint>, Set<Endpoint>, Void>() {

            @Override
            public Void call(Set<Endpoint> expected, Set<Endpoint> actual) {
                reconciliationCheck.increment();
                boolean check = expected.equals(actual);
                logger.debug("Check result: " + check + ", size expected: " + expected.size() + " actual: " + actual.size() + ", for values expected: " + expected + " versus actual: " + actual);
                if (!check) {
                    // reconcile adds
                    Set<Endpoint> expectedDiff = new HashSet<Endpoint>(expected);
                    expectedDiff.removeAll(actual);
                    if (expectedDiff.size() > 0) {
                        for (Endpoint endpoint : expectedDiff) {
                            logger.info("Connection missing from expected set, adding missing connection: " + endpoint);
                            reconciledChanges.onNext(new EndpointChange(Type.add, endpoint));
                        }
                    }
                    // reconile removes
                    Set<Endpoint> actualDiff = new HashSet<Endpoint>(actual);
                    actualDiff.removeAll(expected);
                    if (actualDiff.size() > 0) {
                        for (Endpoint endpoint : actualDiff) {
                            logger.info("Unexpected connection in active set, removing connection: " + endpoint);
                            reconciledChanges.onNext(new EndpointChange(Type.complete, endpoint));
                        }
                    }
                }
                return null;
            }
        }).onErrorResumeNext(new Func1<Throwable, Observable<? extends Void>>() {

            @Override
            public Observable<? extends Void> call(Throwable throwable) {
                logger.error("caught error in Reconciliation for {}", name, throwable);
                return Observable.empty();
            }
        }).doOnCompleted(new Action0() {

            @Override
            public void call() {
                logger.error("onComplete in Reconciliation observable chain for {}", name);
                stopReconciliation();
            }
        }).subscribe();
    } else {
        logger.info("reconciliation already started for {}", name);
    }
}
Also used : Action0(rx.functions.Action0) Set(java.util.Set) HashSet(java.util.HashSet) DynamicConnectionSet(io.reactivex.mantis.remote.observable.DynamicConnectionSet) Endpoint(io.mantisrx.common.network.Endpoint) EndpointChange(io.reactivex.mantis.remote.observable.EndpointChange) Func1(rx.functions.Func1)

Aggregations

Endpoint (io.mantisrx.common.network.Endpoint)27 Test (org.junit.Test)16 Action0 (rx.functions.Action0)8 EndpointChange (io.reactivex.mantis.remote.observable.EndpointChange)7 ArrayList (java.util.ArrayList)6 HashSet (java.util.HashSet)6 LinkedList (java.util.LinkedList)6 List (java.util.List)6 Map (java.util.Map)6 Observable (rx.Observable)6 Set (java.util.Set)5 Action1 (rx.functions.Action1)5 Func1 (rx.functions.Func1)5 Context (io.mantisrx.runtime.Context)4 StageConfig (io.mantisrx.runtime.StageConfig)4 EndpointInjector (io.reactivex.mantis.remote.observable.EndpointInjector)4 RemoteRxServer (io.reactivex.mantis.remote.observable.RemoteRxServer)4 HashMap (java.util.HashMap)4 Logger (org.slf4j.Logger)4 LoggerFactory (org.slf4j.LoggerFactory)4