javaspringcamunda

Stateful Camunda 7 ExternalTaskHandler


is the following safe in terms of ExternalTaskHandler instance reuse by the Camunda 7 engine?

public class ExampleTaskHandler implements ExternalTaskHandler {

    private ExternalTask externalTask;
    private VariableMap taskVariables;

    @Override
    public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {
        this.externalTask = externalTask;
        this.taskVariables = new VariableMapImpl();
        try {
            executeTask();
            externalTaskService.complete(externalTask, taskVariables);
        } finally {
            this.externalTask = null;
            this.taskVariables = null;
        }
    }

    private void executeTask() {
        // do stuff and use externalTask and taskVariables
    }

    ...

}

Debugging showed that ExternalTaskHandler instances are being reused/shared between calls. That’s why we null the reference variables in the finally block of execute as a safety measure. Might be overkill.

Are normal instance variables fine or are we advised to use ThreadLocals? Or should we refrain from stateful ExternalTaskHandler implementations altogether? The latter would mean we’d need to pass on stuff in method parameters over and over again, which we would like to avoid.

Thanks for your help!


Solution

  • You are right: Handlers are reusable instances, most likely singleton, and thus must not contain state.

    To your solution: Though it might work, this is a very error prone solution. And hard to read. If your goal is to avoid passing of parameters to private functions, consider two different approaches: