public class DynamicSequentialTask<T> extends BasicTask<T> implements HasTaskChildren, TaskQueueingContext
There is an optional primary job run with this task, along with multiple secondary children.
If any secondary task fails (assuming it isn't Tasks.markInessential() then by default
subsequent tasks are not submitted and the primary task fails (but no tasks are cancelled or interrupted).
You can change the behavior of this task with fields in DynamicSequentialTask.FailureHandlingConfig,
or the convenience TaskQueueingContext.swallowChildrenFailures()
(and DynamicTasks.swallowChildrenFailures() if you are inside the task).
This synchronizes on secondary tasks when submitting them, in case they may be manually submitted and the submitter wishes to ensure it is only submitted once.
Improvements which would be nice to have:
BasicExecutionManager to run the jobs sequentially (combined with fix to item above)
| Modifier and Type | Class and Description |
|---|---|
static class |
DynamicSequentialTask.FailureHandlingConfig |
static class |
DynamicSequentialTask.QueueAbortedException |
BasicTask.SubmissionErrorCatchingExecutor, BasicTask.TaskFinalizerdescription, displayName, NO_OP, WARN_IF_NOT_RUN| Constructor and Description |
|---|
DynamicSequentialTask()
Constructs a new compound task containing the specified units of work.
|
DynamicSequentialTask(java.util.concurrent.Callable<T> mainJob) |
DynamicSequentialTask(java.util.Map<?,?> flags,
java.util.concurrent.Callable<T> mainJob) |
| Modifier and Type | Method and Description |
|---|---|
boolean |
cancel(boolean mayInterruptIfRunning)
As
Future.cancel(boolean). |
boolean |
cancel(boolean mayInterruptTask,
boolean interruptPrimaryThread,
boolean alsoCancelChildren) |
void |
drain(Duration optionalTimeout,
boolean includePrimary,
boolean throwFirstError)
Drains the task queue for this context to complete, ie waits for this context to complete (or terminate early)
|
java.lang.Iterable<Task<?>> |
getChildren() |
java.util.List<Task<?>> |
getQueue()
returns a list of queued tasks (immutable copy)
|
void |
handleException(java.lang.Throwable throwable) |
void |
handleException(java.lang.Throwable throwable,
boolean fromChild) |
Task<?> |
last()
Deprecated.
|
void |
queue(Task<?> t)
queues the task for submission as part of this queueing context
|
void |
setFailureHandlingConfig(DynamicSequentialTask.FailureHandlingConfig failureHandlingConfig) |
void |
swallowChildrenFailures()
causes subsequent children failures not to fail the parent
|
boolean |
uncancel()
doesn't resume it, just means if something was cancelled but not submitted it could now be submitted;
probably going to be removed and perhaps some mechanism for running again made available
|
addListener, applyTagModifier, asTask, blockUntilEnded, blockUntilEnded, blockUntilStarted, blockUntilStarted, cancel, equals, get, get, get, getBlockingDetails, getBlockingTask, getDescription, getDisplayName, getEndTimeUtc, getExtraStatusText, getId, getInternalFuture, getJob, getListeners, getMutableTags, getProxyTarget, getQueuedTimeUtc, getStartTimeUtc, getStatusDetail, getStatusSummary, getSubmittedByTask, getSubmitTimeUtc, getTags, getThread, getUnchecked, getUnchecked, hashCode, ignoreIfNotRun, initInternalFuture, isBegun, isCancelled, isDone, isError, isQueued, isQueuedAndNotSubmitted, isQueuedOrSubmitted, isSubmitted, markQueued, resetBlockingDetails, resetBlockingTask, runListeners, setBlockingDetails, setBlockingTask, setEndTimeUtc, setExtraStatusText, setFinalizer, setJob, setStartTimeUtc, setSubmittedByTask, setSubmitTimeUtc, setThread, toStringasTaskpublic DynamicSequentialTask()
jobs - A potentially heterogeneous mixture of Runnable, Callable, Closure and Task can be provided.java.lang.IllegalArgumentException - if any of the passed child jobs is not one of the above typespublic DynamicSequentialTask(java.util.concurrent.Callable<T> mainJob)
public DynamicSequentialTask(java.util.Map<?,?> flags,
java.util.concurrent.Callable<T> mainJob)
public void queue(Task<?> t)
TaskQueueingContextimplementations should mark it as queued but not yet submitted. note the task may have already been submitted, and is being queued here for informational purposes, in which case the implementation should not run it.
queue in interface TaskQueueingContextpublic boolean cancel(boolean mayInterruptIfRunning)
TaskFuture.cancel(boolean). Note that Future.isDone() and Task.blockUntilEnded(Duration) return immediately
once a task is cancelled, consistent with the underlying FutureTask behaviour.
TODO Fine-grained control over underlying jobs, e.g. to ensure anything represented by this task is actually completed,
is not (yet) publicly exposed. See the convenience method blockUntilInternalTasksEnded in the Tasks set of helpers
for more discussion.public boolean cancel(boolean mayInterruptTask,
boolean interruptPrimaryThread,
boolean alsoCancelChildren)
public boolean uncancel()
BasicTaskpublic java.lang.Iterable<Task<?>> getChildren()
getChildren in interface HasTaskChildrenpublic void setFailureHandlingConfig(DynamicSequentialTask.FailureHandlingConfig failureHandlingConfig)
public void swallowChildrenFailures()
TaskQueueingContextswallowChildrenFailures in interface TaskQueueingContextpublic java.util.List<Task<?>> getQueue()
TaskQueueingContextgetQueue in interface TaskQueueingContextpublic void handleException(java.lang.Throwable throwable,
boolean fromChild)
throws java.lang.Exception
java.lang.Exceptionpublic void handleException(java.lang.Throwable throwable)
throws java.lang.Exception
java.lang.Exception@Deprecated public Task<?> last()
TaskQueueingContextlast in interface TaskQueueingContextpublic void drain(Duration optionalTimeout, boolean includePrimary, boolean throwFirstError)
TaskQueueingContextdrain in interface TaskQueueingContextoptionalTimeout - null to run foreverincludePrimary - whether the parent (this context) should also be joined on;
should only be true if invoking this from another task, as otherwise it will be waiting for itself!throwFirstError - whether to throw the first exception encountered
Also note that this waits on tasks so that blocking details on the caller are meaningful.