Search in sources :

Example 1 with AbstractListener

use of io.cdap.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class DistributedProgramRuntimeService method createRuntimeInfo.

@Override
protected RuntimeInfo createRuntimeInfo(final ProgramController controller, final ProgramId programId, final Runnable cleanUpTask) {
    SimpleRuntimeInfo runtimeInfo = new SimpleRuntimeInfo(controller, programId, cleanUpTask);
    // Add a listener that publishes KILLED status notification when the YARN application is killed in case that
    // the KILLED status notification is not published from the YARN application container, so we don't need to wait
    // for the run record corrector to mark the status as KILLED.
    // Also, the local staging files can be deleted when the twill program is alive.
    controller.addListener(new AbstractListener() {

        ProgramController actualController = controller;

        @Override
        public void init(ProgramController.State currentState, @Nullable Throwable cause) {
            while (actualController instanceof Delegator) {
                // noinspection unchecked
                actualController = ((Delegator<ProgramController>) actualController).getDelegate();
            }
            if (actualController instanceof AbstractTwillProgramController) {
                runtimeInfo.setTwillRunId(((AbstractTwillProgramController) actualController).getTwillRunId());
            }
            if (currentState == ProgramController.State.ALIVE) {
                alive();
            } else if (currentState == ProgramController.State.KILLED) {
                killed();
            }
        }

        @Override
        public void alive() {
            cleanUpTask.run();
        }

        @Override
        public void killed() {
            programStateWriter.killed(programId.run(controller.getRunId()));
        }
    }, Threads.SAME_THREAD_EXECUTOR);
    return runtimeInfo;
}
Also used : ProgramController(io.cdap.cdap.app.runtime.ProgramController) Delegator(io.cdap.cdap.common.lang.Delegator) AbstractListener(io.cdap.cdap.internal.app.runtime.AbstractListener) SimpleRuntimeInfo(io.cdap.cdap.internal.app.runtime.service.SimpleRuntimeInfo)

Example 2 with AbstractListener

use of io.cdap.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class DefaultProgramWorkflowRunner method blockForCompletion.

/**
 * Adds a listener to the {@link ProgramController} and blocks for completion.
 *
 * @param closeable a {@link Closeable} to call when the program execution completed
 * @param controller the {@link ProgramController} for the program
 * @throws Exception if the execution failed
 */
private void blockForCompletion(final Closeable closeable, final ProgramController controller) throws Exception {
    // Execute the program.
    final SettableFuture<Void> completion = SettableFuture.create();
    controller.addListener(new AbstractListener() {

        @Override
        public void init(ProgramController.State currentState, @Nullable Throwable cause) {
            switch(currentState) {
                case COMPLETED:
                    completed();
                    break;
                case KILLED:
                    killed();
                    break;
                case ERROR:
                    error(cause);
                    break;
            }
        }

        @Override
        public void completed() {
            Closeables.closeQuietly(closeable);
            Set<Operation> fieldLineageOperations = new HashSet<>();
            if (controller instanceof WorkflowDataProvider) {
                fieldLineageOperations.addAll(((WorkflowDataProvider) controller).getFieldLineageOperations());
            }
            nodeStates.put(nodeId, new WorkflowNodeState(nodeId, NodeStatus.COMPLETED, fieldLineageOperations, controller.getRunId().getId(), null));
            completion.set(null);
        }

        @Override
        public void killed() {
            Closeables.closeQuietly(closeable);
            nodeStates.put(nodeId, new WorkflowNodeState(nodeId, NodeStatus.KILLED, controller.getRunId().getId(), null));
            completion.set(null);
        }

        @Override
        public void error(Throwable cause) {
            Closeables.closeQuietly(closeable);
            nodeStates.put(nodeId, new WorkflowNodeState(nodeId, NodeStatus.FAILED, controller.getRunId().getId(), cause));
            completion.setException(cause);
        }
    }, Threads.SAME_THREAD_EXECUTOR);
    // Block for completion.
    try {
        completion.get();
    } catch (ExecutionException e) {
        Throwable cause = e.getCause();
        if (cause instanceof Exception) {
            throw (Exception) cause;
        }
        throw Throwables.propagate(cause);
    } catch (InterruptedException e) {
        try {
            Futures.getUnchecked(controller.stop());
        } catch (Throwable t) {
        // no-op
        }
        // reset the interrupt
        Thread.currentThread().interrupt();
    }
}
Also used : ProgramController(io.cdap.cdap.app.runtime.ProgramController) HashSet(java.util.HashSet) Set(java.util.Set) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) WorkflowNodeState(io.cdap.cdap.api.workflow.WorkflowNodeState) WorkflowDataProvider(io.cdap.cdap.app.runtime.WorkflowDataProvider) AbstractListener(io.cdap.cdap.internal.app.runtime.AbstractListener) ExecutionException(java.util.concurrent.ExecutionException)

Example 3 with AbstractListener

use of io.cdap.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class WorkerProgramRunnerTest method stopProgram.

private void stopProgram(ProgramController controller) throws Throwable {
    final AtomicReference<Throwable> errorCause = new AtomicReference<>();
    final CountDownLatch complete = new CountDownLatch(1);
    controller.addListener(new AbstractListener() {

        @Override
        public void error(Throwable cause) {
            complete.countDown();
            errorCause.set(cause);
        }

        @Override
        public void completed() {
            complete.countDown();
        }

        @Override
        public void killed() {
            complete.countDown();
        }
    }, Threads.SAME_THREAD_EXECUTOR);
    controller.stop();
    complete.await(30, TimeUnit.SECONDS);
    runningPrograms.remove(controller);
    Throwable t = errorCause.get();
    if (t != null) {
        throw t;
    }
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) AbstractListener(io.cdap.cdap.internal.app.runtime.AbstractListener) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 4 with AbstractListener

use of io.cdap.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class ProgramControllerTest method testInitState.

@Test
public void testInitState() throws ExecutionException, InterruptedException {
    // To test against race-condition, we start/stop service multiple times.
    // If there is race, there is a chance that this test will fail in some env.
    // Otherwise it should always pass
    ExecutorService executor = Executors.newCachedThreadPool();
    int serviceCount = 1000;
    final CountDownLatch latch = new CountDownLatch(serviceCount);
    ProgramId programId = new ApplicationId(NamespaceId.DEFAULT.getNamespace(), "test").service("test");
    for (int i = 0; i < serviceCount; i++) {
        // Creates a controller for a guava service do nothing in start/stop.
        // The short time in start creates a chance to have out-of-order init() and alive() call if there is a race.
        Service service = new TestService(0, 0);
        ProgramController controller = new ProgramControllerServiceAdapter(service, programId.run(RunIds.generate()));
        ListenableFuture<Service.State> startCompletion = service.start();
        controller.addListener(new AbstractListener() {

            private volatile boolean initCalled;

            @Override
            public void init(ProgramController.State currentState, @Nullable Throwable cause) {
                initCalled = true;
                if (currentState == ProgramController.State.ALIVE) {
                    latch.countDown();
                }
            }

            @Override
            public void alive() {
                if (initCalled) {
                    latch.countDown();
                } else {
                    LOG.error("init() not called before alive()");
                }
            }
        }, executor);
        startCompletion.get();
        service.stopAndWait();
    }
    Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
Also used : Service(com.google.common.util.concurrent.Service) AbstractIdleService(com.google.common.util.concurrent.AbstractIdleService) ExecutorService(java.util.concurrent.ExecutorService) CountDownLatch(java.util.concurrent.CountDownLatch) ProgramId(io.cdap.cdap.proto.id.ProgramId) ProgramControllerServiceAdapter(io.cdap.cdap.internal.app.runtime.ProgramControllerServiceAdapter) ExecutorService(java.util.concurrent.ExecutorService) AbstractListener(io.cdap.cdap.internal.app.runtime.AbstractListener) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) Test(org.junit.Test)

Example 5 with AbstractListener

use of io.cdap.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class MapReduceRunnerTestBase method waitForCompletion.

private boolean waitForCompletion(ProgramController controller) throws InterruptedException {
    final AtomicBoolean success = new AtomicBoolean(false);
    final CountDownLatch completion = new CountDownLatch(1);
    controller.addListener(new AbstractListener() {

        @Override
        public void completed() {
            success.set(true);
            completion.countDown();
        }

        @Override
        public void error(Throwable cause) {
            completion.countDown();
        }
    }, Threads.SAME_THREAD_EXECUTOR);
    // MR tests can run for long time.
    completion.await(10, TimeUnit.MINUTES);
    return success.get();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AbstractListener(io.cdap.cdap.internal.app.runtime.AbstractListener) CountDownLatch(java.util.concurrent.CountDownLatch)

Aggregations

AbstractListener (io.cdap.cdap.internal.app.runtime.AbstractListener)13 ProgramController (io.cdap.cdap.app.runtime.ProgramController)8 ProgramId (io.cdap.cdap.proto.id.ProgramId)5 IOException (java.io.IOException)5 BasicArguments (io.cdap.cdap.internal.app.runtime.BasicArguments)4 ExecutionException (java.util.concurrent.ExecutionException)4 Test (org.junit.Test)4 Injector (com.google.inject.Injector)3 ProgramDescriptor (io.cdap.cdap.app.program.ProgramDescriptor)3 SystemArguments (io.cdap.cdap.internal.app.runtime.SystemArguments)3 File (java.io.File)3 Supplier (com.google.common.base.Supplier)2 Throwables (com.google.common.base.Throwables)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 Iterators (com.google.common.collect.Iterators)2 SettableFuture (com.google.common.util.concurrent.SettableFuture)2 AppWithAnonymousWorkflow (io.cdap.cdap.AppWithAnonymousWorkflow)2 MissingMapReduceWorkflowApp (io.cdap.cdap.MissingMapReduceWorkflowApp)2 MissingSparkWorkflowApp (io.cdap.cdap.MissingSparkWorkflowApp)2 NonUniqueProgramsInWorkflowApp (io.cdap.cdap.NonUniqueProgramsInWorkflowApp)2