Basically, I have a multi-instance subprocess and want to be able to send some kind of signal to the parent process without terminating all other instances of the subprocess.
Please have a look on this sample process:
The subprocess is a multi-instance subprocess with a cardinality of 3.
i.e. when completing UserTask A, three instances of the subprocess are created. The user then needs to complete Task B three times. Fine.
But when the gateway routes to the "throw signal" event, I want the other two instances keep on running! Currently, all instances of the subprocess are terminated as soon as the signal is thrown.
With the help of the signal, I want to create some more instances of the subprocess after visiting UserTask A again.
How can I model this behavior in BPMN / Camunda?
Thanks in advance!
Chris
It is possible to achieve what you want by declaring the boundary catching signal event to be non-interrupting.
(Having said that, from a pure BPMN perspective an escalation event throw/catch would be a better fit for your case, but it is not yet supported by camunda BPM. So, just be careful not to cause side effects with the signal, because the signals may be received by other catching signal events, too.)
Related
I implemented two Flows(Initiating and Responder Flow) that run every X minutes from my Service. They make use of both the send and receive method. When one Node goes down the Flow stays in memory and does not return or throw an Exception. This turns into a problem since after some time the node will crash because too many Flows are running at the same time.
My question is how can i timeout a Flow automatically after X TIME. Or how can i terminate a Flow from the CordApp at all?
Things that i have tried are:
kill flow from RPCOps - no use, since i want to delete it from the Cordapp
kill flow from shell - no use, since i want to delete it in the Code under certain conditions
Make Flow inherit from TimedFlow and set the parameters accordingly - The docs say that this never actually kills the Flow but just restarts it
The fundamental problem you are facing is that there are too many flows running at the same time. If you are using Corda Open Source v4.x, keep in mind that it is single threaded, so if you need to have a several flows running in parallel you should switch to Corda Enterprise, which is multi-threaded.
More specifically about the killing of flows. In your case it seems that the Responder flow has some issues, so causing the Initiating flow to wait forever for a response that never arrives. It is normal behavior. Since the flow is started from the Initiating flow, you need to kill that, you cannot kill the Responder flow from the Initiating one (which is what you are asking in this question).
What you want to do is also theoretically wrong. It would imply that, in a distributed network with Initiating and Responder flows running on two different nodes belonging to two different Organizations, the first one could control the operations of the other. This is not how DLTs/blockchains are supposed to work, it is instead normal in a standard client/server architecture.
The only way to kill the Initiating flow is from either the node terminal or from an external client using CordaRPC.
How to model running multiple tasks/branches in parallel, and wait for just the first one to finish. Then the other (running) branches should be cancelled. To illustrate what I'm asking (what to use instead of the X gateway):
As far as I know, the exclusive gateway's join function is to immediately proceed. It neither stops/cancels the other branches, nor does it stop further executions of the output (so multiple tokens can pass through it).
Is this the answer?
Or perhaps this is even better?
I would do the following:
Starting off from your third diagramme, wrap the tasks ‘a’ and ‘b’ inside your subprocess into another transaction subprocess (but still inside the bigger subprocess that you had already used.
At the boundary of this new sub process as well as the boundary of the task ‘c’, you should add interrupting boundary signal events that lead to a None end event.
After task ‘b’ and ‘c’, add a signal end event. Each of these two signal end events should be caught by the interrupting boundary signal events of the other subprocess or task that you want to stop. So, if task ‘c’ is completed, the signal that is thrown right after that should be caught by the boundary on the transaction subprocess of tasks ‘a’ and ‘b’. The signal end event after ‘b’ should be caught by the boundary event on task ‘c’.
After the bigger subprocess, which contains tasks ‘c’ as well the inner subprocess for ‘a’ and ‘b’, you continue just like in your third diagramme with a merging exclusive gateway and the “Do once” task. I would keep the timer boundary event on the bigger subprocess like you did in your third diagramme.
Here is how this would look like:
However, you could also draw a simpler diagramme with an additional exclusive gateway before the "Do only once" activity that filters out all remaining process instances if that activity has already been carried out. You diagramme would be easier to understand but the process would be slightly different from your requirements: You would allow a situation where activity b will be carried out even though activity c has already been completed. So, instead of cancelling one process instance you would ignore it. Depending on your business context, this might have certain implications.
A third option would be to use a terminate end event instead of a none end event. That way, all remaining process instances will be deleted as soon as the first one reaches the end. However, semantically, that might not be the most elegant solution because a termination is intended to signal that your process has finished abnormally.
I've read the camunda doc, but I don't find anything about it.
I know it doesn't make sense throw something that nobody will catch, but is it possible?
https://docs.camunda.org/manual/7.7/reference/bpmn20/events/signal-events/
https://camunda.com/bpmn/reference/#events-signal
In the Business Process Model And Notation 2.0 specification(can be found at
https://www.omg.org/spec/BPMN/2.0/), P253, in the Table 10.89 - Intermediate Event Types in Normal Flow:
(Signal) This type of Event is used for sending or receiving Signals. A Signal is
for general communication within and across Process levels, across
Pools, and between Business Process Diagrams. A BPMN Signal is
similar to a signal flare that shot into the sky for anyone who might be
interested to notice and then react. Thus, there is a source of the Signal,
but no specific intended target.
Hope that helps.
Yes this is possible. You can model a throwing signal event when there are no receivers. The event will simply throw the signal and continue the normal flow (without anyone ever using the event).
In contrary to that, the catching signal events can not be used without a throwing signal event. If you use a catching signal event without a throwing signal event the process will stop at this event and will never be able to continue.
I have observed that even if i stop a node or a participant by pressing ctr + C, i.e. terminate it...it still shows in the Admin console or 2 minutes or so. Why isnt it immediately derigestered. Is there a way to do so ?
At shutdown of your application, you should clean up the DDS entities, as demonstrated in this piece of example code. In a nutshell, it invokes the following methods:
DDS_DomainParticipant_delete_contained_entities(participant);
DDS_DomainParticipantFactory_delete_participant(DDS_TheParticipantFactory, participant);
If you do not do that, the DDS discovery process will detect by itself after a while that the Participant has gone. The responsiveness of this mechanism is configurable, as explained in the knowledge base article What settings affect DomainParticipant’s liveliness?
Now pressing Ctrl+C normally will not execute the code described above, because the signal will terminate the process right away. As far as I know, the only way to avoid that is to install a signal handler that invokes that clean-up functionality. Here is a gist with some example code on how to install a signal handler: aspyct/signal.c.
I know in BPMN there is just a "start event" for each pool. In my case I have a pool that can begin when a message is caught or because the actor decide to do it by his own decision.
How can I model that? I'm not sure I can use an event-based exclusive XOR.
Maybe a complex gateway?
As stated in many best practice how-tos, it is NOT RECOMMENDED to use multiple start events in a pool. BPMN specification 1.2 contains this note too:
9.3.2.
...
It is RECOMMENDED that
this feature be used sparingly and that
the modeler be aware that other readers of the Diagram may have difficulty
understanding the intent of the Diagram.
...
On the other side, the common rule for the case with omitted start event is
If the Start Event is not used, then all Flow Objects that do not have
an incoming Sequence Flow SHALL be instantiated when the Process is instantiated.
I assume this will be fair enough for the case of manual process start too. Even if the process has only message start event it will be correctly started because Message Start Event is a fair flow object with no incoming sequence flow and thus it complies to the above rule.
However, if you want to be 100% sure the process will go the way you want then the Event Based Exclusive Gateway (which is available since version 1.1) is your choice. Placing it before multiple different start events will make the process choose either of them for start.
Further explanation can be found in this blog.
Unlimited process instances
If you don't mind that during execution of your process the pool could be used multiple times (e. g. once started by a message and 3 times by an actor) then you can simply use multiple start events (BPMN 1.2 PDF Spec 9.3.2 page 37 allows this):
Single instance
If you can only allow a single run of the pool, you might have to instantiate it manually at the start of your execution and then decide whether to use it and when. Here is an example of how this can be done:
The Event-Based Gateway (Spec 9.5.2.4) will "decide" what to do with your pool:
If Actor decides to start or a message comes from the main pool, some actions will take place;
If the process is "sure" that additional pool will not be required, a signal is cast to terminate its instance.