cancel
Showing results for 
Search instead for 
Did you mean: 

Querying to find currently waiting receive tasks

imamchishty
Champ in-the-making
Champ in-the-making
Hi guys,

I've taken this example from the activiti site:

<receiveTask id="waitState" name="wait" />  
 

To continue a process instance that is currently waiting at such a receive task, the runtimeService.signal(executionId) must be called using the id of the execution that arrived in the receive task. The following code snippet shows how this works in practice:

ProcessInstance pi = runtimeService.startProcessInstanceByKey("receiveTask");
Execution execution = runtimeService.createExecutionQuery()
  .processInstanceId(pi.getId())
  .activityId("wait")
  .singleResult();
assertNotNull(execution);

Question
If you don't have access to the activity Id is there anyway to find tasks that are in suspended state? All I have access to is the processInstanceId. Using this I need to signal to the waiting task to continue.
7 REPLIES 7

ryanp
Champ in-the-making
Champ in-the-making
Can you do something like getting a list of tasks for the processInstanceId you have, then looping through and checking their status:


TaskQuery taskQuery = processEngine.getTaskService().createTaskQuery();

List<Task> tasks = taskQuery.processInstanceId(processInstanceId).list();

for (Task task : tasks) {
   if (task.getDelegationState == DelegationState.PENDING) {
      // do stuff
   }
}

maikelnait
Champ in-the-making
Champ in-the-making
I know this was posted a long time ago, but I have actually the same problem.
In my case, we use messages to signal processes waiting in receive tasks.

So we do something like this: (in our case we use CDI injection)


               // retrieve the current execution context of the process Id in the waiting state
  Execution execution = runtimeService.createExecutionQuery()
      .processInstanceId(businessProcess.getProcessInstanceId())
      .messageEventSubscriptionName("continueMessage")
      .singleResult();

In this way, we don't need to know the Activity id,
but we still need to know the name of the message the process is waiting.

Is there any way to even avoid that? ( using Activiti 5.19.0.2 )

Thanks a lot in advance.

jbarrez
Star Contributor
Star Contributor
No, that's not possible. What would be the alternative if you don't want to use the message name?

maikelnait
Champ in-the-making
Champ in-the-making
In our application we want to work in the following way:

1) A user clicks on a button in the UI, starting a BPM Activiti process.
2) When the flow reaches a receive task, (we need input from the user) the UI is updated with a new screen.
    (we don't use user tasks, because we don't use the User concept from Activiti)
3) When the user fills whatever information is needed, he clicks on a button to "continue" the flow.

Steps 2) and 3) may be repeated several times, depending on how many screens the user needs to traverse to complete the flow.
Somehow we are mixing the concepts of page-flow with business-flow, as explained in the article:
http://www.bpm-guide.de/2012/04/04/pageflow-vs-process-flow-and-ui-mediator-pattern

Now the point is, each time the user clicks on a button to "continue" the flow, we cannot just use a "global common" function to ask the current process to just continue, because we need to know either the activity id, or the message id, to get the correct Execution Id, so we can proceed.

At the end, every time a user clicks on a button, we know that the current process for that user is in a "waiting state", persisted in a DB.
And from our understanding, a particular process instance Id can only be in a single waiting state at a particular time, so there should be an API like:
"runtimeService.createExecutionQuery().processInstanceId(businessProcess.getProcessInstanceId()).inWaitingState().singleResult()

Probably this could not work with parallel executions, but in our case we don't use them, so that API would give us the correct Execution Id, without the need to know any particular activity id or message name.

Another thing is that, after getting the Execution Id, we still need to know the message name to resume the process execution waiting in the receive task.  We use messages, because the user can choose basically "continue" or "cancel" options in each step, so we use two different message names to decide which should be the next step in the flow.

To avoid even having to know this, we are also thinking of using a simple "signal" event, -without the need to know the signal name-, and include some execution variables, so depending on the user's choice, the flow would go on different paths based on a gateway.

At the end, we want to simplify the Java part that deals with how to call / continue activiti processes from the presentation layer ( we use JSF for the page-flow design ), and concentrate most of the work in the BPM design itself, so different customers will not need to modify existing java code for the page-flows, (as much as possible), and only work on the "business side" flows.

Of course, not sure if this is possible, because we are just new to Activiti and BPM in general.


I think I have found a way to achieve what I want, with the following Native Execution Query:

runtimeService.createNativeExecutionQuery()
.sql("SELECT * FROM " + mgmtService.getTableName(Execution.class) + " WHERE PROC_INST_ID_ = #{processInstanceId} AND IS_ACTIVE_ = 1" ).parameter("processInstanceId", processInstance.getProcessInstanceId()).singleResult();

The key point is that, in our application we only use SEQUENTIAL processes, not parallel ones, so by knowing the process instance Id, we just need to query the Execution table with the [IS_ACTIVE_ = 1] filter, which always gives us the latest "persisted" Execution of the process, which is our "waiting state", just the one we need to signal to continue.

As long as we don't use parallel flows, does this approach present any caveats or potential problems ?
Thanks a lot !

jbarrez
Star Contributor
Star Contributor
"And from our understanding, a particular process instance Id can only be in a single waiting state at a particular time, so there should be an API like:"

As you said, this does not apply to parallel execution, nor subprocesses and certain other constructs and definitely not for the v6!

It seems you are indeed mixing a few bits. Also, the typical way to do what you want, is to use data (variables) and use exclusive gateways AFTER the receive task/user task, to correlate with buttons from the user.

"The key point is that, in our application we only use SEQUENTIAL processes,"

There are sequential processes that also have more than one execution.

maikelnait
Champ in-the-making
Champ in-the-making
Thanks a lot for the tips!

Currently we are also exploring the usage of User Tasks.

One problem we found while using the previous approach, is that it's hard to chain flows with the "Call Activity" functionality, because different flows will run with different process id's, so after pressing a button, the process id that we stored beforehand may not be the correct one for signaling, if the next receive task belongs to a "called activity" step. Indeed there are many tricky situations.

However, with User Tasks, we don't need to know the process id, even if we chain flows. All we need is to query the pending user tasks with the correct assignee, and ensure we get the one that corresponds to the current page. In this sense, what we need is more related to the original answer… we are going to do some further tests with User Tasks, and see if we can come with an "easy" API for customers to use without too much knowledge of the Activiti internals.

Thanks a lot so far !