Task instances

A task instance can be assigned to an actorId (java.lang.String). All task instances are stored in one table of the database (JBPM_TASKINSTANCE). By querying this table for all task instances for a given actorId, you get the task list for that perticular user.

The jBPM task list mechanism can combine jBPM tasks with other tasks, even when those tasks are unrelated to a process execution. That way jBPM developers can easily combine jBPM-process-tasks with tasks of other applications in one centralized task-list-repository.

Task instance lifecycle

The task instance lifecycle is straightforward: After creation, task instances can optionally be started. Then, task instances can be ended, which means that the task instance is marked as completed.

Note that for flexibility, assignment is not part of the life cycle. So task instances can be assigned or not assigned. Task instance assignment does not have an influence on the task instance life cycle.

Task instances are typically created by the process execution entering a task-node (with the method TaskMgmtInstance.createTaskInstance(...)). Then, a user interface component will query the database for the tasklists using the TaskMgmtSession.findTaskInstancesByActorId(...). Then, after collecting input from the user, the UI component calls TaskInstance.assign(String), TaskInstance.start() or TaskInstance.end(...).

A task instance maintains it's state by means of date-properties : create, start and end. Those properties can be accessed by their respective getters on the TaskInstance.

Currently, completed task instances are marked with an end date so that they are not fetched with subsequent queries for tasks lists. But they remain in the JBPM_TASKINSTANCE table.

Task instances and graph execution

Task instances are the items in an actor's tasklist. Task instances can be signalling. A signalling task instance is a task instance that, when completed, can send a signal to its token to continue the process execution. Task instances can be blocking, meaning that the related token (=path of execution) is not allowed to leave the task-node before the task instance is completed. By default task instances are signalling and non-blocking.

In case more than one task instance are associated with a task-node, the process developer can specify how completion of the task instances affects continuation of the process. Following is the list of values that can be given to the signal-property of a task-node.

  • last: This is the default. Proceeds execution when the last task instance is completed. When no tasks are created on entrance of this node, execution is continued.
  • last-wait: Proceeds execution when the last task instance is completed. When no tasks are created on entrance of this node, execution waits in the task node till tasks are created.
  • first: Proceeds execution when the first task instance is completed. When no tasks are created on entrance of this node, execution is continued.
  • first-wait: Proceeds execution when the first task instance is completed. When no tasks are created on entrance of this node, execution waits in the task node till tasks are created.
  • unsynchronized: Execution always continues, regardless wether tasks are created or still unfinished.
  • never: Execution never continues, regardless wether tasks are created or still unfinished.

Task instance creation might be based upon a runtime calculation. In that case, add an ActionHandler on the node-enter event of the task-node and set the attribute create-tasks="false". Here is an example of such an action handler implementation:

public class CreateTasks implements ActionHandler {
  public void execute(ExecutionContext executionContext) throws Exception {
    Token token = executionContext.getToken();
    TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();
      
    TaskNode taskNode = (TaskNode) executionContext.getNode();
    Task changeNappy = taskNode.getTask("change nappy");

    // now, 2 task instances are created for the same task.
    tmi.createTaskInstance(changeNappy, token);
    tmi.createTaskInstance(changeNappy, token);
  }
}

As shown in the example the tasks to be created can be specified in the task-node. They could also be specified in the process-definition and fetched from the TaskMgmtDefinition. TaskMgmtDefinition extends the ProcessDefinition with task management information.

The API method for marking task instances as completed is TaskInstance.end(). Optionally, you can specify a transition in the end method. In case the completion of this task instance triggers continuation of the execution, the task-node is left over the specified transition.