Getting started with messages

Good day,
the question, although may sound like something, for what a typical reaction would be RTFM (it has been day 2 of me reading Camunda’s docs…) is - how do I work with messages?

I still have a long road ahead of me learning Camunda, and this topic, although seems to be simple (according to Niall’s video about Camunda 7 messaging), got me stuck. So please be patient with me.

First of, “what do I want to achieve”. I have a simple A-B-C flow, in which B is a subprocess(or maybe just a set of user tasks). Once the user enters the premises of B, I want to basically start poking the poor thing after some timeout (timeout isn’t static though… want to have a separate model for it). BUT I do want to stop poking once C is reached (basically, terminating the process, which is responsible for the annoy stuff).

I did get suggested to wrap B as a subprocess (cool, like the approach), which would end with Terminate. There I would define a separate subprocess, in which I would define my POKE subprocess.

All seemed well, but then I decided to have a possibility of “please don’t poke me” button. From here the question of Messages came into existence - I want to have a possibility of making a message, which would be treated as a stop signal for the notification subprocess.

After hours of “Sorry Dave, I can’t do that” (Cannot specify a process definition id when correlate a message, except for explicit correlation of a start message. and similar), a good person pointed out that message cannot be instantiated for the process, in which it is expecting it.

This brought up the question of moving the POKE phase into a separate bpmn model (or I could have gotten away with leaving it in the existing one?). And now I need to make thing run using messages?

Would be grateful for advises (and maybe some article with from A to Z examples on how to actually do it…).

Hi @Draakzward

Thanks for the question. Would you be able to upload the modeles that you’ve made? It’ll make it easier to follow and suggest changes.

In the meantime let me try to explain a pattern that might work for you… first by explaining some events in the BPMN standard.

  1. Messages: As you’ve found out messages are designed to be communication between processes or basically coming from outside the scope of the process or leaving the scope of the process. So as you found out these weren’t well suited to what you where trying to do (sorry that this caused you so much frustation, i can imagine how irritating that is. )
  2. Signals: So unlike messages these have no limitations around leaving the scope of the sender, but sadly these are a broadcast, so they would be picked up by mulitple instances at once, so that’s not going to help either sadly.
  3. Conditional events: this might be a winner for you… a conditional event is triggered when a specific condition (usually the value of a process variable) is met as defined by the model so it might say #{vip == true} or something in Camunda 7.

But actually, you might not need an event at all. You might just need a timer and a gateway.
Something like this (I think) would solve the problem. Depending on how the “Stop the Poke” action is taken

1 Like

@Niall thanks for the reply (and for all your work on the tutorials, they have been of most help)

Yes, here is the current model (before I started looking into the messaging question, but it does explain what I wish to achieve)
pingMe_1.bpmn (11.3 KB)

I did start of with the Signals (before getting to the part, that it broadcasts).

Next attempt was with conditions. I start of with a timed non-interacting event, which verifies “ping == off” type of variable value. That one is a possibility, but I do feel like I’m doing things the wrong “workaroundish” way. Plus I would wish to keep the bpmn “main” model as clean as possible (it hasn’t evolved to a matter of using subprocesses and stuff, so its a bit of a mess as it is right now).

So my hopes for now are to make the “PingMe” subprocess a separate entity, something like this
image
(but more mature and with several service tasks and message gateways).

But I can’t seem to make (or I still have much to read about) the message.

I’m currently trying

		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
		                                                       .processDefinitionName("pokeProcess")
		                                                       .active()
		                                                       .latestVersion()
		                                                       .active()
		                                                       .singleResult();
		
		runtimeService.createMessageCorrelation("poke")
//		              .processDefinitionId(processDefinition.getId())
				.correlate();
		              //.correlateWithResult();
	}

But fail to understand how it works. Do I need to deploy a process instance for “pokeProcess” manually or something? If so, is it stand-alone, or is it a child process of my “main” process (from which I made the message)?

When I try going for the .processDefinition(...) I get an exception, stating that it needs to be start message…

Just now, while typing this, I did struck

runtimeService.createMessageCorrelation("poke").processDefinitionId(processDefinition.getId()).correlateStartMessage()

Which seems to have actually started that message based process, but I feel I’m going blind.

@Niall
I think I’ve made it through the “start process by message”. Now I’m stuck on the


NOTE: don’t mind the message name from the screenshot (I am not giving the wrong message in the following code)

Can’t seem to figure out how to address a running process.
I am looking at your old video Tutorial: Messaging with BPMN (Video 7) - YouTube, the part with the “Boundary message”, and I basically can’t find a process, which may be expecting the “poke_stop” message -

		runtimeService.createMessageCorrelation("poke_stop")
//		              .processDefinitionId(processDefinition.getId())
		              .processInstanceVariableEquals("parent", execution.getProcessInstanceId())
		              //.processInstanceBusinessKey(execution.getId()+"nurture")
		              .correlateWithResult();

but get the error:

Cannot correlate message 'poke_stop': No process definition or execution matches the parameters 

I even tried creating the starting message process with a specific business key

      .processInstanceBusinessKey("bkey_"+execution.getBusinessKey())

Still end up with the upper error (and I did verify that the created-by-message-event instances have either the variable or the business key).

Hi @Draakzward

Just to let you know that, i’m just a little busy right now, but I intend to answer in detail as soon as i get some time :slight_smile:

1 Like

@Niall appreciate it. Will be waiting (and trying to figure out what I’m doing wrong)

1 Like

@Niall still hoping to get an answer from you :innocent:

How are the service tasks being executed?
Are they using external tasks or java delegates?

@Niall Java delegate.
This is the code for starting an instance (Camunda 7, btw)

	ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
		                                                       .processDefinitionName("pingModel")
		                                                       .active()
		                                                       .latestVersion()
		                                                       .active()
		                                                       .singleResult();
		
	
		ProcessInstance result = runtimeService.createMessageCorrelation("ping")
		              .processDefinitionId(processDefinition.getId())
		              .processInstanceBusinessKey("child_"+execution.getProcessInstanceId())
		              .setVariable("parent", execution.getProcessInstanceId())
		              .correlateStartMessage();

Alright, so i think i know what your problem is.

So messages will only be delivered if there a token waiting a point where a message is expected and the incoming message matched the correlation criteria.

Waiting is the key here, there’s probably no wait state at PING 2 after the timer is complete the process will end pretty much immediately and when you’re sending in the message, there isn’t any token waiting for it because it’s moves too fast.

@Niall
Had a feeling that it would end up like this. But what would be the correct way of implementing this from a perspective of sending a message to a separate process? And how the “boundary message event” should be implemented then?

It’s hard to say without a specific goal in mind… But if you wanted to get this working, just in order to see the event working.
You could change PING 2 to a user task or use the External Task implementation. Either way it would create a point where the process would be able to wait.

Understood. Thanks. WIll give it a try.

For now will take the “workaround” approach with restarting/stopping the ping process itself.