Search in sources :

Example 46 with Context

use of io.mantisrx.runtime.Context in project mantis by Netflix.

the class HttpSourceImplTest method testRemovedServerWillBeUnsubscribed.

@Test
public void testRemovedServerWillBeUnsubscribed() throws Exception {
    HttpSourceImpl<ByteBuf, ServerSentEvent, ServerContext<ServerSentEvent>> source = createStreamingSource("test/infStream");
    final AtomicInteger counter = new AtomicInteger();
    final CountDownLatch done = new CountDownLatch(1);
    final ConcurrentHashMap<String, AtomicInteger> result = new ConcurrentHashMap<>();
    final ConcurrentMap<ServerInfo, CountDownLatch> serverRemovalLatch = new ConcurrentHashMap<>();
    for (Server server : localServerProvider.getServers()) {
        serverRemovalLatch.put(toServerInfo(server), new CountDownLatch(1));
    }
    Observable.merge(source.call(new Context(), new Index(1, 1))).doOnNext(new Action1<ServerContext<ServerSentEvent>>() {

        @Override
        public void call(ServerContext<ServerSentEvent> pair) {
            try {
                assertTrue(pair.getValue().contentAsString().contains("line"));
                counter.incrementAndGet();
                String msg = pair.getValue().contentAsString();
                result.putIfAbsent(msg, new AtomicInteger());
                result.get(msg).incrementAndGet();
            } finally {
                serverRemovalLatch.get(pair.getServer()).countDown();
            }
        }
    }).doOnError(new Action1<Throwable>() {

        @Override
        public void call(Throwable throwable) {
            fail("Unexpected failure: " + throwable);
        }
    }).doAfterTerminate(new Action0() {

        @Override
        public void call() {
            done.countDown();
        }
    }).subscribe();
    for (Server server : localServerProvider.getServers()) {
        serverRemovalLatch.get(toServerInfo(server)).await();
        localServerProvider.removeServer(toServerInfo(server));
    }
    long waitSeconds = 5;
    boolean timedout = !done.await(waitSeconds, TimeUnit.SECONDS);
    if (timedout) {
        fail(String.format("Waited at least %d seconds for the test to finish. Connection to at least one server is not unsubscribed.", waitSeconds));
    }
    assertTrue(String.format("Each server should emit at least one event before being canceled. Expected counter >= %d, actual counter: %d", localServerProvider.serverSize(), counter.get()), counter.get() >= localServerProvider.serverSize());
    for (Server server : localServerProvider.getServers()) {
        ServerInfo serverInfo = toServerInfo(server);
        assertEquals("There should be one completion per server", 1, sourceObserver.getCount(serverInfo, EventType.SOURCE_COMPLETED));
        assertEquals("There should be one un-subscription per server", 1, sourceObserver.getCount(serverInfo, EventType.CONNECTION_UNSUBSCRIBED));
        assertEquals("There should be no error", 0, sourceObserver.getCount(serverInfo, EventType.SUBSCRIPTION_FAILED));
        assertEquals("There should be one connection per server", 1, sourceObserver.getCount(serverInfo, EventType.SUBSCRIPTION_ESTABLISHED));
        assertEquals(String.format("There should be exactly one cancellation event per server for %d servers. ", localServerProvider.serverSize()), 1, sourceObserver.getCount(serverInfo, EventType.SUBSCRIPTION_CANCELED));
    }
    assertEquals("The source should emit exactly one completion event", 1, sourceObserver.getCompletionCount());
    assertEquals("The server should not have any error event", 0, sourceObserver.getErrorCount());
    Set<EventType> events = sourceObserver.getEvents();
    assertEquals("Each server should have one occurrence per event type except server failure event", (EventType.values().length - 1), events.size());
    for (EventType event : events) {
        assertEquals("Each event should be recorded exactly once", localServerProvider.serverSize(), sourceObserver.getEventCount(event));
    }
}
Also used : Context(io.mantisrx.runtime.Context) Action0(rx.functions.Action0) Action1(rx.functions.Action1) Server(io.mantisrx.runtime.source.http.LocalServerProvider.Server) EventType(io.mantisrx.runtime.source.http.impl.HttpSourceImpl.HttpSourceEvent.EventType) ServerInfo(mantis.io.reactivex.netty.client.RxClient.ServerInfo) ServerSentEvent(mantis.io.reactivex.netty.protocol.http.sse.ServerSentEvent) Index(io.mantisrx.runtime.source.Index) ByteBuf(io.netty.buffer.ByteBuf) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Test(org.junit.Test)

Example 47 with Context

use of io.mantisrx.runtime.Context in project mantis by Netflix.

the class HttpSourceImplTest method testConnectionFailureShouldBeCaptured.

@Test
public void testConnectionFailureShouldBeCaptured() throws Exception {
    HttpClientFactory<ByteBuf, ByteBuf> factory = new HttpClientFactory<ByteBuf, ByteBuf>() {

        @Override
        public HttpClient<ByteBuf, ByteBuf> createClient(ServerInfo server) {
            HttpClientBuilder<ByteBuf, ByteBuf> clientBuilder = new HttpClientBuilder<>(server.getHost(), server.getPort());
            return clientBuilder.channelOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, 100).build();
        }
    };
    HttpSourceImpl<ByteBuf, ByteBuf, ServerContext<ByteBuf>> source = HttpSourceImpl.builder(factory, HttpRequestFactories.createGetFactory("/"), HttpSourceImpl.<ByteBuf>contextWrapper()).withActivityObserver(sourceObserver).withServerProvider(new HttpServerProvider() {

        @Override
        public Observable<ServerInfo> getServersToAdd() {
            return Observable.just(new ServerInfo("localhost", UNUSED_PORT));
        }

        @Override
        public Observable<ServerInfo> getServersToRemove() {
            return Observable.empty();
        }
    }).build();
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicReference<Throwable> ex = new AtomicReference<>();
    final AtomicReference<ServerContext<ByteBuf>> items = new AtomicReference<>();
    Observable.merge(source.call(new Context(), new Index(1, 1))).subscribe(new Subscriber<ServerContext<ByteBuf>>() {

        @Override
        public void onCompleted() {
            latch.countDown();
        }

        @Override
        public void onError(Throwable e) {
            ex.set(e);
            latch.countDown();
        }

        @Override
        public void onNext(ServerContext<ByteBuf> pair) {
            items.set(pair);
        }
    });
    if (!latch.await(5, TimeUnit.HOURS)) {
        fail("The test case should finish way sooner than 5 seconds. ");
    }
    Assert.assertNull("The connection error should be captured per server, therefore not propagated up to the entire source.", ex.get());
    Assert.assertNull("There should be no emitted item due to connection timeout", items.get());
}
Also used : Context(io.mantisrx.runtime.Context) ServerInfo(mantis.io.reactivex.netty.client.RxClient.ServerInfo) AtomicReference(java.util.concurrent.atomic.AtomicReference) Index(io.mantisrx.runtime.source.Index) HttpClientBuilder(mantis.io.reactivex.netty.protocol.http.client.HttpClientBuilder) ByteBuf(io.netty.buffer.ByteBuf) CountDownLatch(java.util.concurrent.CountDownLatch) HttpServerProvider(io.mantisrx.runtime.source.http.HttpServerProvider) HttpClientFactory(io.mantisrx.runtime.source.http.HttpClientFactory) Test(org.junit.Test)

Example 48 with Context

use of io.mantisrx.runtime.Context in project mantis by Netflix.

the class HttpSourceImplTest method testResumeOnTimeout.

@Test
public void testResumeOnTimeout() throws Exception {
    HttpClientFactory<ByteBuf, ByteBuf> factory = new HttpClientFactory<ByteBuf, ByteBuf>() {

        @Override
        public HttpClient<ByteBuf, ByteBuf> createClient(ServerInfo server) {
            ClientConfig clientConfig = new ClientConfig.Builder().readTimeout(10, TimeUnit.MILLISECONDS).build();
            return new HttpClientBuilder<ByteBuf, ByteBuf>(server.getHost(), server.getPort()).config(clientConfig).build();
        }
    };
    final ConcurrentMap<ServerInfo, AtomicInteger> resumptions = new ConcurrentHashMap<>();
    for (ServerInfo server : localServerProvider.getServerInfos()) {
        resumptions.put(server, new AtomicInteger());
    }
    final int maxRepeat = 5;
    HttpSourceImpl<ByteBuf, ByteBuf, ServerContext<ByteBuf>> source = HttpSourceImpl.builder(factory, HttpRequestFactories.createGetFactory("test/timeout?timeout=10000"), HttpSourceImpl.<ByteBuf>contextWrapper()).withActivityObserver(sourceObserver).resumeWith(new ClientResumePolicy<ByteBuf, ByteBuf>() {

        @Override
        public Observable<HttpClientResponse<ByteBuf>> onError(ServerClientContext<ByteBuf, ByteBuf> clientContext, int attempts, Throwable error) {
            if (attempts <= maxRepeat) {
                resumptions.get(clientContext.getServer()).incrementAndGet();
                return clientContext.newResponse();
            }
            return null;
        }

        @Override
        public Observable<HttpClientResponse<ByteBuf>> onCompleted(ServerClientContext<ByteBuf, ByteBuf> clientContext, int attempts) {
            return null;
        }
    }).withServerProvider(localServerProvider).build();
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicReference<Throwable> ex = new AtomicReference<>();
    final AtomicReference<ServerContext<ByteBuf>> items = new AtomicReference<>();
    Observable.merge(source.call(new Context(), new Index(1, 1))).subscribe(new Subscriber<ServerContext<ByteBuf>>() {

        @Override
        public void onCompleted() {
            latch.countDown();
        }

        @Override
        public void onError(Throwable e) {
            ex.set(e);
            latch.countDown();
        }

        @Override
        public void onNext(ServerContext<ByteBuf> pair) {
            items.set(pair);
        }
    });
    if (!latch.await(10, TimeUnit.SECONDS)) {
        fail("The test case should finish way sooner than 10 seconds. ");
    }
    Assert.assertNull("The timeout error should be captured by the client so it does not surface to the source", ex.get());
    Assert.assertNull("There should be no emitted item due to connection timeout", items.get());
    for (ServerInfo serverInfo : localServerProvider.getServerInfos()) {
        assertEquals("There should be no source level error", 0, sourceObserver.getErrorCount());
        assertEquals("There should be one connection attempt per server per retry", maxRepeat + 1, sourceObserver.getCount(serverInfo, EventType.CONNECTION_ATTEMPTED));
        assertEquals("There should be no established connection per server due to read timeout. ", 0, sourceObserver.getCount(serverInfo, EventType.CONNECTION_ESTABLISHED));
        assertEquals("There should no subscribed server because of read timeout", 0, sourceObserver.getCount(serverInfo, EventType.SUBSCRIPTION_ESTABLISHED));
        assertEquals("Each server will repeat exactly " + maxRepeat + " times", maxRepeat, resumptions.get(serverInfo).get());
    }
}
Also used : ServerInfo(mantis.io.reactivex.netty.client.RxClient.ServerInfo) HttpClientBuilder(mantis.io.reactivex.netty.protocol.http.client.HttpClientBuilder) Builder(io.mantisrx.runtime.source.http.impl.HttpSourceImpl.Builder) Index(io.mantisrx.runtime.source.Index) HttpClientBuilder(mantis.io.reactivex.netty.protocol.http.client.HttpClientBuilder) ByteBuf(io.netty.buffer.ByteBuf) ClientConfig(mantis.io.reactivex.netty.client.RxClient.ClientConfig) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HttpClientFactory(io.mantisrx.runtime.source.http.HttpClientFactory) Context(io.mantisrx.runtime.Context) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) Observable(rx.Observable) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Test(org.junit.Test)

Example 49 with Context

use of io.mantisrx.runtime.Context in project mantis by Netflix.

the class WorkerExecutionOperationsNetworkStage method convertJobSchedulingInfoToWorkerMap.

/**
 * Converts a JobSchedulingInfo object to a simple WorkerMap to be used from within the context.
 * Static for easier testing.
 *
 * @param jobName
 * @param jobId
 * @param durationType
 * @param js
 *
 * @return
 */
static WorkerMap convertJobSchedulingInfoToWorkerMap(String jobName, String jobId, MantisJobDurationType durationType, JobSchedulingInfo js) {
    Map<Integer, List<WorkerInfo>> stageToWorkerInfoMap = new HashMap<>();
    WorkerMap workerMap = new WorkerMap(stageToWorkerInfoMap);
    if (jobName == null || jobName.isEmpty() || jobId == null || jobId.isEmpty()) {
        logger.warn("Job name/jobId cannot be null in convertJobSchedulingInfoToWorkerMap");
        return workerMap;
    }
    if (js == null || js.getWorkerAssignments() == null) {
        logger.warn("JobSchedulingInfo or workerAssignments cannot be null in convertJobSchedulingInfoToWorkerMap");
        return workerMap;
    }
    try {
        Map<Integer, WorkerAssignments> workerAssignments = js.getWorkerAssignments();
        Iterator<Map.Entry<Integer, WorkerAssignments>> entryIterator = workerAssignments.entrySet().iterator();
        while (entryIterator.hasNext()) {
            Map.Entry<Integer, WorkerAssignments> next = entryIterator.next();
            int stageNo = next.getKey();
            WorkerAssignments workerAssignmentsForStage = next.getValue();
            Map<Integer, WorkerHost> hosts = workerAssignmentsForStage.getHosts();
            if (hosts != null) {
                List<WorkerInfo> workerInfoList = hosts.values().stream().map((workerHost) -> {
                    return generateWorkerInfo(jobName, jobId, stageNo, workerHost.getWorkerIndex(), workerHost.getWorkerNumber(), durationType, workerHost.getHost(), workerHost);
                }).collect(Collectors.toList());
                stageToWorkerInfoMap.put(stageNo, workerInfoList);
            }
        }
        workerMap = new WorkerMap(stageToWorkerInfoMap);
    } catch (Exception e) {
        logger.warn("Exception converting JobSchedulingInfo " + js + " to worker Map " + e.getMessage());
        return workerMap;
    }
    return workerMap;
}
Also used : Strings(io.mantisrx.shaded.com.google.common.base.Strings) Arrays(java.util.Arrays) MantisJobDurationType(io.mantisrx.runtime.MantisJobDurationType) MantisJobState(io.mantisrx.runtime.MantisJobState) LoggerFactory(org.slf4j.LoggerFactory) StageSchedulingInfo(io.mantisrx.runtime.descriptor.StageSchedulingInfo) JobMasterStageConfig(io.mantisrx.server.worker.jobmaster.JobMasterStageConfig) Lifecycle(io.mantisrx.runtime.lifecycle.Lifecycle) WorkerConsumer(io.mantisrx.runtime.executor.WorkerConsumer) ServiceRegistry(io.mantisrx.server.core.ServiceRegistry) JOB_MASTER_AUTOSCALE_METRIC_SYSTEM_PARAM(io.mantisrx.runtime.parameter.ParameterUtils.JOB_MASTER_AUTOSCALE_METRIC_SYSTEM_PARAM) WorkerPorts(io.mantisrx.common.WorkerPorts) ParameterUtils(io.mantisrx.runtime.parameter.ParameterUtils) Map(java.util.Map) Schedulers(rx.schedulers.Schedulers) VirtualMachineTaskStatus(io.mantisrx.server.worker.mesos.VirtualMachineTaskStatus) RxMetrics(io.reactivex.mantis.remote.observable.RxMetrics) Status(io.mantisrx.server.core.Status) StageExecutors(io.mantisrx.runtime.executor.StageExecutors) ScheduledThreadPoolExecutor(java.util.concurrent.ScheduledThreadPoolExecutor) WorkerAssignments(io.mantisrx.server.core.WorkerAssignments) Observer(rx.Observer) Collectors(java.util.stream.Collectors) JobMasterService(io.mantisrx.server.worker.jobmaster.JobMasterService) WorkerConsumerRemoteObservable(io.mantisrx.runtime.executor.WorkerConsumerRemoteObservable) CountDownLatch(java.util.concurrent.CountDownLatch) WorkerId(io.mantisrx.server.core.domain.WorkerId) List(java.util.List) ToDeltaEndpointInjector(io.reactivex.mantis.remote.observable.ToDeltaEndpointInjector) Action0(rx.functions.Action0) BehaviorSubject(rx.subjects.BehaviorSubject) Splitter(io.mantisrx.shaded.com.google.common.base.Splitter) Optional(java.util.Optional) WorkerMap(io.mantisrx.runtime.WorkerMap) PortSelector(io.mantisrx.runtime.executor.PortSelector) WorkerPublisherRemoteObservable(io.mantisrx.runtime.executor.WorkerPublisherRemoteObservable) StageConfig(io.mantisrx.runtime.StageConfig) MantisMasterClientApi(io.mantisrx.server.master.client.MantisMasterClientApi) MetricsRegistry(io.mantisrx.common.metrics.MetricsRegistry) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Parameters(io.mantisrx.runtime.parameter.Parameters) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) Observable(rx.Observable) Func1(rx.functions.Func1) WorkerMetricsClient(io.mantisrx.server.worker.client.WorkerMetricsClient) LinkedList(java.util.LinkedList) RemoteRxServer(io.reactivex.mantis.remote.observable.RemoteRxServer) AutoScaleMetricsConfig(io.mantisrx.server.worker.jobmaster.AutoScaleMetricsConfig) JobSchedulingInfo(io.mantisrx.server.core.JobSchedulingInfo) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) Endpoint(io.mantisrx.common.network.Endpoint) TYPE(io.mantisrx.server.core.Status.TYPE) Context(io.mantisrx.runtime.Context) StatusPayloads(io.mantisrx.server.core.StatusPayloads) TimeUnit(java.util.concurrent.TimeUnit) ServiceLocator(io.mantisrx.runtime.lifecycle.ServiceLocator) ExecuteStageRequest(io.mantisrx.server.core.ExecuteStageRequest) Registry(com.netflix.spectator.api.Registry) WorkerConfiguration(io.mantisrx.server.worker.config.WorkerConfiguration) SpectatorRegistryFactory(io.mantisrx.common.metrics.spectator.SpectatorRegistryFactory) WorkerInfo(io.mantisrx.runtime.WorkerInfo) WorkerHost(io.mantisrx.server.core.WorkerHost) WorkerHost(io.mantisrx.server.core.WorkerHost) HashMap(java.util.HashMap) WorkerInfo(io.mantisrx.runtime.WorkerInfo) Endpoint(io.mantisrx.common.network.Endpoint) WorkerAssignments(io.mantisrx.server.core.WorkerAssignments) List(java.util.List) LinkedList(java.util.LinkedList) WorkerMap(io.mantisrx.runtime.WorkerMap) Map(java.util.Map) WorkerMap(io.mantisrx.runtime.WorkerMap) HashMap(java.util.HashMap)

Aggregations

Context (io.mantisrx.runtime.Context)49 Test (org.junit.Test)34 CountDownLatch (java.util.concurrent.CountDownLatch)24 Index (io.mantisrx.runtime.source.Index)23 Observable (rx.Observable)23 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)20 Action1 (rx.functions.Action1)19 Action0 (rx.functions.Action0)17 Map (java.util.Map)16 Parameters (io.mantisrx.runtime.parameter.Parameters)15 Logger (org.slf4j.Logger)13 LoggerFactory (org.slf4j.LoggerFactory)13 ParameterTestUtils (io.mantisrx.connector.kafka.ParameterTestUtils)11 TimeUnit (java.util.concurrent.TimeUnit)11 StageConfig (io.mantisrx.runtime.StageConfig)10 HashMap (java.util.HashMap)10 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)10 Endpoint (io.mantisrx.common.network.Endpoint)9 WorkerInfo (io.mantisrx.runtime.WorkerInfo)9 ByteBuf (io.netty.buffer.ByteBuf)8