Tasks
The Content Engine APIs provide task-related classes for coordinating and tracking content-centric workflows, consisting of multiple steps and user roles, such as in claim- and loan-processing applications. A task is a single work item to be completed as part of a process, which might involve multiple related or independent work items.
A single task is represented by a CmTask object. A
CmTask object has a content-based coordinator, such as a Folder,
Document, or CustomObject that associates the task to a business
object in a process. A CmTask object also has a changeable state to reflect the
status of a work item in a process (see Task State
Machine). Typically, a CmTask object drives and responds to state changes
through events and subscriptions.
A CmTask object can have successor and predecessor tasks, which, collectively,
define the order that all tasks run in a process. Predecessor-successor associations are specified
by CmTaskRelationship
objects.
A predecessor task in a task relationship can be either a required task or an alternative task. A successor task can have required predecessors, alternative predecessors, or a mix of both. In order for a successor task to advance, all of its required predecessor tasks must complete, and at least one of its alternative predecessor tasks must also complete.
For example, if task relationships associate successor taskX with required predecessors taskA and taskB and with alternative predecessors taskC and taskD, then taskX can advance when both taskA and taskB are completed, and when either taskC or taskD is completed.
The CmTask class is a base class that does not allow instances. You can create
instances only from a subclass of CmTask. For code
examples, see Working with Task Objects.
Task State Machine
As
shown in the following diagram, CmTask has internal
states, indicating how a task is progressing towards completion.
State changes are made automatically by the Content Engine or
manually by a client. A CmTask object can be promoted (left to right in the
diagram) to a new state, or it can be demoted (right to left) to a previous state. The states are
defined in the TaskState constant class.
Pre- and post-conditions
can be set on a CmTask object, and the conditions
are tested when an attempt is made to manually promote a state. Promotion
fails if the condition evaluates to false.
Manual state changes are started with the changeState (LifecycleChangeFlags flags) method on CmTask. Every state
change, whether manual or automatic, generates a ChangeStateEvent, to
which you can subscribe and configure for auditing. For manual changes, the LifecycleOperation
property of the ChangeStateEvent object directly reflects the flag value that is
given in the changeState method call. For automatic changes, the LifecycleOperation
property is either PROMOTE or DEMOTE, depending on the direction
of the state change.
Each of the states, and the transitions into and out of the states, is described in the following sections.
Waiting (Precondition)
Indicates that the task has yet to satisfy its pre-condition, but is not blocked by any incomplete predecessors. This state is the initial state for all newly created task instances, irrespective of whether the precondition is immediately satisfied, or whether there is a precondition set on the task.
This state can be reentered in the following circumstances:
- From
WAITING_ALL- When the last incomplete predecessor task enters the
COMPLETEstate. - Upon deletion of a task relationship for which this task is the successor, removing the only predecessor constraint that prevents this task from completing.
- Upon creation of a task relationship for which this task is the
successor, where the predecessor task is in the
COMPLETEstate.
- When the last incomplete predecessor task enters the
- From
READY- By a demote operation.
The task can move from this state in the following circumstances:
- To
WAITING_ALL- When a predecessor task moves from
COMPLETEtoWORKINGstate. - Upon deletion of a task relationship for which this task is the
successor, removing an alternative predecessor task that is in the
COMPLETEstate. - Upon creation of a task relationship that specifies this task
as the successor, and the state of the predecessor task is not
COMPLETE.
- When a predecessor task moves from
- To
READY- By a promote operation, subject to the pre-condition being satisfied. (An exception is thrown on an attempted promote if the pre-condition is not satisfied.)
Waiting (All)
Indicates that the task is blocked by both incomplete predecessors and an unsatisfied pre-condition.
This state can be entered in the following circumstances:
- From
WAITING_PRECONDITION- When a predecessor task moves from
COMPLETEtoWORKINGstate. - Upon deletion of a task relationship for which this task is the
successor, removing an alternative predecessor task that is in the
COMPLETEstate. - Upon creation of a task relationship that specifies this task
as the successor, and the state of the predecessor task is not
COMPLETE.
- When a predecessor task moves from
- From
WAITING_PREDECESSORS- By a demote operation.
The task can move from this state in the following circumstances:
- To
WAITING_PRECONDITION- When the last incomplete predecessor task enters
COMPLETEstate. - Upon deletion of a task relationship for which this task is the successor, removing the only predecessor constraint that holds this task back.
- Upon addition of a task relationship for which this task is the
successor, where the predecessor task is in the
COMPLETEstate.
- When the last incomplete predecessor task enters
- To
WAITING_PREDECESSORS- By a promote operation, subject to the pre-condition being satisfied.
Waiting (Predecessors)
Applies when the task has satisfied its precondition but is blocked by incomplete predecessors.
This state can be entered in the following circumstances:
- From
READY- When a predecessor task moves from the
COMPLETEto theWORKINGstate. - Upon deletion of a task relationship for which this task is the
successor, removing an alternative predecessor task that is in the
COMPLETEstate. - Upon creation of a task relationship that specifies this task
as the successor, and the state of the predecessor task is not
COMPLETE.
- When a predecessor task moves from the
- From
WAITING_ALL- By a promote operation, subject to the pre-condition being satisfied. (An exception is thrown on an attempted promote if the pre-condition is not satisfied.)
The task can move from this state in the following circumstances:
- To
READY- When the last incomplete predecessor task enters the
COMPLETEstate. - Upon deletion of a task relationship for which this task is the successor, removing the only predecessor constraint that holds this task back.
- Upon addition of a task relationship for which this task is the
successor, where the predecessor task is in the
COMPLETEstate.
- When the last incomplete predecessor task enters the
- To
WAITING_ALL- By a demote operation.
Ready
Indicates that the task is no longer blocked either by incomplete predecessors or by a pre-condition, and, therefore, it is ready to be worked on.
This state can be entered in the following circumstances:
- From
WAITING_PREDECESSORS- When the last incomplete predecessor task enters the
COMPLETEstate. - Upon deletion of a task relationship for which this task is the successor, removing the only predecessor constraint that holds this task back.
- Upon addition of a task relationship for which this task is the
successor, where the predecessor task is in the
COMPLETEstate.
- When the last incomplete predecessor task enters the
- From
WAITING_PRECONDITION- By a promote operation, subject to the pre-condition being satisfied.
- From
WORKING- By a demote operation.
The task can move from this state in the following circumstances:
- To
WAITING_PREDECESSORS- When a predecessor task moves from the
COMPLETEstate to theWORKINGstate. - Upon deletion of a task relationship for which this task is the
successor, removing an alternative predecessor task that is in the
COMPLETEstate. - Upon creation of a task relationship that specifies this task
as the successor, and the state of the predecessor task is not
COMPLETE.
- When a predecessor task moves from the
- To
WAITING_PRECONDITION- By a demote operation.
- To
WORKING- By a promote operation.
Working
Signifies that the task is now being
actively worked on, such as when a workflow is started as a result
of a transition to the WORKING state.
In this
state, an attempt to create a task relationship that specifies this
task as the successor is disallowed unless the state of the predecessor
task for that task relationship is COMPLETE. (Blocking
dependencies cannot be introduced after a task starts.)
This state can be entered in the following circumstances:
- From
READYby a promote. - From
COMPLETEby a demote operation. - From
FAILEDby a clear exception operation.
The task can move from this state in the following circumstances:
- To
READYby a demote operation. - To
COMPLETEby a promote operation. - To
FAILEDby a set exception operation.
Complete
Indicates that the task has successfully completed.
It can be reached only by a promote operation from the WORKING state,
subject to validation of the post-condition. The promote operation
receives an exception if the post-condition is not satisfied, and
the state is unchanged.
A successful transition to COMPLETE might
release successor (dependent) tasks from a WAITING_ALL or WAITING_PREDECESSORS state.
A
task in the COMPLETE state can be moved back to the WORKING state
by a demote operation, but this transition is permitted only if the
task has no successors that have transitioned beyond the READY state. If permitted,
successors in the READY state can be moved to the WAITING_PREDECESSORS state,
and those successors in the WAITING_PRECONDITION state
can be moved to the WAITING_ALL state, which is subject
to the conditions for moving to those states.
In this state,
an attempt to create a task relationship that specifies this task
as the successor is disallowed unless the state of the predecessor
task for that task relationship is COMPLETE.
Failed
Applied
when execution of a task fails for some reason, and is reached only
by a set exception operation from the WORKING state.
If the error condition is resolved, the task can be moved back to WORKING by
a clear exception operation.
In this state, an attempt to create
a task relationship that specifies this task as the successor is disallowed
unless the state of the predecessor task for the task relationship is COMPLETE.