use of co.cask.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, 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));
}
use of co.cask.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.
the class WorkflowTest method testWorkflow.
@Test(timeout = 120 * 1000L)
public void testWorkflow() throws Exception {
final ApplicationWithPrograms app = AppFabricTestHelper.deployApplicationWithManager(WorkflowApp.class, TEMP_FOLDER_SUPPLIER);
final Injector injector = AppFabricTestHelper.getInjector();
final ProgramDescriptor programDescriptor = Iterators.filter(app.getPrograms().iterator(), new Predicate<ProgramDescriptor>() {
@Override
public boolean apply(ProgramDescriptor input) {
return input.getProgramId().getType() == ProgramType.WORKFLOW;
}
}).next();
String inputPath = createInput();
String outputPath = new File(tmpFolder.newFolder(), "output").getAbsolutePath();
BasicArguments userArgs = new BasicArguments(ImmutableMap.of("inputPath", inputPath, "outputPath", outputPath));
final SettableFuture<String> completion = SettableFuture.create();
final ProgramController controller = AppFabricTestHelper.submit(app, programDescriptor.getSpecification().getClassName(), userArgs, TEMP_FOLDER_SUPPLIER);
controller.addListener(new AbstractListener() {
@Override
public void init(ProgramController.State currentState, @Nullable Throwable cause) {
LOG.info("Starting");
injector.getInstance(Store.class).setStart(controller.getProgramRunId().getParent(), controller.getProgramRunId().getRun(), System.currentTimeMillis());
}
@Override
public void completed() {
LOG.info("Completed");
completion.set("Completed");
}
@Override
public void error(Throwable cause) {
LOG.info("Error", cause);
completion.setException(cause);
}
}, Threads.SAME_THREAD_EXECUTOR);
completion.get();
}
use of co.cask.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.
the class AbstractProgramTwillRunnable method run.
@Override
public void run() {
Futures.getUnchecked(Services.chainStart(coreServices.get(0), coreServices.subList(1, coreServices.size()).toArray(new Service[coreServices.size() - 1])));
LOG.info("Starting runnable: {}", name);
controller = programRunner.run(program, programOpts);
final SettableFuture<ProgramController.State> state = SettableFuture.create();
controller.addListener(new AbstractListener() {
@Override
public void alive() {
runLatch.countDown();
}
@Override
public void init(ProgramController.State currentState, @Nullable Throwable cause) {
if (currentState == ProgramController.State.ALIVE) {
alive();
} else {
super.init(currentState, cause);
}
}
@Override
public void completed() {
state.set(ProgramController.State.COMPLETED);
}
@Override
public void killed() {
state.set(ProgramController.State.KILLED);
}
@Override
public void error(Throwable cause) {
LOG.error("Program runner error out.", cause);
state.setException(cause);
}
}, MoreExecutors.sameThreadExecutor());
try {
state.get();
LOG.debug("Program {} stopped.", name);
} catch (InterruptedException e) {
LOG.warn("Program {} interrupted.", name, e);
} catch (ExecutionException e) {
LOG.error("Program {} execution failed.", name, e);
if (propagateServiceError()) {
throw Throwables.propagate(Throwables.getRootCause(e));
}
} finally {
if (programRunner instanceof Closeable) {
Closeables.closeQuietly((Closeable) programRunner);
}
// Always unblock the handleCommand method if it is not unblocked before (e.g if program failed to start).
// The controller state will make sure the corresponding command will be handled correctly in the correct state.
runLatch.countDown();
}
}
Aggregations