protected void waitForTasksOnStart(Map<Entity, Task<?>> tasks) { // TODO Could do best-effort for waiting for remaining tasks, rather than failing on first? for (Map.Entry<Entity, Task<?>> entry: tasks.entrySet()) { try { entry.getValue().get(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw Throwables.propagate(e); } catch (ExecutionException ee) { throw Throwables.propagate(ee.getCause()); } } }
protected List<T> runJobs() throws InterruptedException, ExecutionException { setBlockingDetails("Executing "+ (children.size()==1 ? "1 child task" : children.size()+" children tasks sequentially") ); List<T> result = new ArrayList<T>(); for (Task<? extends T> task : children) { submitIfNecessary(task); // throw exception (and cancel subsequent tasks) on error result.add(task.get()); } return result; } }
protected List<T> runJobs() throws InterruptedException, ExecutionException { setBlockingDetails("Executing "+ (children.size()==1 ? "1 child task" : children.size()+" children tasks in parallel") ); for (Task<? extends T> task : children) { submitIfNecessary(task); } List<T> result = new ArrayList<T>(); for (Task<? extends T> task : children) { result.add(task.get()); } return result; } }
protected Map<Entity, Throwable> waitForTasksOnEntityStart(Map<? extends Entity,? extends Task<?>> tasks) { // TODO Could have CompoundException, rather than propagating first Map<Entity, Throwable> errors = Maps.newLinkedHashMap(); for (Map.Entry<? extends Entity,? extends Task<?>> entry : tasks.entrySet()) { Entity entity = entry.getKey(); Task<?> task = entry.getValue(); try { task.get(); } catch (InterruptedException e) { throw Exceptions.propagate(e); } catch (Throwable t) { Throwable interesting = Exceptions.getFirstInteresting(t); LOG.error("Cluster "+this+" failed to start entity "+entity+" (removing): "+interesting, interesting); LOG.debug("Trace for: Cluster "+this+" failed to start entity "+entity+" (removing): "+t, t); // previously we unwrapped but now there is no need I think errors.put(entity, t); } } return errors; }
@SuppressWarnings({ "unchecked", "rawtypes" }) public void run() { synchronized (entitiesToStopOnShutdown) { log.info("Brooklyn stopOnShutdown shutdown-hook invoked: stopping "+entitiesToStopOnShutdown); List<Task> stops = new ArrayList<Task>(); for (Entity entity: entitiesToStopOnShutdown) { try { stops.add(entity.invoke(Startable.STOP, new MutableMap())); } catch (Exception exc) { log.debug("stopOnShutdown of "+entity+" returned error: "+exc, exc); } } for (Task t: stops) { try { log.debug("stopOnShutdown of {} completed: {}", t, t.get()); } catch (Exception exc) { log.debug("stopOnShutdown of "+t+" returned error: "+exc, exc); } } } } });
@Override public T call() throws Exception { final ExecutionContext executionContext = ((EntityInternal) entity).getManagementSupport().getExecutionContext(); return executionContext.submit(Maps.newHashMap(), job).get(); } }
@Override public T call() throws Exception { final ExecutionContext executionContext = ((EntityInternal) entity).getManagementSupport().getExecutionContext(); return executionContext.submit(Maps.newHashMap(), job).get(); } }
/** gets the value of the most recently run task */ public Object get() throws InterruptedException, ExecutionException { blockUntilStarted(); blockUntilFirstScheduleStarted(); return (truth(recentRun)) ? recentRun.get() : result.get(); } }
@Override public void run() { try { Entities.invokeEffectorWithArgs(entity, entity, DynamicCluster.REPLACE_MEMBER, event.getSource().getId()).get(); consecutiveReplacementFailureTimes.clear(); } catch (Exception e) { // FIXME replaceMember fails if stop fails on the old node; should resolve that more gracefully than this if (e.toString().contains("stopping") && e.toString().contains(event.getSource().getId())) { LOG.info("ServiceReplacer: ignoring error reported from stopping failed node "+event.getSource()); return; } onReplacementFailed("Replace failure (error "+e+") at "+entity+": "+event.getValue()); } }
Object result = null; if (timeout==null || timeout.isEmpty() || "never".equalsIgnoreCase(timeout)) { result = t.get(); } else { long timeoutMillis = "always".equalsIgnoreCase(timeout) ? 0 : Time.parseTimeString(timeout); try { if (timeoutMillis==0) throw new TimeoutException(); result = t.get(timeoutMillis, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { return Response.status(Response.Status.ACCEPTED).entity(TaskTransformer.taskSummary(t)).build();
protected void stopAndRemoveNode(Entity member) { removeMember(member); try { if (member instanceof Startable) { Task<?> task = member.invoke(Startable.STOP, Collections.<String,Object>emptyMap()); try { task.get(); } catch (Exception e) { throw Exceptions.propagate(e); } } } finally { Entities.unmanage(member); } } }
public T call() throws Exception { if (!task.asTask().isSubmitted()) { BasicExecutionContext.getCurrentExecutionContext().submit(task); } return transformer.apply(task.asTask().get()); }}); }
/** * Decreases the cluster size by the given number. * Called when synchronized on mutex, so overriders beware! */ protected void shrink(int delta) { Collection<Entity> removedEntities = pickAndRemoveMembers(delta * -1); // FIXME symmetry in order of added as child, managed, started, and added to group // FIXME assume stoppable; use logic of grow? Task<?> invoke = Entities.invokeEffector(this, removedEntities, Startable.STOP, Collections.<String,Object>emptyMap()); try { invoke.get(); } catch (Exception e) { throw Exceptions.propagate(e); } finally { for (Entity removedEntity : removedEntities) { discardNode(removedEntity); } } }
Object result = null; if (timeout==null || timeout.isEmpty() || "never".equalsIgnoreCase(timeout)) { result = t.get(); } else { long timeoutMillis = "always".equalsIgnoreCase(timeout) ? 0 : Time.parseTimeString(timeout); try { if (timeoutMillis==0) throw new TimeoutException(); result = t.get(timeoutMillis, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { return Response.status(Response.Status.ACCEPTED).entity( TaskSummary.fromTask(t) ).build();
@Override public void removeRegion(String id) { Entity entity = getManagementContext().getEntityManager().getEntity(id); Preconditions.checkNotNull(entity, "No entity found for %s", id); Preconditions.checkArgument(this.equals(entity.getParent()), "Wrong parent (%s) for %s", entity.getParent(), entity); Collection<Location> childLocations = entity.getLocations(); if (entity instanceof Startable) { try { Entities.invokeEffector(this, entity, Startable.STOP).get(); } catch (Exception e) { Exceptions.propagateIfFatal(e); log.warn("Error stopping "+entity+" ("+e+"); proceeding to remove it anyway"); log.debug("Error stopping "+entity+" ("+e+"); proceeding to remove it anyway", e); } } removeChild(entity); removeLocations(childLocations); }
} else { try { out.append(((Task<?>)v).get() + " (from "+v+")"); } catch (ExecutionException ee) { throw new IllegalStateException("task "+v+" done and !isError, but threw exception on get", ee);
protected synchronized void onDetectedFailure(SensorEvent<Object> event) { if (isSuspended()) { LOG.warn("ServiceRestarter suspended, so not acting on failure detected at "+entity+" ("+event.getValue()+")"); return; } LOG.warn("ServiceRestarter acting on failure detected at "+entity+" ("+event.getValue()+")"); long current = System.currentTimeMillis(); Long last = lastFailureTime.getAndSet(current); long elapsed = last==null ? -1 : current-last; if (elapsed>=0 && elapsed <= getConfig(FAIL_ON_RECURRING_FAILURES_IN_THIS_DURATION)) { onRestartFailed("Restart failure (failed again after "+Time.makeTimeStringRounded(elapsed)+") at "+entity+": "+event.getValue()); return; } try { entity.setAttribute(Attributes.SERVICE_STATE, Lifecycle.STARTING); Entities.invokeEffector(entity, entity, Startable.RESTART).get(); } catch (Exception e) { onRestartFailed("Restart failure (error "+e+") at "+entity+": "+event.getValue()); } }
@Override public void stop() { setAttribute(SERVICE_STATE, Lifecycle.STOPPING); try { Iterable<Entity> stoppableChildren = Iterables.filter(getChildren(), Predicates.instanceOf(Startable.class)); Task<?> invoke = Entities.invokeEffector(this, stoppableChildren, Startable.STOP); if (invoke != null) invoke.get(); setAttribute(SERVICE_STATE, Lifecycle.STOPPED); setAttribute(SERVICE_UP, false); } catch (Exception e) { setAttribute(SERVICE_STATE, Lifecycle.ON_FIRE); throw Exceptions.propagate(e); } }
/** * Method for entity to make effector happen with correct semantics (right place, right task context), * when a method is called on that entity. * @throws ExecutionException */ public <T> T invokeEffectorMethodSync(final Entity entity, final Effector<T> eff, final Object args) throws ExecutionException { try { Task<?> current = Tasks.current(); if (current == null || !entity.equals(BrooklynTasks.getContextEntity(current)) || !isManagedLocally(entity)) { manageIfNecessary(entity, eff.getName()); // Wrap in a task if we aren't already in a task that is tagged with this entity Task<T> task = runAtEntity( EffectorUtils.getTaskFlagsForEffectorInvocation(entity, eff), entity, new Callable<T>() { public T call() { return invokeEffectorMethodLocal(entity, eff, args); }}); return task.get(); } else { return invokeEffectorMethodLocal(entity, eff, args); } } catch (Exception e) { // don't need to attach any message or warning because the Effector impl hierarchy does that (see calls to EffectorUtils.handleException) throw new ExecutionException(e); } }