Define retries on external task in Camunda Modeler

Is it possible to define the desired number of retries for an external task within the BPMN - that is within Camunda Modeler? If so how - an extended property setting perhaps?

thanks!

@ddrouin you can set reties for external task retries through REST api like below:

POST /external-task/retries-async
Request Body:

{
  "retries": 123
  "externalTaskIds": [
    "anExternalTask",
    "anotherExternalTask"
  ]
}

Refer this link.

That’s unfortunate as we’d like to define the retry counts declaratively when creating the bpmn steps. Without this things get ambiguous.

Consider when an external step is launched, retries will be 0 as it cannot be set in the BPMN. So we could programmatically set it to say 3.
Failure 1: 3 retries remain so re-enable step and retries becomes 2
Failure 2: 2 retries remain so re-enable step and retries becomes 1
Failure 3: 1 retry remains so re-enable step and retries becomes 0

So on that last retry, we fetch and lock and see that retries is 0. Hmm set it to 3? No we should not but how do we know not to? That’s why having it defined as 3 at the outset - no setting it at runtime - would be great. It would also enable setting different retries per step.

while modeling your bpmn, camunda modeler doesn’t provide the number of job retries for external tasks, because external tasks are executed out of the engine like workers(camunda-external-task-client) and the state will be committed to process engine by the external task workers. Job retries for external tasks are configured during execution time only.

So you can configure the external task retries in the workers implementation and its valid approach. You can only configure job retires for tasks in the bpmn model which is executed within the process engine.

You can configure retry for external task job retry like below code snippet:

List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")
  .topic("AddressValidation", 60L * 1000L).variables("address")
  .execute();

LockedExternalTask task = tasks.get(0);

// ... processing the task fails

externalTaskService.handleFailure(
  task.getId(),
  "externalWorkerId",
  "Address could not be validated: Address database not reachable",     // errorMessage
  "Super long error details",                                           // errorDetails
  1,                                                                    // retries
  10L * 60L * 1000L);                                                   // retryTimeout

// ... other activities

externalTaskService.getExternalTaskErrorDetails(task.getId());

For more details refer the external-tasks retry jobs

1 Like

ddrouin you can set retries in external worker:

class Worker implements ExternalTaskHandler {
    private final static int DEFAULT_RETRIES_NO = 3;
    private final static int RETRY_TIMEOUT = 5_000;

    @Override
    public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {
        try {
            // someLogic
        } catch (SomeException e) {
            externalTaskService.handleFailure(
                    externalTask,
                    getExceptionMessage(e),
                    getExceptionDetails(e),
                    calculateRetries(externalTask.getRetries()),
                    RETRY_TIMEOUT);
        }
    }
    
    private int calculateRetries(int taskRetries) {
        if (taskRetries == null) { // initially task.retries is null
            return DEFAULT_RETRIES_NO;
        }
        return task.getRetries() - 1;
    }
}