/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.brooklyn.util.core.task; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import org.apache.brooklyn.api.mgmt.ExecutionManager; import org.apache.brooklyn.api.mgmt.Task; import org.apache.brooklyn.util.time.Duration; import com.google.common.annotations.Beta; import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.util.concurrent.ExecutionList; import com.google.common.util.concurrent.ListenableFuture; /** * All tasks being passed to the {@link ExecutionManager} should implement this. * Users are strongly encouraged to use (or extend) {@link BasicTask}, rather than * implementing a task from scratch. * * The methods on this interface will change in subsequent releases. Because this is * marked as beta, the normal deprecation policy for these methods does not apply. * * @author aled */ @Beta public interface TaskInternal<T> extends Task<T> { /** sets the internal future object used to record the association to a job submitted to an {@link ExecutorService} */ void initInternalFuture(ListenableFuture<T> result); /** returns the underlying future where this task's results will come in; see {@link #initInternalFuture(ListenableFuture)} */ Future<T> getInternalFuture(); /** if the job is queued for submission (e.g. by another task) it can indicate that fact (and time) here; * note tasks can (and often are) submitted without any queueing, in which case this value may be -1 */ long getQueuedTimeUtc(); boolean isQueuedOrSubmitted(); boolean isQueuedAndNotSubmitted(); boolean isQueued(); /** marks the task as queued for execution */ void markQueued(); boolean cancel(); boolean blockUntilStarted(Duration timeout); /** allows a task user to specify why a task is blocked; for use immediately before a blocking/wait, * and typically cleared immediately afterwards; referenced by management api to inspect a task * which is blocking * <p> * returns previous details, in case caller wishes to recall and restore it (e.g. if it is doing a sub-blocking) */ String setBlockingDetails(String blockingDetails); /** as {@link #setBlockingDetails(String)} but records a task which is blocking, * for use e.g. in a gui to navigate to the current active subtask * <p> * returns previous blocking task, in case caller wishes to recall and restore it */ Task<?> setBlockingTask(Task<?> blockingTask); void resetBlockingDetails(); void resetBlockingTask(); /** returns a textual message giving details while the task is blocked */ String getBlockingDetails(); /** returns a task that this task is blocked on */ Task<?> getBlockingTask(); void setExtraStatusText(Object extraStatus); Object getExtraStatusText(); /** On task completion (or cancellation) runs the listeners which have been registered using * {@link #addListener(Runnable, java.util.concurrent.Executor)}. */ void runListeners(); void setEndTimeUtc(long val); void setThread(Thread thread); Callable<T> getJob(); void setJob(Callable<T> job); ExecutionList getListeners(); void setSubmitTimeUtc(long currentTimeMillis); void setSubmittedByTask(Task<?> task); Set<Object> getMutableTags(); void setStartTimeUtc(long currentTimeMillis); void applyTagModifier(Function<Set<Object>,Void> modifier); /** if a task is a proxy for another one (used mainly for internal tasks), * this returns the "real" task represented by this one */ Task<?> getProxyTarget(); /** clearer semantics around cancellation; may be promoted to {@link Task} if we */ @Beta public boolean cancel(TaskCancellationMode mode); @Beta public static class TaskCancellationMode { public static final TaskCancellationMode DO_NOT_INTERRUPT = new TaskCancellationMode(false, false, false); public static final TaskCancellationMode INTERRUPT_TASK_BUT_NOT_SUBMITTED_TASKS = new TaskCancellationMode(true, false, false); public static final TaskCancellationMode INTERRUPT_TASK_AND_DEPENDENT_SUBMITTED_TASKS = new TaskCancellationMode(true, true, false); public static final TaskCancellationMode INTERRUPT_TASK_AND_ALL_SUBMITTED_TASKS = new TaskCancellationMode(true, true, true); private final boolean allowedToInterruptTask, allowedToInterruptDependentSubmittedTasks, allowedToInterruptAllSubmittedTasks; private TaskCancellationMode(boolean mayInterruptIfRunning, boolean interruptSubmittedTransients, boolean interruptAllSubmitted) { this.allowedToInterruptTask = mayInterruptIfRunning; this.allowedToInterruptDependentSubmittedTasks = interruptSubmittedTransients; this.allowedToInterruptAllSubmittedTasks = interruptAllSubmitted; } public boolean isAllowedToInterruptTask() { return allowedToInterruptTask; } /** Implementation-dependent what "dependent" means in this context, * e.g. may be linked to a "transient" tag (that's what Brooklyn does) */ public boolean isAllowedToInterruptDependentSubmittedTasks() { return allowedToInterruptDependentSubmittedTasks; } public boolean isAllowedToInterruptAllSubmittedTasks() { return allowedToInterruptAllSubmittedTasks; } @Override public String toString() { return Objects.toStringHelper(this).add("interruptTask", allowedToInterruptTask) .add("interruptDependentSubmitted", allowedToInterruptDependentSubmittedTasks) .add("interruptAllSubmitted", allowedToInterruptAllSubmittedTasks) .toString(); } } }