camunda / camunda

Distributed Workflow Engine for Microservices Orchestration
https://camunda.com/platform/
3.09k stars 562 forks source link

Camunda 7 scripting - race conditions across process-instances while setting a variable #19249

Open DumboJetEngine opened 2 weeks ago

DumboJetEngine commented 2 weeks ago

Describe the bug

I have a Camunda 7 workflow with a sub-process that accesses parent variables. Specifically, the parent does this in a script task (groovy code):

class Result {
    Boolean canProceed
    String errorMessage
}

Init();

def Init()
{
    def result = execution.hasVariable("result");
    if(result == false)
    {
        result = new Result();
//        execution.removeVariable("result");
        execution.setVariable("result", result);
    }
}

def setError(errorMessage)
{
    Init();
    def result = execution.getVariable("result");
    result.canProceed = false;
    result.errorMessage = errorMessage;
}

def setSuccess()
{
    Init();
    def result = execution.getVariable("result");
    result.canProceed = true;
    result.errorMessage = null;
}

And the sub-process calls the setSuccess() and setError("sth") functions.

The workflow does not contain any user tasks, so once I start a process instance, it executes and it gets done/destroyed, after I get the result variables back.

All is working fine when I call the workflow once at a time. But when I bombard it with parallel calls (each time creating a new process instance), then I get weird errors revolving around variables.

This is the C# code that calls the workflow in parallel (using the latest Camunda.Api.Client nuget package):

var camunda = CamundaClient.Create("http://localhost:8080/engine-rest");
var pd = camunda.ProcessDefinitions.ByKey("name");

var actionNames = new string[] {
    "delete",
    "delete",
    ...
    ...
};

var repetition = 0;
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = 10 };
await Parallel.ForEachAsync(actionNames, parallelOptions, async (actionName, ct) => {
    var result = await PerformAction(actionName: actionName);
});

async Task<Result> PerformAction(string actionName)
{
    var businessKey = $"temp-id:{Guid.NewGuid()}";

    var camundaResult = await pd.StartProcessInstance(new Camunda.Api.Client.ProcessDefinition.StartProcessInstance
    {
        BusinessKey = businessKey,
        Variables =
        {
            { "action", VariableValue.FromObject(new { name = actionName }) },
        },
        WithVariablesInReturn = true,
    });

    var processResultJson = camundaResult.Variables["result"]?.Value as string;
    var result = JsonSerializer.Deserialize<Result>(processResultJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    return result;
}

When MaxDegreeOfParallelism is bigger than 1, I get all kinds of unexpected errors, like:

Here are some stack traces (they were too long to post here): https://mega.nz/file/cR0VSLDA#W1f_a4Xxs6OI0hREfAc1SBwx0nzvDrQb3Jn1qPDoGpE

And here is the workflow file: https://mega.nz/file/NM1kDDxK#zsiqoi-7meHYLV4cYl7Qa9CAmQdtyFAW3aMf4cNAKA0

To Reproduce

Current behavior

When using MaxDegreeOfParallelism = 10 various errors related to setting or getting the variables appear, coming from the execution engine.

Expected behavior

Not getting any error, no matter what degree of parallelism you use, since a process instance is supposed to be isolated from other process instance.

Environment

Additional context


Acceptance Criteria

Definition of Ready - Checklist

For UI changes required to solve the bug:

Implementation

:mag: Root Cause Analysis

:thought_balloon: Proposed Solution

:point_right: Handover Dev to QA

:green_book: Link to the test case

DumboJetEngine commented 1 week ago

Can someone please verify that this is a bug, as I believe it to be? I don't see any documentation that indicates this would fail, but it does. Is there any fix in newer versions?

P.S. : I use camunda-bpm-run-7.21.0 and jdk-17.0.10. And I have customized pretty much nothing. Camunda uses the default H2 database, as far as I understand. Isn't that database a valid production candidate?

gastonpillet01 commented 2 days ago

@DumboJetEngine - This is the issue tracker for Camunda 8. Could you please report it here: https://github.com/camunda/camunda-bpm-platform/issues ?

DumboJetEngine commented 2 days ago

Done: https://github.com/camunda/camunda-bpm-platform/issues/4449

gastonpillet01 commented 2 days ago

[like] Gaston Pillet reacted to your message:


From: DumboJetEngine @.> Sent: Monday, June 24, 2024 1:48:33 PM To: camunda/camunda @.> Cc: Gaston Pillet @.>; Comment @.> Subject: Re: [camunda/camunda] Camunda 7 scripting - race conditions across process-instances while setting a variable (Issue #19249)

Done: camunda/camunda-bpm-platform#4449https://github.com/camunda/camunda-bpm-platform/issues/4449

— Reply to this email directly, view it on GitHubhttps://github.com/camunda/camunda/issues/19249#issuecomment-2186628156, or unsubscribehttps://github.com/notifications/unsubscribe-auth/A3VXOXQLZFMKRIBCGDWZZSTZJAPTDAVCNFSM6AAAAABJDZCLCKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCOBWGYZDQMJVGY. You are receiving this because you commented.Message ID: @.***>