private static Task<?>[] asTasks(TaskAdaptable<?> ...tasks) { Task<?>[] result = new Task<?>[tasks.length]; for (int i=0; i<tasks.length; i++) result[i] = tasks[i].asTask(); return result; }
private TaskQueueingResult(TaskAdaptable<T> task, boolean wasQueued) { this.task = task.asTask(); this.wasQueued = wasQueued; } @Override
public static void addTagDynamically(TaskAdaptable<?> task, final Object tag) { ((BasicTask<?>)task.asTask()).applyTagModifier(new Function<Set<Object>, Void>() { public Void apply(@Nullable Set<Object> input) { input.add(tag); return null; } }); }
public static void addTagsDynamically(TaskAdaptable<?> task, final Object tag1, final Object ...tags) { ((BasicTask<?>)task.asTask()).applyTagModifier(new Function<Set<Object>, Void>() { public Void apply(@Nullable Set<Object> input) { input.add(tag1); for (Object tag: tags) input.add(tag); return null; } }); }
@Override public T get() { return task.asTask().getUnchecked(); } };
/** @see #submit(Map, Runnable) */ public <T> Task<T> submit(Map<?,?> properties, TaskAdaptable<T> task) { return submitInternal(properties, task.asTask()); }
public static boolean isQueuedOrSubmitted(TaskAdaptable<?> task) { return ((TaskInternal<?>)task.asTask()).isQueuedOrSubmitted(); }
/** @see #submit(Map, Runnable) */ public <T> Task<T> submit(TaskAdaptable<T> task) { return submitInternal(Maps.newLinkedHashMap(), task.asTask()); }
/** tries to add the given task in the given addition context, * returns true if it could, false if it could not (doesn't throw anything) */ public static boolean tryQueueing(TaskQueueingContext adder, TaskAdaptable<?> task) { if (task==null || isQueuedOrSubmitted(task)) return false; try { adder.queue(task.asTask()); return true; } catch (Exception e) { if (log.isDebugEnabled()) log.debug("Could not add task "+task+" at "+adder+": "+e); return false; } }
/** submits the given task if needed, and gets the result (unchecked) * only permitted in a queueing context (ie a DST main job) */ // things get really confusing if you try to queueInTaskHierarchy -- easy to cause deadlocks! public static <T> T get(TaskAdaptable<T> t) { return queueIfNeeded(t).asTask().getUnchecked(); }
public <T> Task<T> submit(Map<?,?> flags, TaskAdaptable<T> task) { if (!(task instanceof Task)) task = task.asTask(); synchronized (task) { if (((TaskInternal<?>)task).getResult()!=null) return (Task<T>)task; return submitNewTask(flags, (Task<T>) task); } }
public static <V extends TaskAdaptable<?>> V queue(V task) { try { Preconditions.checkNotNull(task, "Task to queue cannot be null"); Preconditions.checkState(!Tasks.isQueuedOrSubmitted(task), "Task to queue must not yet be submitted: %s", task); TaskQueueingContext adder = getTaskQueuingContext(); if (adder==null) throw new IllegalStateException("Task "+task+" cannot be queued here; no queueing context available"); adder.queue(task.asTask()); return task; } catch (Throwable e) { log.warn("Error queueing "+task+" (rethrowing): "+e); throw Exceptions.propagate(e); } }
@SuppressWarnings({ "unchecked", "rawtypes" }) public CompoundTask(Map<String,?> flags, Collection<?> jobs) { super(flags); super.job = new Callable<List<T>>() { @Override public List<T> call() throws Exception { return runJobs(); } }; this.result = new ArrayList<Object>(jobs.size()); this.children = new ArrayList<Task<? extends T>>(jobs.size()); for (Object job : jobs) { if (job instanceof TaskAdaptable) { children.add(((TaskAdaptable)job).asTask()); } else if (job instanceof Closure) { children.add(new BasicTask<T>((Closure) job)); } else if (job instanceof Callable) { children.add(new BasicTask<T>((Callable) job)); } else if (job instanceof Runnable) { children.add(new BasicTask<T>((Runnable) job)); } else throw new IllegalArgumentException("Invalid child "+job+ " passed to compound task; must be Runnable, Callable, Closure or Task"); } for (Task<?> t: getChildren()) ((TaskInternal<?>)t).markQueued(); }
/** submits a task to run at the entity */ public static <T extends TaskAdaptable<?>> T submit(final Entity entity, final T task) { final ExecutionContext executionContext = ((EntityInternal)entity).getManagementSupport().getExecutionContext(); executionContext.submit(task.asTask()); return task; }
/** submits a task factory to construct its task at the entity (in a precursor task) and then to submit it; * important if e.g. task construction relies on an entity being in scope (in tags, via {@link BrooklynTasks}) */ public static <T extends TaskAdaptable<?>> T submit(final Entity entity, final TaskFactory<T> taskFactory) { // TODO it is messy to have to do this, but not sure there is a cleaner way :( final Semaphore s = new Semaphore(0); final AtomicReference<T> result = new AtomicReference<T>(); final ExecutionContext executionContext = ((EntityInternal)entity).getManagementSupport().getExecutionContext(); executionContext.execute(new Runnable() { // TODO could give this task a name, like "create task from factory" @Override public void run() { T t = taskFactory.newTask(); result.set(t); s.release(); } }); try { s.acquire(); } catch (InterruptedException e) { throw Exceptions.propagate(e); } executionContext.submit(result.get().asTask()); return result.get(); }
@Override public boolean isRunning() { return DynamicTasks.queue(getRequiredConfig(IS_RUNNING_TASK)).asTask().getUnchecked(); }
@SuppressWarnings("deprecation") protected void submitIfNecessary(TaskAdaptable<?> task) { if (!task.asTask().isSubmitted()) { if (BasicExecutionContext.getCurrentExecutionContext() == null) { if (em!=null) { log.warn("Discouraged submission of compound task ({}) from {} without execution context; using execution manager", task, this); em.submit(task); } else { throw new IllegalStateException("Compound task ("+task+") launched from "+this+" missing required execution context"); } } else { BasicExecutionContext.getCurrentExecutionContext().submit(task); } } }
public static <T> Task<T> invokeEffector(EntityLocal callingEntity, Entity entityToCall, final Effector<T> effector, final Map<String,?> parameters) { Task<T> t = Effectors.invocation(entityToCall, effector, parameters).asTask(); // we pass to callingEntity for consistency above, but in exec-context it should be // re-dispatched to targetEntity ((EntityInternal)callingEntity).getManagementSupport().getExecutionContext().submit( MutableMap.of("tag", BrooklynTasks.tagForCallerEntity(callingEntity)), t); return t; } @SuppressWarnings("unchecked")