Skip to content

Commit 1104fb0

Browse files
authored
Merge pull request #279 from erinoggz/main
Fix task handlers for multiple process instances with same user task IDs
2 parents 31b6c5c + 14ebb9c commit 1104fb0

File tree

3 files changed

+168
-1
lines changed

3 files changed

+168
-1
lines changed

pkg/bpmn_engine/jobs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func (j job) Element() *BPMN20.BaseElement {
3535
func findOrCreateJob(jobs *[]*job, element *BPMN20.TaskElement, instance *processInstanceInfo, generateKey func() int64) *job {
3636
be := (*element).(BPMN20.BaseElement)
3737
for _, job := range *jobs {
38-
if job.ElementId == be.GetId() {
38+
if job.ElementId == be.GetId() && job.ProcessInstanceKey == instance.GetInstanceKey() {
3939
return job
4040
}
4141
}

pkg/bpmn_engine/jobs_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,3 +339,44 @@ func Test_missing_task_handlers_break_execution_and_can_be_continued_later(t *te
339339
then.AssertThat(t, err, is.Nil())
340340
then.AssertThat(t, cp.CallPath, is.EqualTo("id-a-1,id-b-1,id-b-2"))
341341
}
342+
343+
func Test_multiple_instances_with_same_user_task_ids(t *testing.T) {
344+
// setup
345+
bpmnEngine := New()
346+
process, err := bpmnEngine.LoadFromFile("../../test-cases/user-tasks-with-parallel-gateways.bpmn")
347+
then.AssertThat(t, err, is.Nil())
348+
349+
called := map[int64][]string{}
350+
handler := func(taskId string) func(ActivatedJob) {
351+
return func(job ActivatedJob) {
352+
called[job.ProcessInstanceKey()] = append(called[job.ProcessInstanceKey()], taskId)
353+
job.Complete()
354+
}
355+
}
356+
357+
// given
358+
bpmnEngine.NewTaskHandler().Id("assignee-task1").Handler(handler("assignee-task1"))
359+
bpmnEngine.NewTaskHandler().Id("assignee-task2").Handler(handler("assignee-task2"))
360+
bpmnEngine.NewTaskHandler().Id("assignee-task3").Handler(handler("assignee-task3"))
361+
bpmnEngine.NewTaskHandler().Id("assignee-task4").Handler(handler("assignee-task4"))
362+
363+
instance1, err1 := bpmnEngine.CreateAndRunInstance(process.ProcessKey, nil)
364+
then.AssertThat(t, err1, is.Nil())
365+
then.AssertThat(t, instance1, is.Not(is.Nil()))
366+
367+
instance2, err2 := bpmnEngine.CreateAndRunInstance(process.ProcessKey, nil)
368+
then.AssertThat(t, err2, is.Nil())
369+
then.AssertThat(t, instance2, is.Not(is.Nil()))
370+
371+
// when
372+
_, err1c := bpmnEngine.RunOrContinueInstance(instance1.GetInstanceKey())
373+
_, err2c := bpmnEngine.RunOrContinueInstance(instance2.GetInstanceKey())
374+
375+
// then
376+
then.AssertThat(t, err1c, is.Nil())
377+
then.AssertThat(t, err2c, is.Nil())
378+
then.AssertThat(t, instance1.GetState(), is.EqualTo(Completed))
379+
then.AssertThat(t, instance2.GetState(), is.EqualTo(Completed))
380+
then.AssertThat(t, called[instance1.GetInstanceKey()], has.Length(4))
381+
then.AssertThat(t, called[instance2.GetInstanceKey()], has.Length(4))
382+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1u3x2yl" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.3.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="1.0.0">
3+
<bpmn:process id="user-tasks-with-assignments" name="user-tasks-with-assignments" isExecutable="true">
4+
<bpmn:startEvent id="StartEvent_1">
5+
<bpmn:outgoing>Flow_0xt1d7q</bpmn:outgoing>
6+
</bpmn:startEvent>
7+
<bpmn:sequenceFlow id="Flow_0xt1d7q" sourceRef="StartEvent_1" targetRef="Gateway_0vr3shh" />
8+
<bpmn:userTask id="assignee-task1" name="assignee-task1">
9+
<bpmn:extensionElements>
10+
<zeebe:assignmentDefinition assignee="assignee" />
11+
<zeebe:formDefinition formKey="form-key" />
12+
</bpmn:extensionElements>
13+
<bpmn:incoming>Flow_05og6fe</bpmn:incoming>
14+
<bpmn:outgoing>Flow_1yi8zvd</bpmn:outgoing>
15+
</bpmn:userTask>
16+
<bpmn:sequenceFlow id="Flow_1yi8zvd" sourceRef="assignee-task1" targetRef="assignee-task4" />
17+
<bpmn:endEvent id="Event_13981zj">
18+
<bpmn:incoming>Flow_1qo8x2a</bpmn:incoming>
19+
</bpmn:endEvent>
20+
<bpmn:sequenceFlow id="Flow_1nvo18e" sourceRef="assignee-task4" targetRef="Gateway_0j4qy72" />
21+
<bpmn:userTask id="assignee-task4" name="assignee-task4">
22+
<bpmn:extensionElements>
23+
<zeebe:assignmentDefinition assignee="assignee" />
24+
</bpmn:extensionElements>
25+
<bpmn:incoming>Flow_1yi8zvd</bpmn:incoming>
26+
<bpmn:outgoing>Flow_1nvo18e</bpmn:outgoing>
27+
</bpmn:userTask>
28+
<bpmn:userTask id="assignee-task2" name="assignee-task2">
29+
<bpmn:extensionElements>
30+
<zeebe:assignmentDefinition assignee="assignee" />
31+
<zeebe:formDefinition formKey="form-key" />
32+
</bpmn:extensionElements>
33+
<bpmn:incoming>Flow_1qupj9f</bpmn:incoming>
34+
<bpmn:outgoing>Flow_0wdizhy</bpmn:outgoing>
35+
</bpmn:userTask>
36+
<bpmn:userTask id="assignee-task3" name="assignee-task3">
37+
<bpmn:extensionElements>
38+
<zeebe:assignmentDefinition assignee="assignee" />
39+
<zeebe:formDefinition formKey="form-key" />
40+
</bpmn:extensionElements>
41+
<bpmn:incoming>Flow_0wdizhy</bpmn:incoming>
42+
<bpmn:outgoing>Flow_1xqmkxd</bpmn:outgoing>
43+
</bpmn:userTask>
44+
<bpmn:sequenceFlow id="Flow_1qo8x2a" sourceRef="Gateway_0j4qy72" targetRef="Event_13981zj" />
45+
<bpmn:sequenceFlow id="Flow_05og6fe" sourceRef="Gateway_0vr3shh" targetRef="assignee-task1" />
46+
<bpmn:sequenceFlow id="Flow_1qupj9f" sourceRef="Gateway_0vr3shh" targetRef="assignee-task2" />
47+
<bpmn:sequenceFlow id="Flow_0wdizhy" sourceRef="assignee-task2" targetRef="assignee-task3" />
48+
<bpmn:sequenceFlow id="Flow_1xqmkxd" sourceRef="assignee-task3" targetRef="Gateway_0j4qy72" />
49+
<bpmn:parallelGateway id="Gateway_0j4qy72">
50+
<bpmn:incoming>Flow_1nvo18e</bpmn:incoming>
51+
<bpmn:incoming>Flow_1xqmkxd</bpmn:incoming>
52+
<bpmn:outgoing>Flow_1qo8x2a</bpmn:outgoing>
53+
</bpmn:parallelGateway>
54+
<bpmn:parallelGateway id="Gateway_0vr3shh">
55+
<bpmn:incoming>Flow_0xt1d7q</bpmn:incoming>
56+
<bpmn:outgoing>Flow_05og6fe</bpmn:outgoing>
57+
<bpmn:outgoing>Flow_1qupj9f</bpmn:outgoing>
58+
</bpmn:parallelGateway>
59+
</bpmn:process>
60+
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
61+
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="user-tasks-with-assignments">
62+
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
63+
<dc:Bounds x="112" y="99" width="36" height="36" />
64+
</bpmndi:BPMNShape>
65+
<bpmndi:BPMNShape id="Activity_102w2rp_di" bpmnElement="assignee-task1">
66+
<dc:Bounds x="300" y="77" width="100" height="80" />
67+
<bpmndi:BPMNLabel />
68+
</bpmndi:BPMNShape>
69+
<bpmndi:BPMNShape id="Event_13981zj_di" bpmnElement="Event_13981zj">
70+
<dc:Bounds x="752" y="99" width="36" height="36" />
71+
</bpmndi:BPMNShape>
72+
<bpmndi:BPMNShape id="Activity_0o75bye_di" bpmnElement="assignee-task4">
73+
<dc:Bounds x="470" y="77" width="100" height="80" />
74+
<bpmndi:BPMNLabel />
75+
</bpmndi:BPMNShape>
76+
<bpmndi:BPMNShape id="BPMNShape_1u096ea" bpmnElement="assignee-task2">
77+
<dc:Bounds x="300" y="-70" width="100" height="80" />
78+
<bpmndi:BPMNLabel />
79+
</bpmndi:BPMNShape>
80+
<bpmndi:BPMNShape id="BPMNShape_1r9vrob" bpmnElement="assignee-task3">
81+
<dc:Bounds x="460" y="-70" width="100" height="80" />
82+
<bpmndi:BPMNLabel />
83+
</bpmndi:BPMNShape>
84+
<bpmndi:BPMNShape id="Gateway_1u6njpc_di" bpmnElement="Gateway_0j4qy72">
85+
<dc:Bounds x="645" y="92" width="50" height="50" />
86+
</bpmndi:BPMNShape>
87+
<bpmndi:BPMNShape id="Gateway_0ljyn6i_di" bpmnElement="Gateway_0vr3shh">
88+
<dc:Bounds x="215" y="92" width="50" height="50" />
89+
</bpmndi:BPMNShape>
90+
<bpmndi:BPMNEdge id="Flow_0xt1d7q_di" bpmnElement="Flow_0xt1d7q">
91+
<di:waypoint x="148" y="117" />
92+
<di:waypoint x="215" y="117" />
93+
</bpmndi:BPMNEdge>
94+
<bpmndi:BPMNEdge id="Flow_1yi8zvd_di" bpmnElement="Flow_1yi8zvd">
95+
<di:waypoint x="400" y="117" />
96+
<di:waypoint x="470" y="117" />
97+
</bpmndi:BPMNEdge>
98+
<bpmndi:BPMNEdge id="Flow_1nvo18e_di" bpmnElement="Flow_1nvo18e">
99+
<di:waypoint x="570" y="117" />
100+
<di:waypoint x="645" y="117" />
101+
</bpmndi:BPMNEdge>
102+
<bpmndi:BPMNEdge id="Flow_1qo8x2a_di" bpmnElement="Flow_1qo8x2a">
103+
<di:waypoint x="695" y="117" />
104+
<di:waypoint x="752" y="117" />
105+
</bpmndi:BPMNEdge>
106+
<bpmndi:BPMNEdge id="Flow_05og6fe_di" bpmnElement="Flow_05og6fe">
107+
<di:waypoint x="265" y="117" />
108+
<di:waypoint x="300" y="117" />
109+
</bpmndi:BPMNEdge>
110+
<bpmndi:BPMNEdge id="Flow_1qupj9f_di" bpmnElement="Flow_1qupj9f">
111+
<di:waypoint x="240" y="92" />
112+
<di:waypoint x="240" y="-30" />
113+
<di:waypoint x="300" y="-30" />
114+
</bpmndi:BPMNEdge>
115+
<bpmndi:BPMNEdge id="Flow_0wdizhy_di" bpmnElement="Flow_0wdizhy">
116+
<di:waypoint x="400" y="-30" />
117+
<di:waypoint x="460" y="-30" />
118+
</bpmndi:BPMNEdge>
119+
<bpmndi:BPMNEdge id="Flow_1xqmkxd_di" bpmnElement="Flow_1xqmkxd">
120+
<di:waypoint x="560" y="-30" />
121+
<di:waypoint x="670" y="-30" />
122+
<di:waypoint x="670" y="92" />
123+
</bpmndi:BPMNEdge>
124+
</bpmndi:BPMNPlane>
125+
</bpmndi:BPMNDiagram>
126+
</bpmn:definitions>

0 commit comments

Comments
 (0)