Search in sources :

Example 1 with ProgramControllerServiceAdapter

use of io.cdap.cdap.internal.app.runtime.ProgramControllerServiceAdapter 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 2 with ProgramControllerServiceAdapter

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

the class AbstractProgramRuntimeServiceTest method testConcurrentStartLimit.

@Test
public void testConcurrentStartLimit() throws Exception {
    Semaphore proceed = new Semaphore(0);
    Set<String> threadNames = ConcurrentHashMap.newKeySet();
    // Creates a runner factory that block start until a signal is received
    ProgramRunnerFactory runnerFactory = programType -> (program, options) -> {
        threadNames.add(Thread.currentThread().getName());
        proceed.acquireUninterruptibly();
        ProgramId programId = program.getId();
        Service service = new FastService();
        ProgramController controller = new ProgramControllerServiceAdapter(service, programId.run(RunIds.generate()));
        service.start();
        return controller;
    };
    Program program = createDummyProgram();
    ProgramDescriptor descriptor = new ProgramDescriptor(program.getId(), null, NamespaceId.DEFAULT.artifact("test", "1.0"));
    CConfiguration cConf = CConfiguration.create();
    cConf.setInt(Constants.AppFabric.PROGRAM_LAUNCH_THREADS, 2);
    ProgramRuntimeService runtimeService = new TestProgramRuntimeService(cConf, runnerFactory, program, null, null);
    runtimeService.startAndWait();
    try {
        List<ProgramController> controllers = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            controllers.add(runtimeService.run(descriptor, new SimpleProgramOptions(program.getId()), RunIds.generate()).getController());
        }
        // There should be 2 program start threads running only
        Tasks.waitFor(2, proceed::getQueueLength, 2, TimeUnit.SECONDS);
        try {
            // Shouldn't never have more than 2
            Tasks.waitFor(true, () -> proceed.getQueueLength() > 2, 2, TimeUnit.SECONDS);
            Assert.fail("Shouldn't have more than 2 program starting");
        } catch (TimeoutException e) {
        // expected
        }
        // Let all start to proceed. They should have all finished pretty quickly
        proceed.release(5);
        Tasks.waitFor(true, () -> controllers.stream().map(ProgramController::getState).allMatch(ProgramController.State.COMPLETED::equals), 5, TimeUnit.SECONDS);
        Assert.assertEquals(2, threadNames.size());
    } finally {
        runtimeService.stopAndWait();
    }
}
Also used : AbstractExecutionThreadService(com.google.common.util.concurrent.AbstractExecutionThreadService) Arrays(java.util.Arrays) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) ArtifactClasses(io.cdap.cdap.api.artifact.ArtifactClasses) TimeoutException(java.util.concurrent.TimeoutException) ProgramControllerServiceAdapter(io.cdap.cdap.internal.app.runtime.ProgramControllerServiceAdapter) ArtifactMeta(io.cdap.cdap.internal.app.runtime.artifact.ArtifactMeta) SimpleProgramOptions(io.cdap.cdap.internal.app.runtime.SimpleProgramOptions) Map(java.util.Map) RunId(org.apache.twill.api.RunId) ClassRule(org.junit.ClassRule) Tasks(io.cdap.cdap.common.utils.Tasks) ArtifactDescriptor(io.cdap.cdap.internal.app.runtime.artifact.ArtifactDescriptor) ApplicationSpecification(io.cdap.cdap.api.app.ApplicationSpecification) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) List(java.util.List) Constants(io.cdap.cdap.common.conf.Constants) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) ArtifactScope(io.cdap.cdap.api.artifact.ArtifactScope) Location(org.apache.twill.filesystem.Location) Program(io.cdap.cdap.app.program.Program) HashMap(java.util.HashMap) ProgramType(io.cdap.cdap.proto.ProgramType) ArrayList(java.util.ArrayList) ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) AbstractIdleService(com.google.common.util.concurrent.AbstractIdleService) Locations(io.cdap.cdap.common.io.Locations) ArtifactId(io.cdap.cdap.proto.id.ArtifactId) ArtifactDetail(io.cdap.cdap.internal.app.runtime.artifact.ArtifactDetail) Nullable(javax.annotation.Nullable) ProgramLiveInfo(io.cdap.cdap.proto.ProgramLiveInfo) RunIds(io.cdap.cdap.common.app.RunIds) Semaphore(java.util.concurrent.Semaphore) ProgramId(io.cdap.cdap.proto.id.ProgramId) ProgramDescriptor(io.cdap.cdap.app.program.ProgramDescriptor) Test(org.junit.Test) IOException(java.io.IOException) File(java.io.File) Service(com.google.common.util.concurrent.Service) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) ArtifactNotFoundException(io.cdap.cdap.common.ArtifactNotFoundException) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) ArtifactVersion(io.cdap.cdap.api.artifact.ArtifactVersion) ArtifactRepository(io.cdap.cdap.internal.app.runtime.artifact.ArtifactRepository) Assert(org.junit.Assert) Collections(java.util.Collections) TemporaryFolder(org.junit.rules.TemporaryFolder) BasicArguments(io.cdap.cdap.internal.app.runtime.BasicArguments) Program(io.cdap.cdap.app.program.Program) ArrayList(java.util.ArrayList) AbstractExecutionThreadService(com.google.common.util.concurrent.AbstractExecutionThreadService) AbstractIdleService(com.google.common.util.concurrent.AbstractIdleService) Service(com.google.common.util.concurrent.Service) Semaphore(java.util.concurrent.Semaphore) ProgramId(io.cdap.cdap.proto.id.ProgramId) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) ProgramControllerServiceAdapter(io.cdap.cdap.internal.app.runtime.ProgramControllerServiceAdapter) ProgramDescriptor(io.cdap.cdap.app.program.ProgramDescriptor) SimpleProgramOptions(io.cdap.cdap.internal.app.runtime.SimpleProgramOptions) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.Test)

Aggregations

AbstractIdleService (com.google.common.util.concurrent.AbstractIdleService)2 Service (com.google.common.util.concurrent.Service)2 ProgramControllerServiceAdapter (io.cdap.cdap.internal.app.runtime.ProgramControllerServiceAdapter)2 ApplicationId (io.cdap.cdap.proto.id.ApplicationId)2 ProgramId (io.cdap.cdap.proto.id.ProgramId)2 Test (org.junit.Test)2 AbstractExecutionThreadService (com.google.common.util.concurrent.AbstractExecutionThreadService)1 ApplicationSpecification (io.cdap.cdap.api.app.ApplicationSpecification)1 ArtifactClasses (io.cdap.cdap.api.artifact.ArtifactClasses)1 ArtifactScope (io.cdap.cdap.api.artifact.ArtifactScope)1 ArtifactVersion (io.cdap.cdap.api.artifact.ArtifactVersion)1 Program (io.cdap.cdap.app.program.Program)1 ProgramDescriptor (io.cdap.cdap.app.program.ProgramDescriptor)1 ArtifactNotFoundException (io.cdap.cdap.common.ArtifactNotFoundException)1 RunIds (io.cdap.cdap.common.app.RunIds)1 CConfiguration (io.cdap.cdap.common.conf.CConfiguration)1 Constants (io.cdap.cdap.common.conf.Constants)1 Locations (io.cdap.cdap.common.io.Locations)1 Tasks (io.cdap.cdap.common.utils.Tasks)1 AbstractListener (io.cdap.cdap.internal.app.runtime.AbstractListener)1