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.TaskFinalizer
description, 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, toString
asTask
public 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)
TaskQueueingContext
implementations 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 TaskQueueingContext
public boolean cancel(boolean mayInterruptIfRunning)
Task
Future.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()
BasicTask
public java.lang.Iterable<Task<?>> getChildren()
getChildren
in interface HasTaskChildren
public void setFailureHandlingConfig(DynamicSequentialTask.FailureHandlingConfig failureHandlingConfig)
public void swallowChildrenFailures()
TaskQueueingContext
swallowChildrenFailures
in interface TaskQueueingContext
public java.util.List<Task<?>> getQueue()
TaskQueueingContext
getQueue
in interface TaskQueueingContext
public void handleException(java.lang.Throwable throwable, boolean fromChild) throws java.lang.Exception
java.lang.Exception
public void handleException(java.lang.Throwable throwable) throws java.lang.Exception
java.lang.Exception
@Deprecated public Task<?> last()
TaskQueueingContext
last
in interface TaskQueueingContext
public void drain(Duration optionalTimeout, boolean includePrimary, boolean throwFirstError)
TaskQueueingContext
drain
in interface TaskQueueingContext
optionalTimeout
- 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.