triggerAsync failing in a subprocess

The primary task of the service task is to get variables, replace values with the “runtime” placeholder, then schedule an operation on a remote server without failure.

If the return code is anything but OK, an exception is thrown; if unmanaged: the Activity is marked as “in error” and the job moved to deadletter waiting user action. User action (I’m still completing the task tho -_-’ ) consists in resubmitting the job with or without modifying procInst variables, or just abort it.

That is why this “schedule” operation cannot be done afterCommit since it drives the avtivity status of the previous commit itself.

Maybe if I explain a realcase scenario it would be more easy to get.

Imagine to have a service task that must perform a filecopy and that filecopy is done by an another server. I can’t wait holding the transaction on the service task since if the file is too big it will go timeout.

So:
From the user point of view there’s a flow that just copies a file from A to B then moves to the next step.

From an architectural point of view there is a service task that schedules an operation then the activity is completed, staying in a triggerable state. Once the others subsystem ends that scheduled operation, it fires “events” that the system where the engine lives will receive, and correlate them with the correct ExecutionId and wakes up the FlowInstance again to continue.

In this scenario, I think I’ve nothing available to put in an afterCommit or transaction synchronization. I just need to be “sure” in a time t2, when I’ve received the event completed from the subsystem, that my flow instance is in a state that is ready to be triggered.

I think the point I’ve been missing is that one event emitted by the sending system causes two events to be received, sometimes in very rapid succession. I’m not sure there’s a completely “Flowable” solution to the problem. When the second message comes in, could you evaluate whether the processes is ready and stick the message back on the queue if it is not?

1 Like

That is exactly why I was asking for a “query” to perform with the runtimeService (since in that scenario the only two objects I have are the RuntimeService and the ExecutionID) before executing the trigger API.
In that case, instead of doing the ugliest Thread.sleep() (that actually is even not guaranteed working, it just happens to work on my environment but who knows in distributed ones…) I could just “ask” the engine if that ExecutionID is ready to be triggered and then perform that operation. Otherwise I’ll not ACK the JMS event processing so that the message gets back in queue and will be processed later on, when the engine will be “ready” to receive the trigger.

It looked like you were setting a variable after receiving the first message. If that transaction has not committed yet, a query for the variable will not show its presence/updated value. Perhaps something like this:
runtimeService.createExecutionQuery().executionId("someId").variableExists("someVariable").count();

1 Like

Hey William, thanks.

I’ve made a couple tests but since the idea is rocksolid I cannot manage to get it working. I’m explaining:

since it’s my “end user” modeling my process variables names and I don’t want to mess up with them, I’ve tried something like:

  1. my service task goes with the submission and creates a variable where “variableName == executionID”
  2. when I’m noticed about something I’m querying: runtimeService.createExecutionQuery().executionId(executionId).variableExists(executionId).count();
  3. if found:
    runtimeService.removeVariable(executionId, executionId); runtimeService.trigger(executionId, processVariables);
  4. if NOT found, wait, rinse and repeat.

It should work but it actually isn’t.

As you can see the variable is there (name == 412512) but the query keeps on returning count == 0 so the trigger never happens. ¯_(ツ)_/¯

Is this in the JavaDelegate? if so, you can use execution.getVariable(“412512”), that will check the current transaction cache (the problem is that the data is written at the end of the transaction).

Can you try this in case there is a bug in the query on executions of some other logic issue?
runtimeService.createProcessInstanceQuery().variableValueEquals(executionId, executionId).count();

You can also look in the database at the act_ru_variable table, just to verify that variable has been committed and the execution id is what you expect?

I already tried this one yesterday and with this it works properly. But I think it’s a bit overkill to query all process instances just for that…

Btw yes the variable is there, no need to query the dbtable directly since I can see it’s value from flowable-control already.

Nope.

It’s in a whole different part of the application where I have no servicetasks or delegates all I have is the CDI injected instance of the Runtime service (that’s why I’m using it CDI aware tho)

Control is getting the variables based on the process, my ask was to manually look at the table to verify that the execution_id_ listed for the variable is what you expect. If so, we may need to look for bugs in the execution query. BTW, Flowable deletes runtime instances once they are complete and copied to history, so there shouldn’t be much impact on performance querying process instances.

Uhm good to know it works that way.
Behaving like that with asynchronous history aswell I suppose…

I’ll be out of office a couple of days will hook back here next week…

And what about in that way:
if (runtimeService.hasVariable(executionId,executionId)) && runtimeService.getVariable(executionId, executionId).equals(true))

Hi Javier,
it’s apparently working. I’m trying that on a singlenode cluster, and it’s properly triggering my instances.
I’ll stress test it this afternoon on a 2 node cluster to see how it behave, i’ll keep you posted!

Hi,

confirmed solution to your test, Javier, thanks.

Now the trigger is behind that if you suggested and when it’s false it will be thrown to sleep and then retried for a configurable number of time and times.

Works like a charm. <3