Version6.8.1,about performance of task.complete

Hello, I’ve created a simple workflow using the framework. After starting the process, it enters a ServiceTask where I use FutureJavaDelegate to send a request to a third party. Then it uses a UserTask to asynchronously receive the response (here it’s a POST interface that completes the task using task.complete). After that, there’s another ServiceTask where I use FutureJavaDelegate to insert data into the database. I simulated the response to test the performance of this POST interface and found it only reaches around 167 TPS, which I cannot improve no matter what. After investigation, I discovered the bottleneck is at task.complete, but I cannot improve it regardless of how I modify it. The Flowable version is 6.8.1, the server is 2C4G, and MySQL is 8.0

here is how i set servicetask and usertask:

ServiceTask serviceTask = new ServiceTask();
serviceTask.setId(id0);
serviceTask.setName(param.getModulerName());
serviceTask.setImplementation("${" + param.getDelegateMethod() + "}");
serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);

UserTask userTask = new UserTask();
userTask.setId(id1);
userTask.setName(param.getModulerName());

process.addFlowElement(serviceTask);
process.addFlowElement(userTask);

i also set pool like:

private void configureAsyncExecutor(SpringProcessEngineConfiguration configuration) {
    configuration.setAsyncExecutorCorePoolSize(20);

    configuration.setAsyncExecutorMaxPoolSize(300);

    configuration.setAsyncExecutorThreadKeepAliveTime(300000);

    configuration.setAsyncExecutorThreadPoolQueueSize(1000);
}

PS: I’m not sure if using UserTask this way is correct. My goal is to have the process pause at a node and wait for an external response to determine which branch the process should take next or whether it should end. Or perhaps I shouldn’t use UserTask but should use another flowable function to achieve this.

the core and max pool size should be set to the same value - the JVM has a weird setting that it only starts to add more threads once the queue is full (which is 1000 for you).

However, if you’re using Spring Boot, make sure to use the right properties: have a look at this recent forum post: Flowable 7.2.0: Node Affinity Hoards All Jobs – All Async Jobs Locked by Node 1 while only 8 are being processed - #10 by ROY

1 Like

Hey @jeffreylee,

To add to what Joram is saying. You are saying that you are using FutureJavaDelegate. That doesn’t mean that things would be faster. Using that would make sense only when you are using parallel gateways, are you using that?

In any case, if you have something like “User Task” → “Service Task 1” → “Service Task 2” → “End” (or any other wait state). Then the task.complete performance will depend on how long it takes to complete Service Task 1 and Service Task 2 combined. Considering the fact that you are sending a request to a third part, I would say that the bottleneck is in that 3rd party call. Usually, network calls are the “slowest”.

Not sure what you are trying to optimize, if you are trying to return faster to the user. You can explore with using the async flag on the “Service Task 1”. Have a look at:

Most likely a user task is not the right way for this. I would explore the Event Registry for this, not sure how you are receiving the response from an external response.

Cheers,
Filip

1 Like

thank you, I tried various suggestions provided by Copilot, and replacing the UserTask with a ReceiveTask allowed me to achieve the desired concurrency. The AI model advised that UserTask is designed for scenarios like manual approval. For cases like mine, where an automatic response from a third party is expected, it is better to use a ReceiveTask and trigger the process continuation using runtimeService.trigger(). This approach can significantly reduce MySQL overhead and transaction costs.