paed01 / bpmn-engine

BPMN 2.0 execution engine. Open source javascript workflow engine.
MIT License
874 stars 167 forks source link

Parallel Join stuck in postponed state #125

Closed mdwheele closed 3 years ago

mdwheele commented 3 years ago

Hello!

ℹ️ There is a high probability that I am doing something wrong here, so please feel free to say "You're doing this wrong" and I'll do my best to explain my goals! I'm trying to learn the library (thanks for all the hard work, by the way!).

image

I have a fairly simple Process Definition with two parallel User Tasks that, upon completion, end the Process.

BPMN Process Definition ```xml Flow_0817cno Flow_0817cno Flow_1fq2v93 Flow_0slt4s3 Flow_16cbds7 Flow_02qgtms Flow_1wsx714 Flow_1fq2v93 Flow_16cbds7 Flow_0slt4s3 Flow_02qgtms Flow_1wsx714 ```

My goal is to be able to start Processes using this definition and persist their state between API/CLI calls (which is a challenge for me in and of itself, but I think I'm doing it right). Currently, in my proof of concept, I am simply persisting Engine state to JSON files named by Process ID.

I have command-lets to start, provide input and tick an Engine. The expectation with this process is that I will start, receive a Process ID (references the stored state) and then use that PID to provide input to specific tasks (A and B) and the last tick would show a completed process (state should be idle).

Starting a process

$ bin/pocky.ts start src/resources/parallel.bpmn 
a1014e01-a76b-4b1c-b95f-017a96263a2c
export async function Start(path: string) {
  const pid = uuid()
  const source = fs.readFileSync(path).toString()

  const engine = Engine({ name: pid, source })

  const execution = await engine.execute()
  execution.stop()

  save(execution.getState())
  console.log(pid)
}

The save function basically just JSON.stringify the BpmnEngineExecutionState and saves that to a file named after the PID. load does the reverse by JSON.parse the value on disk and returning Engine().recover(state).

"Ticking" to see current state

$ bin/pocky.ts tick a1014e01-a76b-4b1c-b95f-017a96263a2c
State: running
Status: There are 2 waiting tasks [A, B] on a1014e01-a76b-4b1c-b95f-017a96263a2c
export async function Tick(pid: string) {
  const engine = load(pid)

  const execution = await engine.resume()

  const waiting = execution.getPostponed()

  console.log(`State: ${execution.state}`)

  execution.stop()

  console.log(`Status: There are ${waiting.length} waiting tasks [${waiting.map(task => task.name).sort().join(', ')}] on ${execution.name}`)
  save(execution.getState())
}

This function ultimately gives us some logging on how many tasks are waiting but also runs the Process as far as it will go before stopping and saving state to disk.

Providing User Input

$ bin/pocky.ts input a1014e01-a76b-4b1c-b95f-017a96263a2c A
Sent input to task A in a1014e01-a76b-4b1c-b95f-017a96263a2c
export async function Input(pid: string, task: string, input: string) {
  const engine = load(pid)

  const execution = await engine.resume()

  execution.signal({ 
    id: task
  })

  execution.stop()

  save(execution.getState())
  console.log(`Sent input to task ${task} in ${execution.name}`)
}

Now... once I provide input to both A and B, I expect that there would be know postponed tasks and that the process would report idle (effectively, ended). However, this is what we see:

$ bin/pocky.ts input a1014e01-a76b-4b1c-b95f-017a96263a2c B
Sent input to task B in a1014e01-a76b-4b1c-b95f-017a96263a2c

$ bin/pocky.ts tick a1014e01-a76b-4b1c-b95f-017a96263a2c
State: running
Status: There are 1 waiting tasks [JOIN] on a1014e01-a76b-4b1c-b95f-017a96263a2c

I've tried sending signals to Gateway_1rh6556 (named JOIN) manually even though I don't think I'm supposed to have to do this.

The final Engine state is here:

Final "Stuck" State ```json { "name": "a1014e01-a76b-4b1c-b95f-017a96263a2c", "state": "stopped", "stopped": true, "engineVersion": "11.3.1", "environment": { "settings": {}, "variables": {}, "output": {} }, "definitions": [ { "id": "Definitions_0wxa0mr", "type": "bpmn:Definitions", "executionId": "Definitions_0wxa0mr_3aac2ba6", "status": "executing", "stopped": false, "counters": { "completed": 0, "discarded": 0 }, "environment": { "settings": {}, "variables": { "fields": { "routingKey": "run.execute", "exchange": "run", "redelivered": true, "consumerTag": "_process-run" }, "content": { "id": "first-come-first-serve", "type": "bpmn:Process", "parent": { "id": "Definitions_0wxa0mr", "type": "bpmn:Definitions" }, "executionId": "first-come-first-serve_204655f0" }, "properties": { "messageId": "smq.mid-69ff18", "timestamp": 1610661312646 } }, "output": {} }, "execution": { "executionId": "Definitions_0wxa0mr_3aac2ba6", "stopped": true, "completed": false, "status": "executing", "processes": [ { "id": "first-come-first-serve", "type": "bpmn:Process", "parent": { "id": "Definitions_0wxa0mr", "type": "bpmn:Definitions" }, "executionId": "first-come-first-serve_204655f0", "status": "executing", "stopped": true, "counters": { "completed": 0, "discarded": 0, "terminated": 0 }, "broker": { "exchanges": [ { "name": "run", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "run-q" } ] }, { "name": "format", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "format-run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "format-run-q" } ] }, { "name": "execution", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "execution-q/execution.#", "options": { "priority": 0 }, "pattern": "execution.#", "queueName": "execution-q" } ] } ], "queues": [ { "name": "run-q", "options": { "autoDelete": false, "durable": true }, "messages": [ { "fields": { "routingKey": "run.execute", "exchange": "run", "redelivered": true }, "content": { "id": "first-come-first-serve", "type": "bpmn:Process", "parent": { "id": "Definitions_0wxa0mr", "type": "bpmn:Definitions" }, "executionId": "first-come-first-serve_204655f0" }, "properties": { "messageId": "smq.mid-69ff18", "timestamp": 1610661312646 } }, { "fields": { "routingKey": "run.resume", "exchange": "run" }, "content": { "id": "first-come-first-serve", "type": "bpmn:Process", "parent": { "id": "Definitions_0wxa0mr", "type": "bpmn:Definitions" }, "executionId": "first-come-first-serve_204655f0" }, "properties": { "persistent": false, "messageId": "smq.mid-312793", "timestamp": 1610661900440 } } ], "messageCount": 2 }, { "name": "format-run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execution-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execute-first-come-first-serve_204655f0-q", "options": { "autoDelete": false, "durable": true }, "messages": [ { "fields": { "routingKey": "activity.init", "exchange": "event", "redelivered": true }, "content": { "inbound": [ { "action": "take", "id": "Flow_16cbds7", "sequenceId": "Flow_16cbds7_take_2d70f98d", "type": "bpmn:SequenceFlow", "sourceId": "A", "targetId": "Gateway_1rh6556", "isSequenceFlow": true, "parent": { "id": "first-come-first-serve", "type": "bpmn:Process" } } ], "executionId": "Gateway_1rh6556_19d000c4", "id": "Gateway_1rh6556", "type": "bpmn:ParallelGateway", "name": "JOIN", "parent": { "id": "first-come-first-serve", "type": "bpmn:Process", "executionId": "first-come-first-serve_204655f0" }, "state": "init" }, "properties": { "persistent": true, "type": "init", "mandatory": false, "messageId": "smq.mid-797215", "timestamp": 1610661741128 } } ], "messageCount": 1 } ] }, "execution": { "executionId": "first-come-first-serve_204655f0", "stopped": true, "completed": false, "status": "executing", "children": [ { "id": "Event_10vtlbf", "type": "bpmn:StartEvent", "name": "START", "parent": { "id": "first-come-first-serve", "type": "bpmn:Process" }, "isStart": true, "executionId": "Event_10vtlbf_21eaae62", "stopped": false, "behaviour": { "$type": "bpmn:StartEvent", "id": "Event_10vtlbf", "name": "START" }, "counters": { "taken": 1, "discarded": 0 }, "broker": { "exchanges": [ { "name": "run", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "run-q" } ] }, { "name": "format", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "format-run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "format-run-q" } ] }, { "name": "execution", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "execution-q/execution.#", "options": { "priority": 0 }, "pattern": "execution.#", "queueName": "execution-q" } ] } ], "queues": [ { "name": "run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "format-run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execution-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "inbound-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execute-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 } ] }, "execution": { "completed": true } }, { "id": "Gateway_01zwbav", "type": "bpmn:ParallelGateway", "name": "FORK", "parent": { "id": "first-come-first-serve", "type": "bpmn:Process" }, "executionId": "Gateway_01zwbav_276776dc", "stopped": false, "behaviour": { "$type": "bpmn:ParallelGateway", "id": "Gateway_01zwbav", "name": "FORK" }, "counters": { "taken": 1, "discarded": 0 }, "broker": { "exchanges": [ { "name": "run", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "run-q" } ] }, { "name": "format", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "format-run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "format-run-q" } ] }, { "name": "execution", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "execution-q/execution.#", "options": { "priority": 0 }, "pattern": "execution.#", "queueName": "execution-q" } ] } ], "queues": [ { "name": "run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "format-run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execution-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "inbound-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execute-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 } ] }, "execution": { "completed": true } }, { "id": "Gateway_1rh6556", "type": "bpmn:ParallelGateway", "name": "JOIN", "parent": { "id": "first-come-first-serve", "type": "bpmn:Process" }, "executionId": "Gateway_1rh6556_342aa127", "stopped": false, "behaviour": { "$type": "bpmn:ParallelGateway", "id": "Gateway_1rh6556", "name": "JOIN" }, "counters": { "taken": 1, "discarded": 0 }, "broker": { "exchanges": [ { "name": "run", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "run-q" } ] }, { "name": "format", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "format-run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "format-run-q" } ] }, { "name": "execution", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "execution-q/execution.#", "options": { "priority": 0 }, "pattern": "execution.#", "queueName": "execution-q" } ] } ], "queues": [ { "name": "run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "format-run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execution-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "inbound-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execute-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 } ] }, "execution": { "completed": true } }, { "id": "A", "type": "bpmn:UserTask", "name": "A", "parent": { "id": "first-come-first-serve", "type": "bpmn:Process" }, "executionId": "A_303526ec", "stopped": false, "behaviour": { "$type": "bpmn:UserTask", "id": "A", "name": "A" }, "counters": { "taken": 2, "discarded": 0 }, "broker": { "exchanges": [ { "name": "run", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "run-q" } ] }, { "name": "format", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "format-run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "format-run-q" } ] }, { "name": "execution", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "execution-q/execution.#", "options": { "priority": 0 }, "pattern": "execution.#", "queueName": "execution-q" } ] } ], "queues": [ { "name": "run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "format-run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execution-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "inbound-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execute-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 } ] }, "execution": { "completed": true } }, { "id": "B", "type": "bpmn:UserTask", "name": "B", "parent": { "id": "first-come-first-serve", "type": "bpmn:Process" }, "executionId": "B_161e57df", "stopped": false, "behaviour": { "$type": "bpmn:UserTask", "id": "B", "name": "B" }, "counters": { "taken": 1, "discarded": 0 }, "broker": { "exchanges": [ { "name": "run", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "run-q" } ] }, { "name": "format", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "format-run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "format-run-q" } ] }, { "name": "execution", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "execution-q/execution.#", "options": { "priority": 0 }, "pattern": "execution.#", "queueName": "execution-q" } ] } ], "queues": [ { "name": "run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "format-run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execution-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "inbound-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execute-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 } ] }, "execution": { "completed": true } }, { "id": "Event_1brbwtj", "type": "bpmn:EndEvent", "parent": { "id": "first-come-first-serve", "type": "bpmn:Process" }, "isEnd": true, "executionId": "Event_1brbwtj_2088753c", "stopped": false, "behaviour": { "$type": "bpmn:EndEvent", "id": "Event_1brbwtj" }, "counters": { "taken": 1, "discarded": 0 }, "broker": { "exchanges": [ { "name": "run", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "run-q" } ] }, { "name": "format", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "format-run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "format-run-q" } ] }, { "name": "execution", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "execution-q/execution.#", "options": { "priority": 0 }, "pattern": "execution.#", "queueName": "execution-q" } ] } ], "queues": [ { "name": "run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "format-run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execution-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "inbound-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execute-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 } ] }, "execution": { "completed": true } } ], "flows": [ { "id": "Flow_0817cno", "type": "bpmn:SequenceFlow", "sourceId": "Event_10vtlbf", "targetId": "Gateway_01zwbav", "counters": { "looped": 0, "take": 1, "discard": 0 }, "broker": { "exchanges": [ { "name": "event", "type": "topic", "options": { "durable": true, "autoDelete": false, "prefix": "flow" }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 } } ] } }, { "id": "Flow_1fq2v93", "type": "bpmn:SequenceFlow", "sourceId": "Gateway_01zwbav", "targetId": "A", "counters": { "looped": 0, "take": 1, "discard": 0 }, "broker": { "exchanges": [ { "name": "event", "type": "topic", "options": { "durable": true, "autoDelete": false, "prefix": "flow" }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 } } ] } }, { "id": "Flow_0slt4s3", "type": "bpmn:SequenceFlow", "sourceId": "Gateway_01zwbav", "targetId": "B", "counters": { "looped": 0, "take": 1, "discard": 0 }, "broker": { "exchanges": [ { "name": "event", "type": "topic", "options": { "durable": true, "autoDelete": false, "prefix": "flow" }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 } } ] } }, { "id": "Flow_16cbds7", "type": "bpmn:SequenceFlow", "sourceId": "A", "targetId": "Gateway_1rh6556", "counters": { "looped": 0, "take": 2, "discard": 0 }, "broker": { "exchanges": [ { "name": "event", "type": "topic", "options": { "durable": true, "autoDelete": false, "prefix": "flow" }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 } } ] } }, { "id": "Flow_02qgtms", "type": "bpmn:SequenceFlow", "sourceId": "B", "targetId": "Gateway_1rh6556", "counters": { "looped": 0, "take": 1, "discard": 0 }, "broker": { "exchanges": [ { "name": "event", "type": "topic", "options": { "durable": true, "autoDelete": false, "prefix": "flow" }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 } } ] } }, { "id": "Flow_1wsx714", "type": "bpmn:SequenceFlow", "sourceId": "Gateway_1rh6556", "targetId": "Event_1brbwtj", "counters": { "looped": 0, "take": 1, "discard": 0 }, "broker": { "exchanges": [ { "name": "event", "type": "topic", "options": { "durable": true, "autoDelete": false, "prefix": "flow" }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 } } ] } } ], "messageFlows": [], "associations": [] } } ] }, "broker": { "exchanges": [ { "name": "run", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "run-q" } ] }, { "name": "format", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "format-run-q/run.#", "options": { "priority": 0 }, "pattern": "run.#", "queueName": "format-run-q" } ] }, { "name": "execution", "type": "topic", "options": { "durable": true, "autoDelete": false }, "deliveryQueue": { "name": "delivery-q", "options": { "autoDelete": true }, "messages": [], "messageCount": 0 }, "bindings": [ { "id": "execution-q/execution.#", "options": { "priority": 0 }, "pattern": "execution.#", "queueName": "execution-q" } ] } ], "queues": [ { "name": "run-q", "options": { "autoDelete": false, "durable": true }, "messages": [ { "fields": { "routingKey": "run.execute", "exchange": "run", "redelivered": true }, "content": { "id": "Definitions_0wxa0mr", "type": "bpmn:Definitions", "executionId": "Definitions_0wxa0mr_3aac2ba6" }, "properties": { "messageId": "smq.mid-5e293", "timestamp": 1610661312640 } }, { "fields": { "routingKey": "run.resume", "exchange": "run" }, "content": { "id": "Definitions_0wxa0mr", "type": "bpmn:Definitions", "executionId": "Definitions_0wxa0mr_3aac2ba6" }, "properties": { "persistent": false, "messageId": "smq.mid-8bf979", "timestamp": 1610661900436 } } ], "messageCount": 2 }, { "name": "format-run-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execution-q", "options": { "autoDelete": false, "durable": true }, "messages": [], "messageCount": 0 }, { "name": "execute-Definitions_0wxa0mr_3aac2ba6-q", "options": { "autoDelete": false, "durable": true }, "messages": [ { "fields": { "routingKey": "process.start", "exchange": "event", "redelivered": true }, "content": { "id": "first-come-first-serve", "type": "bpmn:Process", "parent": { "id": "Definitions_0wxa0mr", "type": "bpmn:Definitions", "executionId": "Definitions_0wxa0mr_3aac2ba6" }, "executionId": "first-come-first-serve_204655f0", "state": "start" }, "properties": { "type": "start", "mandatory": false, "messageId": "smq.mid-3fc1a9", "timestamp": 1610661312646 } } ], "messageCount": 1 } ] }, "source": "{\"id\":\"Definitions_0wxa0mr\",\"type\":\"bpmn:Definitions\",\"activities\":[{\"id\":\"Event_10vtlbf\",\"type\":\"bpmn:StartEvent\",\"name\":\"START\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"behaviour\":{\"$type\":\"bpmn:StartEvent\",\"id\":\"Event_10vtlbf\",\"name\":\"START\"}},{\"id\":\"Gateway_01zwbav\",\"type\":\"bpmn:ParallelGateway\",\"name\":\"FORK\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"behaviour\":{\"$type\":\"bpmn:ParallelGateway\",\"id\":\"Gateway_01zwbav\",\"name\":\"FORK\"}},{\"id\":\"Gateway_1rh6556\",\"type\":\"bpmn:ParallelGateway\",\"name\":\"JOIN\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"behaviour\":{\"$type\":\"bpmn:ParallelGateway\",\"id\":\"Gateway_1rh6556\",\"name\":\"JOIN\"}},{\"id\":\"A\",\"type\":\"bpmn:UserTask\",\"name\":\"A\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"behaviour\":{\"$type\":\"bpmn:UserTask\",\"id\":\"A\",\"name\":\"A\"}},{\"id\":\"B\",\"type\":\"bpmn:UserTask\",\"name\":\"B\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"behaviour\":{\"$type\":\"bpmn:UserTask\",\"id\":\"B\",\"name\":\"B\"}},{\"id\":\"Event_1brbwtj\",\"type\":\"bpmn:EndEvent\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"behaviour\":{\"$type\":\"bpmn:EndEvent\",\"id\":\"Event_1brbwtj\"}}],\"associations\":[],\"dataObjects\":[],\"definition\":{\"id\":\"Definitions_0wxa0mr\",\"type\":\"bpmn:Definitions\",\"targetNamespace\":\"http://bpmn.io/schema/bpmn\",\"exporter\":\"Camunda Modeler\",\"exporterVersion\":\"4.5.0\"},\"messageFlows\":[],\"processes\":[{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\",\"parent\":{\"id\":\"Definitions_0wxa0mr\",\"type\":\"bpmn:Definitions\"},\"behaviour\":{\"$type\":\"bpmn:Process\",\"id\":\"first-come-first-serve\",\"isExecutable\":true,\"flowElements\":[{\"$type\":\"bpmn:StartEvent\",\"id\":\"Event_10vtlbf\",\"name\":\"START\"},{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_0817cno\"},{\"$type\":\"bpmn:ParallelGateway\",\"id\":\"Gateway_01zwbav\",\"name\":\"FORK\"},{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_1fq2v93\"},{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_0slt4s3\"},{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_16cbds7\"},{\"$type\":\"bpmn:ParallelGateway\",\"id\":\"Gateway_1rh6556\",\"name\":\"JOIN\"},{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_02qgtms\"},{\"$type\":\"bpmn:UserTask\",\"id\":\"A\",\"name\":\"A\"},{\"$type\":\"bpmn:UserTask\",\"id\":\"B\",\"name\":\"B\"},{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_1wsx714\"},{\"$type\":\"bpmn:EndEvent\",\"id\":\"Event_1brbwtj\"}]}}],\"sequenceFlows\":[{\"id\":\"Flow_0817cno\",\"type\":\"bpmn:SequenceFlow\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"targetId\":\"Gateway_01zwbav\",\"sourceId\":\"Event_10vtlbf\",\"behaviour\":{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_0817cno\"}},{\"id\":\"Flow_1fq2v93\",\"type\":\"bpmn:SequenceFlow\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"targetId\":\"A\",\"sourceId\":\"Gateway_01zwbav\",\"behaviour\":{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_1fq2v93\"}},{\"id\":\"Flow_0slt4s3\",\"type\":\"bpmn:SequenceFlow\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"targetId\":\"B\",\"sourceId\":\"Gateway_01zwbav\",\"behaviour\":{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_0slt4s3\"}},{\"id\":\"Flow_16cbds7\",\"type\":\"bpmn:SequenceFlow\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"targetId\":\"Gateway_1rh6556\",\"sourceId\":\"A\",\"behaviour\":{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_16cbds7\"}},{\"id\":\"Flow_02qgtms\",\"type\":\"bpmn:SequenceFlow\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"targetId\":\"Gateway_1rh6556\",\"sourceId\":\"B\",\"behaviour\":{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_02qgtms\"}},{\"id\":\"Flow_1wsx714\",\"type\":\"bpmn:SequenceFlow\",\"parent\":{\"id\":\"first-come-first-serve\",\"type\":\"bpmn:Process\"},\"targetId\":\"Event_1brbwtj\",\"sourceId\":\"Gateway_1rh6556\",\"behaviour\":{\"$type\":\"bpmn:SequenceFlow\",\"id\":\"Flow_1wsx714\"}}],\"scripts\":[],\"timers\":[]}" } ] } ```

If there's any other information that would be helpful to diagnose, please let me know. Really looking forward to digging in deep with this package!

Thanks!

mdwheele commented 3 years ago

I have a feeling that I am either stopping Engine execution too soon before persisting or that I am somehow persisting an invalid state and that's what is getting me into this mess. As a matter of fact, if I change the bpmn:userTask to bpmn:task, the process executes start to finish immediately and this JOIN event does not get "stuck". So I feel like there's something wrong with how I'm persisting / restoring the Engine, but am at a loss where to go from here.

Something I'm looking at right now is if the following is actually correct:

export async function Input(pid: string, task: string, input: string) {
  const engine = load(pid)

  const execution = await engine.resume()

  execution.signal({ 
    id: task
  })

  execution.stop()    // <<<<<<

  save(execution.getState())
  console.log(`Sent input to task ${task} in ${execution.name}`)
}

I almost feel like what I should be doing here is wiring a listener on activity.end, which would stop execution and save state. But what's weird about that is that it seems to work okay as-is for A and B completion. This whole issue I'm having really does feel like some persistence issue where I'm saving in the middle of async tasks on-going in the Engine, so I fully expect you to come in here and be like... "No no, do it THIS way!" 😂

paed01 commented 3 years ago

I have struggled myself with states/stop/recover/resume, so you might be on to something. What does it say if you DEBUG=bpmn* node your-program.js?

Btw, parallel gateways does not respond to signal or anything really. It just waits for all inbound flows to be touched.

Regarding task vs user task: task will complete immediately without waiting for a signal, hence the entire process is completed in a jiffy.

mdwheele commented 3 years ago

I have struggled myself with states/stop/recover/resume, so you might be on to something. What does it say if you DEBUG=bpmn* node your-program.js?

We'll see! I really appreciate the help here. I apologize about the verbosity, but I've grabbed DEBUG for all steps:

Start

``` $ DEBUG=bpmn-* bin/pocky.ts start src/resources/parallel.bpmn bpmn-engine:engine execute +0ms bpmn-engine:bpmn:definitions found 1 processes +0ms bpmn-engine:bpmn:definitions run +0ms bpmn-engine:bpmn:definitions enter +1ms bpmn-engine:bpmn:definitions start +0ms bpmn-engine:bpmn:definitions execute definition +1ms bpmn-engine:bpmn:process initialized with executionId +0ms bpmn-engine:bpmn:process enter +1ms bpmn-engine:bpmn:process start +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:process execute process +17ms bpmn-engine:bpmn:startevent initialized with executionId +0ms bpmn-engine:bpmn:startevent enter +10ms bpmn-engine:bpmn:startevent start +0ms bpmn-engine:bpmn:startevent execute +1ms bpmn-engine:bpmn:startevent completed execution +1ms bpmn-engine:bpmn:sequenceflow take, target +36ms bpmn-engine:bpmn:usertask enter +0ms bpmn-engine:bpmn:usertask start +0ms bpmn-engine:bpmn:usertask execute +1ms bpmn-engine:bpmn:sequenceflow take, target +40ms bpmn-engine:bpmn:usertask enter +0ms bpmn-engine:bpmn:usertask start +0ms bpmn-engine:bpmn:usertask execute +2ms bpmn-engine:bpmn:process left (bpmn:StartEvent), pending runs 2 [ 'A', 'B' ] +30ms bpmn-engine:bpmn:definitions stop definition execution (stop process executions 1) +57ms bpmn-engine:bpmn:process stop process execution (stop child executions 2) +3ms bpmn-engine:engine stopped +69ms af6decc3-47cd-4390-bb0f-fe69fc6cfa5e ```

Tick (immediately after start)

``` $ DEBUG=bpmn-* bin/pocky.ts tick af6decc3-47cd-4390-bb0f-fe69fc6cfa5e bpmn-engine:engine recover +0ms bpmn-engine:engine recover bpmn:Definitions +2ms bpmn-engine:bpmn:definitions found 1 processes +0ms bpmn-engine:bpmn:definitions recover executing definition execution +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:process recover process execution at executing +0ms bpmn-engine:engine resume +39ms bpmn-engine:bpmn:definitions resume +32ms bpmn-engine:bpmn:definitions resume executing definition execution +2ms bpmn-engine:bpmn:process resume process execution at executing +13ms bpmn-engine:bpmn:usertask resume execution +0ms bpmn-engine:bpmn:usertask resume execution +0ms bpmn-engine:bpmn:definitions stop definition execution (stop process executions 1) +25ms bpmn-engine:bpmn:process stop process execution (stop child executions 2) +24ms bpmn-engine:engine stopped +36ms State: stopped Status: There are 2 waiting tasks [A, B] on af6decc3-47cd-4390-bb0f-fe69fc6cfa5e ```

Input A

``` $ DEBUG=bpmn-* bin/pocky.ts input af6decc3-47cd-4390-bb0f-fe69fc6cfa5e A bpmn-engine:engine recover +0ms bpmn-engine:engine recover bpmn:Definitions +2ms bpmn-engine:bpmn:definitions found 1 processes +0ms bpmn-engine:bpmn:definitions recover executing definition execution +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:process recover process execution at executing +0ms bpmn-engine:engine resume +49ms bpmn-engine:bpmn:definitions resume +42ms bpmn-engine:bpmn:definitions resume executing definition execution +2ms bpmn-engine:bpmn:process resume process execution at executing +18ms bpmn-engine:bpmn:usertask resume execution +0ms bpmn-engine:bpmn:usertask resume execution +0ms bpmn-engine:bpmn:process delegate api definition.signal.Definitions_0wxa0mr_286c257f message to children, with correlationId +23ms bpmn-engine:bpmn:process delegated api message was consumed by A_cc470e2 +1ms bpmn-engine:bpmn:usertask completed execution +13ms bpmn-engine:bpmn:sequenceflow take, target +74ms bpmn-engine:bpmn:parallelgateway inbound take from , 1 remaining +0ms bpmn-engine:bpmn:parallelgateway initialized with executionId +0ms bpmn-engine:bpmn:process left (bpmn:UserTask), pending runs 3 [ 'B', 'Flow_16cbds7', 'Gateway_1rh6556' ] +10ms bpmn-engine:bpmn:definitions stop definition execution (stop process executions 1) +39ms bpmn-engine:bpmn:process stop process execution (stop child executions 3) +4ms bpmn-engine:engine stopped +48ms Sent input to task A in af6decc3-47cd-4390-bb0f-fe69fc6cfa5e ```

Input B

``` $ DEBUG=bpmn-* bin/pocky.ts input af6decc3-47cd-4390-bb0f-fe69fc6cfa5e B bpmn-engine:engine recover +0ms bpmn-engine:engine recover bpmn:Definitions +1ms bpmn-engine:bpmn:definitions found 1 processes +0ms bpmn-engine:bpmn:definitions recover executing definition execution +1ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:process recover process execution at executing +0ms bpmn-engine:engine resume +31ms bpmn-engine:bpmn:definitions resume +25ms bpmn-engine:bpmn:definitions resume executing definition execution +2ms bpmn-engine:bpmn:process resume process execution at executing +10ms bpmn-engine:bpmn:parallelgateway inbound take from , 1 remaining +0ms bpmn-engine:bpmn:parallelgateway initialized with executionId +0ms bpmn-engine:bpmn:usertask resume execution +0ms bpmn-engine:bpmn:process delegate api definition.signal.Definitions_0wxa0mr_286c257f message to children, with correlationId +16ms bpmn-engine:bpmn:process delegated api message was consumed by B_37606a1c +1ms bpmn-engine:bpmn:usertask completed execution +5ms bpmn-engine:bpmn:sequenceflow take, target +48ms bpmn-engine:bpmn:parallelgateway enter +21ms bpmn-engine:bpmn:parallelgateway start +1ms bpmn-engine:bpmn:parallelgateway execute +0ms bpmn-engine:bpmn:parallelgateway completed execution +1ms bpmn-engine:bpmn:sequenceflow take, target +54ms bpmn-engine:bpmn:endevent enter +0ms bpmn-engine:bpmn:endevent start +0ms bpmn-engine:bpmn:endevent execute +1ms bpmn-engine:bpmn:endevent completed execution +4ms bpmn-engine:bpmn:process left (bpmn:EndEvent), pending runs 3 [ 'Gateway_1rh6556', 'B', 'Gateway_1rh6556' ] +18ms bpmn-engine:bpmn:process left (bpmn:ParallelGateway), pending runs 2 [ 'Gateway_1rh6556', 'B' ] +3ms bpmn-engine:bpmn:process left (bpmn:UserTask), pending runs 1 [ 'Gateway_1rh6556' ] +0ms bpmn-engine:bpmn:definitions stop definition execution (stop process executions 1) +42ms bpmn-engine:bpmn:process stop process execution (stop child executions 1) +2ms bpmn-engine:engine stopped +48ms Sent input to task B in af6decc3-47cd-4390-bb0f-fe69fc6cfa5e ```

Final Tick

``` $ DEBUG=bpmn-* bin/pocky.ts tick af6decc3-47cd-4390-bb0f-fe69fc6cfa5e bpmn-engine:engine recover +0ms bpmn-engine:engine recover bpmn:Definitions +1ms bpmn-engine:bpmn:definitions found 1 processes +0ms bpmn-engine:bpmn:definitions recover executing definition execution +1ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:sequenceflow init, -> +0ms bpmn-engine:bpmn:process recover process execution at executing +0ms bpmn-engine:engine resume +29ms bpmn-engine:bpmn:definitions resume +24ms bpmn-engine:bpmn:definitions resume executing definition execution +1ms bpmn-engine:bpmn:process resume process execution at executing +10ms bpmn-engine:bpmn:definitions stop definition execution (stop process executions 1) +8ms bpmn-engine:bpmn:process stop process execution (stop child executions 1) +13ms bpmn-engine:engine stopped +22ms State: stopped Status: There are 1 waiting tasks [JOIN] on af6decc3-47cd-4390-bb0f-fe69fc6cfa5e ```
mdwheele commented 3 years ago

I'm in over my head, but was digging into the Process state immediately following both inputs to A and B and may have discovered something worth looking at. I noted that immediately following an input to A, we have these logs (this is from a slightly different BPMN that just IDs the flows / gateway explicitly). Take note of the JOIN execution ID (JOIN_13b36255):

  bpmn-engine:bpmn:usertask <A_1d484ba6 (A)> completed execution +10ms
  bpmn-engine:bpmn:sequenceflow <A-JOIN_take_2af164d1 (A-JOIN)> take, target <JOIN> +50ms
  bpmn-engine:bpmn:parallelgateway <JOIN> inbound take from <A-JOIN>, 1 remaining +0ms
  bpmn-engine:bpmn:parallelgateway <JOIN> initialized with executionId <JOIN_13b36255> +0ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> left <A> (bpmn:UserTask), pending runs 3 [ 'B', 'A-JOIN', 'JOIN' ] +10ms
  bpmn-engine:bpmn:definitions <Definitions_0wxa0mr_36025779 (Definitions_0wxa0mr)> stop definition execution (stop process executions 1) +40ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> stop process execution (stop child executions 3) +3ms
  bpmn-engine:engine <a5859094-be68-47b7-a26f-312771fb1d06> stopped +49ms

Additionally, I see an execute-parallel_343f4500-q is queued with an executionId matching logs above (i.e. JOIN_13b36255). Now, when I tick, we see this:

  bpmn-engine:engine <a5859094-be68-47b7-a26f-312771fb1d06> resume +29ms
  bpmn-engine:bpmn:definitions <Definitions_0wxa0mr_36025779 (Definitions_0wxa0mr)> resume +24ms
  bpmn-engine:bpmn:definitions <Definitions_0wxa0mr_36025779 (Definitions_0wxa0mr)> resume executing definition execution +2ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> resume process execution at executing +10ms
  bpmn-engine:bpmn:parallelgateway <JOIN> inbound take from <A-JOIN>, 1 remaining +0ms
  bpmn-engine:bpmn:parallelgateway <JOIN> initialized with executionId <JOIN_24a241d0> +1ms
  bpmn-engine:bpmn:usertask <B_33fbbeae (B)> resume execution +0ms

This is now a different executionId (JOIN_24a241d0). When this completes, nothing is written to disk and the previous execution remains queued. Additionally, every time I tick I get a different executionId, none of which seem to be serialized back to disk when the process is stopped and the previous execution seems to remain queued.

Now, I send input to B:

  bpmn-engine:engine <a5859094-be68-47b7-a26f-312771fb1d06> resume +31ms
  bpmn-engine:bpmn:definitions <Definitions_0wxa0mr_36025779 (Definitions_0wxa0mr)> resume +25ms
  bpmn-engine:bpmn:definitions <Definitions_0wxa0mr_36025779 (Definitions_0wxa0mr)> resume executing definition execution +1ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> resume process execution at executing +9ms
  bpmn-engine:bpmn:parallelgateway <JOIN> inbound take from <A-JOIN>, 1 remaining +0ms
  bpmn-engine:bpmn:parallelgateway <JOIN> initialized with executionId <JOIN_1ed1cbf7> +0ms
  bpmn-engine:bpmn:usertask <B_33fbbeae (B)> resume execution +0ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> delegate api definition.signal.Definitions_0wxa0mr_36025779 message to children, with correlationId <Definitions_0wxa0mr_signal_ff6a898> +18ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> delegated api message was consumed by B_33fbbeae +1ms
  bpmn-engine:bpmn:usertask <B_33fbbeae (B)> completed execution +13ms
  bpmn-engine:bpmn:sequenceflow <B-JOIN_take_1b35cc78 (B-JOIN)> take, target <JOIN> +50ms
  bpmn-engine:bpmn:parallelgateway <JOIN> enter  +20ms
  bpmn-engine:bpmn:parallelgateway <JOIN> start  +1ms
  bpmn-engine:bpmn:parallelgateway <JOIN_1ed1cbf7 (JOIN)> execute +0ms
  bpmn-engine:bpmn:parallelgateway <JOIN_1ed1cbf7 (JOIN)> completed execution +1ms
  bpmn-engine:bpmn:sequenceflow <Flow_1wsx714_take_d2c13a3 (Flow_1wsx714)> take, target <END> +52ms
  bpmn-engine:bpmn:endevent <END> enter  +0ms
  bpmn-engine:bpmn:endevent <END> start  +0ms
  bpmn-engine:bpmn:endevent <END_12bf1fad (END)> execute +0ms
  bpmn-engine:bpmn:endevent <END_12bf1fad (END)> completed execution +1ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> left <END> (bpmn:EndEvent), pending runs 3 [ 'JOIN', 'B', 'JOIN' ] +13ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> left <JOIN> (bpmn:ParallelGateway), pending runs 2 [ 'JOIN', 'B' ] +2ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> left <B> (bpmn:UserTask), pending runs 1 [ 'JOIN' ] +0ms
  bpmn-engine:bpmn:definitions <Definitions_0wxa0mr_36025779 (Definitions_0wxa0mr)> stop definition execution (stop process executions 1) +38ms
  bpmn-engine:bpmn:process <parallel_343f4500 (parallel)> stop process execution (stop child executions 1) +2ms
  bpmn-engine:engine <a5859094-be68-47b7-a26f-312771fb1d06> stopped +42ms

So this shows the process completing (or... at least reaching the end event). However, when ticked again, the process still shows as running. I confirm that this is the original execution stuck in queue by dumping:

const [waiting] = execution.getPostponed()

console.log(`${waiting.type} ${waiting.id} ${waiting.executionId}`)

... and see the following:

bpmn:ParallelGateway JOIN JOIN_13b36255

So, I think somewhere between Signal A -> {STOP} -> {RESTORE}, there's a execution getting "orphaned" or something. I'll try and dig into bpmn-elements a bit more tonight and see if I can come up with anything. I also think it may help me to switch to JavaScript for a while to make it easier to diagnose this as I'm also having to overwrite type definitions to have access to things like stop or engine.on. I'm happy to contribute those when we get everything settled!

paed01 commented 3 years ago

Can you have another attempt with the new shiny version?

mdwheele commented 3 years ago

Hey @paed01!

Just gave the example above another go and everything works perfectly on the latest version. Thanks so much for taking a look at this on your weekend.

I'll be sending a PR including some TypeScript type declaration fixes soon. It'll be a good opportunity for me to inspect the actual API and get that codified. Up to this point I've only been patching the things I am directly using.

paed01 commented 3 years ago

No problem. Feel free to close the issue if you deem it solved.