Monolith process to micro service (HELP)

To me - this makes a lot of sense. The instance that triggers the compensation should be the only one that is compensated. the fact the this compensation is triggered by an interrupting cancel event happens to cancel the remaining instances is a function of the boundary event rather than the compensation itself.

If your goal is the compensate all instances when if a single instance triggers a compensation there might be a better way of doing it. I’ll see what i can come up with.

Thx for the reply.

If your goal is the compensate all instances when if a single instance triggers a compensation there might be a better way of doing it. I’ll see what i can come up with.

My goal is at best to compensate only completed instance in the case of a multi transaction sub process.

This would do the trick:

https://cawemo.com/shares/400f636c-f7e7-4338-b346-65119ab3771a

Let me know if you have any questions.

I wondering if the signal event will be caught by other process instances ? If yes, it’s a big deal :D. I only want the multi instance of the current processes to be compensate. Not for all process instances.

In the example above i’m using an expression as the signal name to ensure that for each instance the signal is unique.

But this of course isn’t obvious from the visual representation. :slight_smile:

In your example, if before the sub process we add a service task with compensation, and the sub process failed, signal is launch, all multi instance are compensate but the task before will not be ? Can you confirm ?

It will only activate compensation tasks within the scope of the sub process. If you had and another task before the sub process it would not be triggered.

Can we catch the signal outside the sub process and compensate the first task. Or this approch is restricted to sub process. If it is, is not the right way for us

If you’d like to trigger other compensations on a global scope it’s a pretty simple change to the model

Edit : I’ve added this change to the Cawemo model in the link above

1 Like

I have strange behavior with this method. My process is the following:

Logs:

(first step) => log ok
(second step) => log ok n°0
(back-end | ShipGoodAdapter) call (Supplier) micro service n° 0
(second step) => log ok n°1
(back-end | ShipGoodAdapter) call (Supplier) micro service n° 1
(second step) => log ok n°2
(back-end | ShipGoodAdapter) call (Supplier) micro service n° 2
(second step) => log ok n°3
(back-end | ShipGoodAdapter) call (Supplier) micro service n° 3
(second step) => log ok n°4
(back-end | ShipGoodAdapter) call (Supplier) micro service n° 4
(second step) => after received task with success:true for n°0
(second step) => after received task with success:true for n°1
(second step) => after received task with success:true for n°2
-------------------
(back-end) send step 2 ship good compensation !!!!
-------------------
(second step) => after received task with success:false for n°3
(second step) => event sub process compensation from signal n°4
(second step) => log compensation n°4
 before all compensation
(first step) => log compensation
(second step) => event sub process compensation from globall compensation n°null
(second step) => event sub process compensation from globall compensation n°null
(second step) => log compensation n°null
(second step) => ship compensation n°null
(second step) => log compensation n°null
(second step) => ship compensation n°null
(second step) => event sub process compensation from globall compensation n°null
(second step) => log compensation n°null
(second step) => ship compensation n°null
(second step) => event sub process compensation from globall compensation n°null
(second step) => log compensation n°null
(second step) => ship compensation n°null
(second step) => event sub process compensation from globall compensation n°null
(second step) => log compensation n°null
(second step) => ship compensation n°null
after all compensation

Signal occur for the item n°3 of the sub process (no compensation is launched) but compensation only for n°4 that is not yet finished. Items n°1, 2, 3 are completed and no compensate :thinking:. Not what i want but it’s understandable.

Plus, the non interrupting signal boundary event is not fired, compensate is fired by the the last compensation of the process, between the log “before all compensation” and “before all compensation”. I’m not sure about understanding the expected behavior with the non interrupting signal boundary event on a multi-instance subprocess with event sub process and compensation…

Plus the compensation order is strange, the first step run before second step (sub process). From what I understand from the documentation, the compensation must be done in the reverse order. Why all the items of the second step are not compensate before the first one ?

I have the project base on the camunda-unittest project, if you need it @Niall .

Can you upload your bpmn process model?

You mean the java project ? Have you a repository, file sharing ?

Just the BPMN file itself should be enough for now.
If you want to put your project somewhere on github that would also be handy.

testProcess4.bpmn (31.3 KB)

public class SmartShipGoodService extends PublishSubscribeAdapter {

    private static Integer count = 0;

    public void execute(final ActivityExecution context) throws Exception {

        addMessageSubscription(context, "Message_shipping");

        System.out.println("(back-end | ShipGoodAdapter) call (Supplier) micro service n° "+context.getVariable("loopCounter"));
    }
}

public class PublishSubscribeAdapter extends AbstractBpmnActivityBehavior {
    
  public void signal(ActivityExecution execution, String signalName, Object signalData) throws Exception {
    leave(execution);
  }
  
  protected void addMessageSubscription(final ActivityExecution context, String eventName) {
    ExecutionEntity executionEntity = (ExecutionEntity)context;
    EventSubscriptionEntity eventSubscriptionEntity = new EventSubscriptionEntity(executionEntity, EventType.MESSAGE);
    eventSubscriptionEntity.setEventName(eventName);
    eventSubscriptionEntity.setActivity(executionEntity.getActivity());
    eventSubscriptionEntity.insert();
  }

}

@Test
  @Deployment(resources = {"testProcess4.bpmn"})
  public void shouldExecuteProcess4() {
    ProcessInstance processInstance = runtimeService().startProcessInstanceByKey("testProcess4");

    List<Execution> messagesShipping = getExecutions(processInstance); // cardinality is 5 for the subprocess
    for (int i = 0; i < messagesShipping.size(); i++) {
      Map<String, Object> variables = new HashMap<String, Object>();
      if (i == 3) { // set i == 30 to avoid sub process signal and arrive to the global compensation
        System.out.println("-------------------");
        System.out.println("(back-end) send step 2 ship good compensation !!!!");
        System.out.println("-------------------");
        variables.put("success", false);
      } else {
        variables.put("success", true);
      }
      // compensate received message added programmatically be SmartShipGoodService
      // some message sending can failed due to sub process signal launch and the compensation already append
      runtimeService().messageEventReceived("Message_shipping", messagesShipping.get(i).getId(), variables);
    }
  }

  private List<Execution> getExecutions(ProcessInstance processInstance) {
    return executionQuery().processInstanceId(processInstance.getId()).messageEventSubscriptionName("Message_shipping").list();
  }

The project is here => https://github.com/jdupont22/camunda-engine-unittest-compensation.git

Use

  @Test
  @Deployment(resources = {"testProcess4.bpmn"})
  public void shouldExecuteProcess4() {

What are your expectations of this construct - seems a bit weird to me

Also - the java class you’re running what are you trying to accomplish with that?

-Niall

When all is good in the subprocess and i want compensate later, with the last step, outside of the subprocess. Imagine the second step is a call to one micro service, but i have 5 like that in my real case. Also, i realized that i need to order myself the compensation inside the subprocess with an event subprocess if not, the compensation was not well ordered.

My use case is to have a multi sub process with tasks (another sub process, service …) before and afters. Plus compensation on all elements. What i’m expecting for the compensation is when:

  1. An error occurs during the loop of one of the sub processes (stop the loop and compensate all completed items) + compensate all tasks before in reverse order
    1.1 Alternative (acceptable if 1. is not possible), wait all items complete (error or success) and compensate all if one is in error without added a variable state (must be a feature from the engine) + compensate all tasks before in reverse order
  2. An error occurs after the sub process (compensate all items of the sub process) + compensate all tasks before in reverse order

Edited

@Niall

Hope my last updated post (just before) and the project help you to understand what i want to accomplish.

Have you find a successul way to do it ?