How to wait for a task completion?

I have a Service Task after a User Task. The Service Task should call a method of a service.

What I want is to wait for Service Task completion after completing the User Task. I would not add anything manually in the service.

I checked TaskService and Task but I have found nothing.

A task remains active until it completes. If you want to wait after any task , you can use Timer Intermediate Catching Event, after completing any task.

Hi @Marco_Sulla,

your use case is not really clear. So you have a user task as the first step in your process, and a service task as the second step?

servicetask

Is the above picture of your process correct? Where do you want to wait in this scenario?

PS: why is this question in the community extensions and osgi section? it should be located in the general Process Engine category

Regards
Michael

Yes, and another User Task to show the result. But I think I solved.

I reason as classical Spring flux: user POST the data, controller call the service, get the result, and redirect to result view.

So I wanted that the controller, after getting the data, will wait for Service Task completion and redirect to result view.

But I don’t need it. I can do a POST controller that returns void, and simply gets the data and put them as process variables, and complete the 1st User Task. Than Service Task will call a method that reads the variables and produces a result, that will be put as process variable too. After that, the User Task will call a controller that takes the result from process and pass it to the view with a redirect.

PS: I don’t know if I’m just doing things in a wrong manner, but I find a simple task, like taking data, processing it and show the result, extremely overcomplicated. If I had to do this in pure Spring, I’ll finished it in 5 minutes. Am I wronging something?

Help please…

I’m not at all sure what you’re trying to achieve or what your question is.

1 Like

I would know if I’m doing it right or if there’s a simpler way to do this. I re-explain it again.

What I want is a simple “Read data” -> “Elaborate data some way” -> “Show the result”.

For this, I created an User Task, Read, that is connected to a Service Task, Elaborate, that is connected to another User Task, Show.

In my concrete implementation, I want simply to sum two numbers and see the result.

In Spring Boot I created the AddNumbersController, that maps the /start URI that simply start the process by key (well, I could generalize it in a ProcessController in a “/start/{key}/{redirectPath}” mapping… well, I’ll do it later).

After starting the process, the page will redirect to a form. When the form is submitted, Add2NumbersController.submit() is invoked. The form data are added to the process variables with runtimeService.setVariable(processId, variableName, variableValue).

Next I query the db for getting Read by key:

public Task getByProcessIdAndTaskKey(String processId, String taskKey) {
    final TaskQuery taskQuery = this.taskService.createTaskQuery();
    
    return taskQuery
        .processInstanceId(processId)
        .taskDefinitionKey(taskKey)
        .active()
        .singleResult();
}

Well, for example, I don’t know if this is the smarter way to do the thing… in theory I should know in some way the current task. I should not query it by key explicitly. No?

Anyway, after that I complete the Read task. This way Elaborate should start. It is linked with an expression to demoTaskService.addNumbers(String processId), that cycle over all process variables, converts them to double and then to BigDecimal and sums them. Yes, there are only two numbers but this way you can add also N numbers in future if you want. Ok, now I’m thinking that is better to put all the numbers to add inside a single Collection process variable…
Anyway, after summing all the numbers, I put the result in a process variable. I do not need to complete the task manually I suppose, since it’s a Service Task, so I didn’t do it.
Next, Show task starts. It has an Execution Listener that at task start fires the expression demoTaskService.showAddNumbersResult(), that redirects to AddNumbersController.showAddNumbersResult(), that gets the result variable, put it on the model and redirect to the HTML template that shows the result. End.

I mean, this simple task musy be done in such a complicated way? Or am I wronging something?

Hi @Marco_Sulla,

The most easy way is to use embedded task forms for the user tasks: User Task Forms | docs.camunda.org and a java delegate implementation for the service task to do the calculation: Service Task | docs.camunda.org.

Then you can run your process with the help of the Camunda Tasklist: Working with Tasklist | docs.camunda.org.

Hope this helps, Ingo

I suppose embedded forms uses the camunda layout. I want to use the HTML and CSS of my site, the basic layouts I created, with my header, footer and menu.

Well, Java delegates seems to me a sort of script. Calling a service method gives you more power and it’s more compliant of how Spring should work (the business logic should be in the Service layer). Furthermore I don’t see it more complicated.

As I said before, I would use my GUI.

So if you want to integrate Camunda in your site, this is the simplest way to do it?

Hi @Marco_Sulla,

of course, there are other ways to reach your goal.

You can either customize the Camunda Webapplication with your logo, colors and stylesheets: https://docs.camunda.org/manual/7.11/webapps/tasklist/configuration/#logo-and-header-color

or you create a new tasklist with the technology of your choice: https://blog.camunda.com/post/2018/02/custom-tasklist-examples/

Similar options are available for service invocation. First think about, which exisiting software do you want to reuse in your processes? With the answer you can choose the way to connect the existing part to the Camunda engine. As JavaDelegates or existing beans? Or with the help of external task workers?

When you want to go with spring services, expressions are useful here: https://docs.camunda.org/manual/7.11/user-guide/process-engine/expression-language/#delegation-code. For example, use ${myBean.myMethod(myParameters)}

Lots of options where you have to choose one of.

Hope this helps, Ingo