Skip to Content
BPMN ElementsTasksService Task

Service Task

A service task delegates work to an external worker process. Workers subscribe by topic and use long-polling to fetch and lock tasks.

<serviceTask id="validatePayment" name="Validate Payment" activiti:type="external" activiti:topic="validatePayment" />

Execution behavior

When the engine reaches a service task it:

  1. Sets the instance state to WaitingForTask
  2. Records a task row in the database with state = CREATED
  3. Pauses — no further progress until a worker completes the task

Fetch and lock protocol

Workers call POST /api/external-tasks/fetch-and-lock:

{ "workerId": "payment-worker-1", "maxTasks": 10, "lockDurationMs": 30000, "requestTimeoutMs": 20000, "subscriptions": [ { "topic": "validatePayment" } ] }

The server assigns tasks using FOR UPDATE SKIP LOCKED to prevent double-claiming. Tasks are returned in FIFO order by creation time.

  • lockDurationMs — how long the worker has exclusive ownership before the task can be re-claimed by another worker
  • requestTimeoutMs — server holds the request open (long-polling) and returns as soon as tasks are available, or after the timeout if none appear
  • subscriptions[].processDefinitionIds — optional; omit to receive tasks from any process definition

Completing a task

Call POST /api/external-tasks/{id}/complete:

{ "workerId": "payment-worker-1", "variables": { "paymentValid": true, "chargeId": "ch_abc123" } }

Output variables are merged into the instance’s variable scope. Existing variables with the same name are overwritten.

The lock must not be expired at completion time. For long-running tasks, extend it proactively with POST /api/external-tasks/{id}/extend-lock.

Failing a task

Call POST /api/external-tasks/{id}/fail:

{ "workerId": "payment-worker-1", "errorMessage": "Payment gateway timeout", "retries": 2, "retryTimeoutMs": 5000 }
  • If retries > 0: the task is reset to CREATED and re-enters the pool after retryTimeoutMs milliseconds
  • If retries = 0: the task is marked FAILED. The engine looks for an error boundary event or error event subprocess on the service task. If neither is found, the entire process instance is marked FAILED
Last updated on