Activiti: [Activiti7] How to proper resume receiveTask?

Created on 12 Nov 2018  Â·  14Comments  Â·  Source: Activiti/Activiti

Hi.

I used receiveTask to wait for some response from other parts of our application. I found in the documentation of previous activiti version example how to resume receiveTask:

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

runtimeService.signal(execution.getId());

Bu in the current version we don't have the signal method. How can I do this in activiti 7? I tried taskRuntime.complete, processRuntime.resume without success.

Edit:
signal is not exposed to the RuntimeService interface. RuntimeServiceImp has this method so:

    ((RuntimeServiceImpl) runtimeService).signal(execution.getId());

works.

question feedback-required risk

All 14 comments

@mkawczynski07 is this not working: https://github.com/Activiti/activiti-api/blob/develop/activiti-api-process-runtime/src/main/java/org/activiti/api/process/runtime/ProcessRuntime.java#L109 ?

I would recommend to use the new ProcessRuntime & TaskRuntime interfaces from the new API instead of using the old Services. Moving forward we will support the new API to make sure that there is a clear separation between the internals and the user facing APIs.

@salaboy signal method from process runtime doesn't work.

@mkawczynski07 can we create a simple reproducer.. for example: https://github.com/Activiti/activiti-examples/tree/develop/activiti-api-basic-full-example
If you copy that project , add a similar process to the one that you have to demonstrate the problem while calling signal, we can make sure to fix that.

We are currently covering UserTasks, ServiceTasks, Start/End events and Gateways , but I am more than happy to look into Receive Tasks and Signals because they should be working.

If we can reproduce the problem I am sure that we can fix it.

@salaboy
This is very confusing issue about Activiti's spec for Receive Task.
Activiti 's Receive Task is different from the BPMN 2.0 spec and can not be processed by messages.
https://www.activiti.org/userguide/#bpmnReceiveTask

In old Activiti, the API to process Receive Task was provided as @mkawczynski07 reported. This API was not releated to BPMN Signal Event.
https://www.activiti.org/javadocs/org/activiti/engine/runtimeservice#signal-java.lang.String-

Runtimeservice.signal(String executionId)

And, in new Activiti, the API to process Receive Task is not provided.
So, we need to respond somewhat.
Providing old-style API or change Receive Task to apply BPMN 2.0 specifications.

@daisuke-yoshimoto thanks a lot for that detailed explanation.. I will do favour the standard (BPMN semantic) way to deal with signals. We need to solve this in the new API layer in a way that doesn't create confusion.
I wonder why we cannot do that with ProcessRuntime.signal() .. I would expect that ProcessRuntime signal triggers all the executions that are waiting for that signal.. it feels like the old method was exposing the executionId so you can be more concrete, but that leaks the internals which is not allowed in the new API layer. It should be ok to do ProcessRuntime.signal(processInstanceId) to broadcast to all the execution related to a Process Instance?

@salaboy
Sinece Receive Task doesn't create signal subscription.

Signal can only process executions that have signal subscriptions.
Signal subscriptions are generated only for signal events.

Any update on this, ETA?Also since this is not working in Activiti 7 yet, are there in alternate ways I can achieve same (wait for external system and then resume upon callback)?
I am thinking of
1) Signal with scope=processInstance, but not sure again if v7 supports it.
2) ombination of ProcessRuntime.suspend and ProcessRuntime.resume
Any pointers?

Thanks

@bhushanshelke I don't work in the project anymore, but as you can see this was reported 12 Nov 2018 and marked with "risk" so ...

@salaboy thanks for quick response. @daisuke-yoshimoto is there any alternative/workaround to this in v7.0.0.SR1? like suspend resume combination?

@bhushanshelke we found a solution. :)

First, in the diagram, you have to use e.g. IntermediateCatchEvent:

<intermediateCatchEvent id="test-1-callback-event">
   <messageEventDefinition messageRef="callback.test-1" />
</intermediateCatchEvent>

Then from the code, you can send signal like this:

        runtimeService.createExecutionQuery()
                .processInstanceId(processInstanceId)
                .messageEventSubscriptionName(messageName)
                .list()
                .forEach(execution -> {
                    runtimeService.messageEventReceived(messageName, execution.getId());
                });

Where:

  • messageName in this example will be callback.test-1
  • runtimeService is an instance of org.activiti.engine.RuntimeService. If you use spring then you will be able to inject this service.

@marek thank you for looking in this, I did explore the option of
intermediatecachedevent, however perhaps my understanding was not correct
about runtimeservice, the examples I have seen so far for activiti 7, none
of them show that we can use runtimeservice directly. There are other
methods in runtimeservice as well which seems to fit the bill, I think
“trigger” is one of’em, where we can pass executionid, but since my
assumption was v7 design doesn’t mean to use runtimeservice directly hence
did not thought it as solution. Can I then assume that I stand corrected
about my understanding of runtimeservice?

Thanks again for your help,
Bhushan

On Sat, 12 Oct 2019 at 5:05 PM, Marek Kawczyński notifications@github.com
wrote:

@bhushanshelke https://github.com/bhushanshelke we found a solution. :)

First, in the diagram, you have to use e.g. IntermediateCatchEvent:



Then from the code, you can send signal like this:

    runtimeService.createExecutionQuery()
            .processInstanceId(processInstanceId)
            .messageEventSubscriptionName(messageName)
            .list()
            .forEach(execution -> {
                runtimeService.messageEventReceived(messageName, execution.getId());
            });

Where:

  • messageName in this example will be callback.test-1
  • runtimeService is an instance of org.activiti.engine.RuntimeService.
    If you use spring then you will be able to inject this service.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Activiti/Activiti/issues/2152?email_source=notifications&email_token=ALULEC7LSZBZCTKVN3EQ7G3QOGY6LA5CNFSM4GDF3GIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBB5KRA#issuecomment-541316420,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ALULEC6SMW5RHCURZ5BJJILQOGY6LANCNFSM4GDF3GIA
.

>

Bhushan

@mkawczynski07 I have been thinking about solution you guys found, glad it worked for you guys, but from little understanding I have about v7 changes, it doesn't seem correct, especially use of RuntimeService as mentioned above. Have Activiti contributers agreed/confirmed that this is indeed is correct way to achieve this?

It is a workaround but it works. We have to use it because we have to fulfill our requirements.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ryandawsonuk picture ryandawsonuk  Â·  6Comments

salaboy picture salaboy  Â·  5Comments

salaboy picture salaboy  Â·  4Comments

salaboy picture salaboy  Â·  3Comments

bikabdel picture bikabdel  Â·  4Comments