/** * Main method for launching a {@link TwillContainerService} which runs a {@link * org.apache.twill.api.TwillRunnable}. */ public static void main(final String[] args) throws Exception { // Try to load the secure store from localized file, which AM requested RM to localize it for // this container. loadSecureStore(); String zkConnectStr = System.getenv(EnvKeys.TWILL_ZK_CONNECT); File twillSpecFile = new File(Constants.Files.TWILL_SPEC); RunId appRunId = RunIds.fromString(System.getenv(EnvKeys.TWILL_APP_RUN_ID)); RunId runId = RunIds.fromString(System.getenv(EnvKeys.TWILL_RUN_ID)); String runnableName = System.getenv(EnvKeys.TWILL_RUNNABLE_NAME); int instanceId = Integer.parseInt(System.getenv(EnvKeys.TWILL_INSTANCE_ID)); int instanceCount = Integer.parseInt(System.getenv(EnvKeys.TWILL_INSTANCE_COUNT)); ZKClientService zkClientService = createZKClient(zkConnectStr); ZKDiscoveryService discoveryService = new ZKDiscoveryService(zkClientService); ZKClient appRunZkClient = getAppRunZKClient(zkClientService, appRunId); TwillSpecification twillSpec = loadTwillSpec(twillSpecFile); renameLocalFiles(twillSpec.getRunnables().get(runnableName)); TwillRunnableSpecification runnableSpec = twillSpec.getRunnables().get(runnableName).getRunnableSpecification(); ContainerInfo containerInfo = new EnvContainerInfo(); Arguments arguments = decodeArgs(); BasicTwillContext context = new BasicTwillContext( runId, appRunId, containerInfo.getHost(), arguments.getRunnableArguments().get(runnableName).toArray(new String[0]), arguments.getArguments().toArray(new String[0]), runnableSpec, instanceId, discoveryService, discoveryService, appRunZkClient, instanceCount, containerInfo.getMemoryMB(), containerInfo.getVirtualCores()); ZKClient containerZKClient = getContainerZKClient(zkClientService, appRunId, runnableName); Configuration conf = new YarnConfiguration(new HdfsConfiguration(new Configuration())); Service service = new TwillContainerService( context, containerInfo, containerZKClient, runId, runnableSpec, getClassLoader(), createAppLocation(conf)); new TwillContainerMain() .doMain( service, new LogFlushService(), zkClientService, new TwillZKPathService(containerZKClient, runId)); }
@Test public void testStateTransition() throws InterruptedException, ExecutionException, TimeoutException { InMemoryZKServer zkServer = InMemoryZKServer.builder().build(); zkServer.startAndWait(); try { final String namespace = Joiner.on('/').join("/twill", RunIds.generate(), "runnables", "Runner1"); final ZKClientService zkClient = ZKClientService.Builder.of(zkServer.getConnectionStr()).build(); zkClient.startAndWait(); zkClient.create(namespace, null, CreateMode.PERSISTENT).get(); try { JsonObject content = new JsonObject(); content.addProperty("containerId", "container-123"); content.addProperty("host", "localhost"); RunId runId = RunIds.generate(); final Semaphore semaphore = new Semaphore(0); ZKServiceDecorator service = new ZKServiceDecorator( ZKClients.namespace(zkClient, namespace), runId, Suppliers.ofInstance(content), new AbstractIdleService() { @Override protected void startUp() throws Exception { Preconditions.checkArgument( semaphore.tryAcquire(5, TimeUnit.SECONDS), "Fail to start"); } @Override protected void shutDown() throws Exception { Preconditions.checkArgument( semaphore.tryAcquire(5, TimeUnit.SECONDS), "Fail to stop"); } }); final String runnablePath = namespace + "/" + runId.getId(); final AtomicReference<String> stateMatch = new AtomicReference<String>("STARTING"); watchDataChange(zkClient, runnablePath + "/state", semaphore, stateMatch); Assert.assertEquals(Service.State.RUNNING, service.start().get(5, TimeUnit.SECONDS)); stateMatch.set("STOPPING"); Assert.assertEquals(Service.State.TERMINATED, service.stop().get(5, TimeUnit.SECONDS)); } finally { zkClient.stopAndWait(); } } finally { zkServer.stopAndWait(); } }