@Override public Future<Command> sendCommand(Command command) { return delegate.sendCommand(command); }
@Override public Future<Command> sendCommand(String runnableName, Command command) { return delegate.sendCommand(runnableName, command); }
@Override public Future<Command> sendCommand(Command command) { return delegate.sendCommand(command); }
@Override public Future<Command> sendCommand(String runnableName, Command command) { return delegate.sendCommand(runnableName, command); }
@Override protected final void doResume() throws Exception { twillController.sendCommand(ProgramCommands.RESUME).get(); }
@Override protected final void doSuspend() throws Exception { twillController.sendCommand(ProgramCommands.SUSPEND).get(); }
@Override protected final void doSuspend() throws Exception { twillController.sendCommand(ProgramCommands.SUSPEND).get(); }
@Override protected final void doResume() throws Exception { twillController.sendCommand(ProgramCommands.RESUME).get(); }
@Override protected final void doResume() throws Exception { twillController.sendCommand(ProgramCommands.RESUME).get(); }
@Override protected final void doSuspend() throws Exception { twillController.sendCommand(ProgramCommands.SUSPEND).get(); }
void update(String flowletId, int newInstanceCount, int oldInstanceCount) throws Exception { FlowletDefinition flowletDefinition = program.getSpecification().getFlowlets().get(flowletId); int maxInstances = flowletDefinition.getFlowletSpec().getMaxInstances(); Preconditions.checkArgument(newInstanceCount <= maxInstances, "Flowlet %s can have a maximum of %s instances", flowletId, maxInstances); waitForInstances(flowletId, oldInstanceCount); twillController.sendCommand(flowletId, ProgramCommands.SUSPEND).get(); FlowUtils.reconfigure(consumerQueues.get(flowletId), FlowUtils.generateConsumerGroupId(program, flowletId), newInstanceCount, queueAdmin); twillController.changeInstances(flowletId, newInstanceCount).get(); twillController.sendCommand(flowletId, ProgramCommands.RESUME).get(); }
void update(final String flowletId, final int newInstanceCount, FlowSpecification flowSpec) throws Exception { // Find all flowlets that are source of the given flowletId. Set<String> flowlets = getUpstreamFlowlets(flowSpec, flowletId, Sets.<String>newHashSet()); flowlets.add(flowletId); // Suspend all upstream flowlets and the flowlet that is going to change instances for (String id : flowlets) { waitForInstances(id, getInstances(flowSpec, id)); // Need to suspend one by one due to a bug in Twill (TWILL-123) twillController.sendCommand(id, ProgramCommands.SUSPEND).get(); } impersonator.doAs(programId, new Callable<Void>() { @Override public Void call() throws Exception { FlowUtils.reconfigure(consumerQueues.get(flowletId), FlowUtils.generateConsumerGroupId(programId, flowletId), newInstanceCount, streamAdmin, queueAdmin, txExecutorFactory); return null; } }); twillController.changeInstances(flowletId, newInstanceCount).get(); for (String id : flowlets) { twillController.sendCommand(id, ProgramCommands.RESUME).get(); } }
@Test public void testRestartSingleRunnable() throws Exception { YarnTwillRunnerService runner = getTwillRunner(); runner.start(); LOG.info("Starting application {}", SingleRunnableApp.class.getSimpleName()); TwillController controller = runner.prepare(new SingleRunnableApp()) .addLogHandler(new PrinterLogHandler(new PrintWriter(System.out))) .start(); // Lets wait until all runnables have started waitForInstance(controller, HANGING_RUNNABLE, "002", 120, TimeUnit.SECONDS); waitForContainers(controller, 2, 60, TimeUnit.SECONDS); // Now restart runnable LOG.info("Restarting runnable {}", HANGING_RUNNABLE); controller.restartAllInstances(HANGING_RUNNABLE); waitForInstance(controller, HANGING_RUNNABLE, "003", 120, TimeUnit.SECONDS); waitForContainers(controller, 2, 60, TimeUnit.SECONDS); // Send command to HANGING_RUNNABLE to hang when stopped controller.sendCommand(HANGING_RUNNABLE, new SleepCommand(1000)).get(); LOG.info("Restarting runnable {}", HANGING_RUNNABLE); controller.restartAllInstances(HANGING_RUNNABLE); waitForInstance(controller, HANGING_RUNNABLE, "004", 120, TimeUnit.SECONDS); waitForContainers(controller, 2, 60, TimeUnit.SECONDS); }
controller.sendCommand(HANGING_RUNNABLE, new SleepCommand(1000)).get(); controller.sendCommand(HANGING_RUNNABLE, new SleepCommand(10)).get();
@Test public void testFailureRestart() throws Exception { TwillRunner runner = getTwillRunner(); ResourceSpecification resource = ResourceSpecification.Builder.with() .setVirtualCores(1) .setMemory(512, ResourceSpecification.SizeUnit.MEGA) .setInstances(2) .build(); TwillController controller = runner.prepare(new FailureRunnable(), resource) .withApplicationArguments("failure") .withArguments(FailureRunnable.class.getSimpleName(), "failure2") .addLogHandler(new PrinterLogHandler(new PrintWriter(System.out, true))) .start(); Iterable<Discoverable> discoverables = controller.discoverService("failure"); Assert.assertTrue(waitForSize(discoverables, 2, 120)); // Make sure we see the right instance IDs Assert.assertEquals(Sets.newHashSet(0, 1), getInstances(discoverables)); // Kill server with instanceId = 0 controller.sendCommand(FailureRunnable.class.getSimpleName(), Command.Builder.of("kill0").build()); // Make sure the runnable is killed. Assert.assertTrue(waitForSize(discoverables, 1, 120)); // Wait for the restart Assert.assertTrue(waitForSize(discoverables, 2, 120)); // Make sure we see the right instance IDs Assert.assertEquals(Sets.newHashSet(0, 1), getInstances(discoverables)); controller.terminate().get(120, TimeUnit.SECONDS); }