tasks); TaskTags.markInessential(invoke); return DynamicTasks.queueIfPossible(invoke).orSubmitAsync(callingEntity).asTask();
@Override public void redeployAll() { Map<String, String> wars = MutableMap.copyOf(getConfig(WARS_BY_CONTEXT)); String redeployPrefix = "Redeploy all WARs (count "+wars.size()+")"; log.debug("Redeplying all WARs across cluster "+this+": "+getConfig(WARS_BY_CONTEXT)); Iterable<CanDeployAndUndeploy> targetEntities = Iterables.filter(getChildren(), CanDeployAndUndeploy.class); TaskBuilder<Void> tb = Tasks.<Void>builder().parallel(true).displayName(redeployPrefix+" across cluster (size "+Iterables.size(targetEntities)+")"); for (Entity targetEntity: targetEntities) { TaskBuilder<Void> redeployAllToTarget = Tasks.<Void>builder().displayName(redeployPrefix+" at "+targetEntity+" (after ready check)"); for (String warContextPath: wars.keySet()) { redeployAllToTarget.add(Effectors.invocation(targetEntity, DEPLOY, MutableMap.of("url", wars.get(warContextPath), "targetName", warContextPath))); } tb.add(whenServiceUp(targetEntity, redeployAllToTarget.build(), redeployPrefix+" at "+targetEntity+" when ready")); } DynamicTasks.queueIfPossible(tb.build()).orSubmitAsync(this).asTask().getUnchecked(); }
@Override public void deploy(String url, String targetName) { checkNotNull(url, "url"); checkNotNull(targetName, "targetName"); targetName = FILENAME_TO_WEB_CONTEXT_MAPPER.convertDeploymentTargetNameToContext(targetName); // set it up so future nodes get the right wars addToWarsByContext(this, url, targetName); log.debug("Deploying "+targetName+"->"+url+" across cluster "+this+"; WARs now "+getConfig(WARS_BY_CONTEXT)); Iterable<CanDeployAndUndeploy> targets = Iterables.filter(getChildren(), CanDeployAndUndeploy.class); TaskBuilder<Void> tb = Tasks.<Void>builder().parallel(true).displayName("Deploy "+targetName+" to cluster (size "+Iterables.size(targets)+")"); for (Entity target: targets) { tb.add(whenServiceUp(target, Effectors.invocation(target, DEPLOY, MutableMap.of("url", url, "targetName", targetName)), "Deploy "+targetName+" to "+target+" when ready")); } DynamicTasks.queueIfPossible(tb.build()).orSubmitAsync(this).asTask().getUnchecked(); // Update attribute // TODO support for atomic sensor update (should be part of standard tooling; NB there is some work towards this, according to @aledsage) Set<String> deployedWars = MutableSet.copyOf(getAttribute(DEPLOYED_WARS)); deployedWars.add(targetName); sensors().set(DEPLOYED_WARS, deployedWars); }
DynamicTasks.queueIfPossible(running).orSubmitAndBlock(this).asTask().getUnchecked(Duration.FIVE_MINUTES); Task<?> hostname = DependentConfiguration.attributeWhenReady(this, Attributes.HOSTNAME, Predicates.notNull()); DynamicTasks.queueIfPossible(hostname).orSubmitAndBlock(this).asTask().getUnchecked(Duration.FIVE_MINUTES); LOG.info("Task {} running on {} successfully", id, getHostname());
ProcessTaskWrapper<Integer> task = SshTasks.newSshExecTaskFactory(origin, "ping -c 1 -t 1 "+hostnameTarget) .summary("checking resolution of "+hostnameTarget).allowingNonZeroExitCode().newTask(); DynamicTasks.queueIfPossible(task).orSubmitAndBlock(entity).asTask().blockUntilEnded(); if (task.asTask().isError()) { log.warn("ping could not be run, at "+entity+" / "+origin+": "+Tasks.getError(task.asTask()));
@Override public void stop() { sensors().set(SERVICE_UP, Boolean.FALSE); synchronized (this) { try { Tasks.setBlockingDetails("Waiting until all containers are disconnected from " + sensors().get(NETWORK_ID)); Task<?> waiting = DependentConfiguration.attributeWhenReady(this, CONNECTED_CONTAINERS, new Predicate<Set>() { @Override public boolean apply(Set input) { return input.isEmpty(); } }); Task<?> task = DynamicTasks.queueIfPossible(waiting).orSubmitAndBlock(this).asTask(); task.get(Duration.FIVE_MINUTES); } catch (InterruptedException | ExecutionException | TimeoutException e) { LOG.error("Error waiting for containers to disconnect", e); throw Exceptions.propagate(e); } finally { Tasks.resetBlockingDetails(); } // If task is still blocking we would never be able to delete the network NetworkProvisioningExtension provisioner = sensors().get(NETWORK_PROVISIONER); if (provisioner != null) { provisioner.deallocateNetwork(this); } super.stop(); } }
@Override public String execCommandTimeout(String command, Duration timeout) { ProcessTaskWrapper<String> task = SshEffectorTasks.ssh(command) .environmentVariables(((AbstractSoftwareProcessSshDriver) getDriver()).getShellEnvironment()) .configure(SshTool.PROP_ALLOCATE_PTY, true) // TODO configure globally .requiringZeroAndReturningStdout() .machine(getMachine()) .summary(command) .newTask(); try { String result = DynamicTasks.queueIfPossible(task) .executionContext(this) .orSubmitAsync() .asTask() .get(timeout); return result; } catch (TimeoutException te) { throw new IllegalStateException("Timed out running command: " + command); } catch (Exception e) { Integer exitCode = task.getExitCode(); LOG.warn("Command failed, return code {}: {}", exitCode == null ? -1 : exitCode, task.getStderr()); throw Exceptions.propagate(e); } }
@Override public int execCommandStatusTimeout(String command, Duration timeout) { ProcessTaskWrapper<Object> task = SshEffectorTasks.ssh(command) .environmentVariables(((AbstractSoftwareProcessSshDriver) getDriver()).getShellEnvironment()) .returning(ScriptReturnType.EXIT_CODE) .allowingNonZeroExitCode() .machine(getMachine()) .summary(command) .newTask(); try { Object result = DynamicTasks.queueIfPossible(task) .executionContext(this) .orSubmitAsync() .asTask() .get(timeout); return (Integer) result; } catch (TimeoutException te) { throw new IllegalStateException("Timed out running command: " + command); } catch (Exception e) { Integer exitCode = task.getExitCode(); LOG.warn("Command failed, return code {}: {}", exitCode == null ? -1 : exitCode, task.getStderr()); throw Exceptions.propagate(e); } }
@Override public String execCommandTimeout(String command, Duration timeout) { AbstractSoftwareProcessSshDriver driver = (AbstractSoftwareProcessSshDriver) getDriver(); if (driver == null) { throw new NullPointerException("No driver for "+this); } ProcessTaskWrapper<String> task = SshEffectorTasks.ssh(command) .environmentVariables(driver.getShellEnvironment()) .requiringZeroAndReturningStdout() .machine(getMachine()) .summary(command) .newTask(); try { String result = DynamicTasks.queueIfPossible(task) .executionContext(this) .orSubmitAsync() .asTask() .get(timeout); return result; } catch (TimeoutException te) { throw new IllegalStateException("Timed out running command: " + command); } catch (Exception e) { Integer exitCode = task.getExitCode(); LOG.warn("Command failed, return code {}: {}", exitCode == null ? -1 : exitCode, task.getStderr()); throw Exceptions.propagate(e); } }
@Override public void undeploy(String targetName) { checkNotNull(targetName, "targetName"); targetName = FILENAME_TO_WEB_CONTEXT_MAPPER.convertDeploymentTargetNameToContext(targetName); // set it up so future nodes get the right wars if (!removeFromWarsByContext(this, targetName)) { DynamicTasks.submit(Tasks.warning("Context "+targetName+" not known at "+this+"; attempting to undeploy regardless", null), this); } log.debug("Undeploying "+targetName+" across cluster "+this+"; WARs now "+getConfig(WARS_BY_CONTEXT)); Iterable<CanDeployAndUndeploy> targets = Iterables.filter(getChildren(), CanDeployAndUndeploy.class); TaskBuilder<Void> tb = Tasks.<Void>builder().parallel(true).displayName("Undeploy "+targetName+" across cluster (size "+Iterables.size(targets)+")"); for (Entity target: targets) { tb.add(whenServiceUp(target, Effectors.invocation(target, UNDEPLOY, MutableMap.of("targetName", targetName)), "Undeploy "+targetName+" at "+target+" when ready")); } DynamicTasks.queueIfPossible(tb.build()).orSubmitAsync(this).asTask().getUnchecked(); // Update attribute Set<String> deployedWars = MutableSet.copyOf(getAttribute(DEPLOYED_WARS)); deployedWars.remove( FILENAME_TO_WEB_CONTEXT_MAPPER.convertDeploymentTargetNameToContext(targetName) ); sensors().set(DEPLOYED_WARS, deployedWars); }
public void apply(final Entity source, final Object valueIgnored) { T val = (T) attribute.getValue(); if (!readiness.apply(val)) { log.warn("Skipping {} for {} because attribute {} not ready", new Object[]{description, attribute.getEntity(), attribute.getAttribute()}); return; } final Task<Void> task = TaskBuilder.<Void>builder().displayName(description).body(runnable).build(); DynamicTasks.queueIfPossible(task).orSubmitAsync(source).asTask(); if (blockUntilEnded) { final String originalBlock = Tasks.setBlockingDetails(description); try { task.blockUntilEnded(); } finally { Tasks.setBlockingDetails(originalBlock); } } } }
@Override public Boolean execute(final boolean shouldThrow) { Task<Boolean> t = Tasks.<Boolean>builder() .body(new Callable<Boolean>() { @Override public Boolean call() { if (shouldThrow) { throw new IllegalArgumentException("exception in feed task"); } return true; } }) .build(); return DynamicTasks.queueIfPossible(t).orSubmitAsync().asTask().getUnchecked(); } }
/** * Creates a MachineDetails for the given location by SSHing to the machine and * running a Bash script to gather data. Should only be called from within a * task context. If this might not be the case then use {@link * #taskForSshMachineLocation(SshMachineLocation)} instead. */ @Beta public static BasicMachineDetails forSshMachineLocationLive(SshMachineLocation location) { return TaskTags.markInessential(DynamicTasks.queueIfPossible(taskForSshMachineLocation(location)) .orSubmitAsync() .asTask()) .getUnchecked(); }
@Override public void rebind() { super.rebind(); Task<String> task = new BasicTask<String>(new Callable<String>() { @Override public String call() { return "abc"; }}); String val = DynamicTasks.queueIfPossible(task) .orSubmitAsync() .asTask() .getUnchecked(); sensors().set(TestEntity.NAME, val); } }
/** queues the task if possible, otherwise submits it asynchronously; returns the task for callers to * {@link Task#getUnchecked()} or {@link Task#blockUntilEnded()} */ public static <T> Task<T> submit(TaskAdaptable<T> task, Entity entity) { return queueIfPossible(task).orSubmitAsync(entity).asTask(); }