Skip to content

Commit 2d642af

Browse files
committed
refactor ActivityState back into the engine package
1 parent 6bb9b20 commit 2d642af

20 files changed

+209
-219
lines changed

docs/advanced-timers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func main() {
7575

7676
// sleep() for 2 seconds, before trying to continue the process instance
7777
// this for-loop essentially will block until the process instance has completed OR an error occurred
78-
for ; instance.GetState() == BPMN20.Active && err == nil; time.Sleep(2 * time.Second) {
78+
for ; instance.GetState() == Active && err == nil; time.Sleep(2 * time.Second) {
7979
println("tick.")
8080
// by re-running, the engine will check for active timers and might continue execution,
8181
// if timer.DueAt has passed

docs/examples/ordering_microservice/ordering_microservice_order_response.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ package main
33
import (
44
_ "embed"
55
"encoding/json"
6-
"github.com/nitram509/lib-bpmn-engine/pkg/spec/BPMN20"
6+
"github.com/nitram509/lib-bpmn-engine/pkg/bpmn_engine"
77
"time"
88
)
99

10-
func prepareJsonResponse(orderIdStr string, state BPMN20.ActivityState, createdAt time.Time) ([]byte, error) {
10+
func prepareJsonResponse(orderIdStr string, state bpmn_engine.ActivityState, createdAt time.Time) ([]byte, error) {
1111
type Order struct {
1212
OrderId string `json:"orderId"`
1313
ProcessInstanceState string `json:"state"`

docs/examples/timers/timers.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package main
22

33
import (
44
"github.com/nitram509/lib-bpmn-engine/pkg/bpmn_engine"
5-
"github.com/nitram509/lib-bpmn-engine/pkg/spec/BPMN20"
65
"time"
76
)
87

@@ -22,7 +21,7 @@ func main() {
2221

2322
// sleep() for 2 seconds, before trying to continue the process instance
2423
// this for-loop essentially will block until the process instance has completed OR an error occurred
25-
for ; instance.GetState() == BPMN20.Active && err == nil; time.Sleep(2 * time.Second) {
24+
for ; instance.GetState() == bpmn_engine.Active && err == nil; time.Sleep(2 * time.Second) {
2625
println("tick.")
2726
// by re-running, the engine will check for active timers and might continue execution,
2827
// if timer.DueAt has passed

pkg/bpmn_engine/actiivty.go

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,80 @@ package bpmn_engine
22

33
import "github.com/nitram509/lib-bpmn-engine/pkg/spec/BPMN20"
44

5+
// ActivityState as per BPMN 2.0 spec, section 13.2.2 Activity, page 428, State diagram:
6+
//
7+
// (Inactive)
8+
// O
9+
// |
10+
// A Token v
11+
// Arrives ┌─────┐
12+
// │Ready│
13+
// └─────┘
14+
// v Activity Interrupted An Alternative Path For
15+
// O -------------------------------------->O----------------------------+
16+
// Data InputSet v | Event Gateway Selected |
17+
// Available ┌──────┐ Interrupting| |
18+
// │Active│ Event | |
19+
// └──────┘ | v
20+
// v Activity Interrupted v An Alternative Path For┌─────────┐
21+
// O -------------------------------------->O ---------------------->│Withdrawn│
22+
// Activity's work v | Event Gateway Selected └─────────┘
23+
// completed ┌──────────┐ Interrupting| |
24+
// │Completing│ Event | The Process|
25+
// └──────────┘ | Ends |
26+
// v Activity Interrupted v Non-Error |
27+
// Completing O -------------------------------------->O--------------+ |
28+
// Requirements Done v Error v v |
29+
// Assignments ┌─────────┐ ┌───────┐ ┌───────────┐ |
30+
// Completed │Completed│ │Failing│ │Terminating│ |
31+
// └─────────┘ └───────┘ └───────────┘ |
32+
// v Compensation ┌────────────┐ v v |
33+
// O ------------->│Compensating│ O <-------------O Terminating |
34+
// | Occurs └────────────┘ v v Requirements Done
35+
// The Process | Compensation v Compensation | ┌──────────┐ |
36+
// Ends | +--------------O----------------/|\--------->│Terminated│ |
37+
// | | Completes | Interrupted | └──────────┘ |
38+
// | v | v | |
39+
// | ┌───────────┐ |Compensation┌──────┐ | |
40+
// | │Compensated│ +----------->│Failed│ | |
41+
// | └─────┬─────┘ Failed └──────┘ | |
42+
// | | | | |
43+
// v / The Process Ends / Process Ends / |
44+
// O<--------------------------------------------------------------------+
45+
// (Closed)
46+
type ActivityState string
47+
48+
const (
49+
Active ActivityState = "ACTIVE"
50+
Compensated ActivityState = "COMPENSATED"
51+
Compensating ActivityState = "COMPENSATING"
52+
Completed ActivityState = "COMPLETED"
53+
Completing ActivityState = "COMPLETING"
54+
Failed ActivityState = "FAILED"
55+
Failing ActivityState = "FAILING"
56+
Ready ActivityState = "READY"
57+
Terminated ActivityState = "TERMINATED"
58+
Terminating ActivityState = "TERMINATING"
59+
Withdrawn ActivityState = "WITHDRAWN"
60+
)
61+
562
type activity interface {
663
Key() int64
7-
State() BPMN20.ActivityState
64+
State() ActivityState
865
Element() *BPMN20.BaseElement
966
}
1067

1168
type elementActivity struct {
1269
key int64
13-
state BPMN20.ActivityState
70+
state ActivityState
1471
element *BPMN20.BaseElement
1572
}
1673

1774
func (a elementActivity) Key() int64 {
1875
return a.key
1976
}
2077

21-
func (a elementActivity) State() BPMN20.ActivityState {
78+
func (a elementActivity) State() ActivityState {
2279
return a.state
2380
}
2481

@@ -30,7 +87,7 @@ func (a elementActivity) Element() *BPMN20.BaseElement {
3087

3188
type gatewayActivity struct {
3289
key int64
33-
state BPMN20.ActivityState
90+
state ActivityState
3491
element *BPMN20.BaseElement
3592
parallel bool
3693
inboundFlowIdsCompleted []string
@@ -40,7 +97,7 @@ func (ga *gatewayActivity) Key() int64 {
4097
return ga.key
4198
}
4299

43-
func (ga *gatewayActivity) State() BPMN20.ActivityState {
100+
func (ga *gatewayActivity) State() ActivityState {
44101
return ga.state
45102
}
46103

@@ -61,15 +118,15 @@ func (ga *gatewayActivity) SetInboundFlowCompleted(flowId string) {
61118
ga.inboundFlowIdsCompleted = append(ga.inboundFlowIdsCompleted, flowId)
62119
}
63120

64-
func (ga *gatewayActivity) SetState(state BPMN20.ActivityState) {
121+
func (ga *gatewayActivity) SetState(state ActivityState) {
65122
ga.state = state
66123
}
67124

68125
// -------------------------------------------------------------------------
69126

70127
type eventBasedGatewayActivity struct {
71128
key int64
72-
state BPMN20.ActivityState
129+
state ActivityState
73130
element *BPMN20.BaseElement
74131
OutboundActivityCompleted string
75132
}
@@ -78,7 +135,7 @@ func (ebg *eventBasedGatewayActivity) Key() int64 {
78135
return ebg.key
79136
}
80137

81-
func (ebg *eventBasedGatewayActivity) State() BPMN20.ActivityState {
138+
func (ebg *eventBasedGatewayActivity) State() ActivityState {
82139
return ebg.state
83140
}
84141

pkg/bpmn_engine/conditions_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package bpmn_engine
22

33
import (
4-
"github.com/nitram509/lib-bpmn-engine/pkg/spec/BPMN20"
54
"testing"
65

76
"github.com/corbym/gocrest/has"
@@ -164,7 +163,7 @@ func Test_evaluation_error_percolates_up(t *testing.T) {
164163
instance, err := bpmnEngine.CreateAndRunInstance(process.ProcessKey, nil)
165164

166165
// then
167-
then.AssertThat(t, instance.State, is.EqualTo(BPMN20.Failed))
166+
then.AssertThat(t, instance.State, is.EqualTo(Failed))
168167
then.AssertThat(t, err, is.Not(is.Nil()))
169168
then.AssertThat(t, err.Error(), has.Prefix("Error evaluating expression in flow element id="))
170169
}

pkg/bpmn_engine/engine.go

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (state *BpmnEngineState) CreateInstance(processKey int64, variableContext m
7474
InstanceKey: state.generateKey(),
7575
VariableHolder: NewVarHolder(nil, variableContext),
7676
CreatedAt: time.Now(),
77-
State: BPMN20.Ready,
77+
State: Ready,
7878
}
7979
state.processInstances = append(state.processInstances, &processInstanceInfo)
8080
state.exportProcessInstanceEvent(*process, processInstanceInfo)
@@ -127,17 +127,17 @@ func (state *BpmnEngineState) run(instance *processInstanceInfo) (err error) {
127127
var commandQueue []command
128128

129129
switch instance.State {
130-
case BPMN20.Ready:
130+
case Ready:
131131
// use start events to start the instance
132132
for _, startEvent := range process.definitions.Process.StartEvents {
133133
var be BPMN20.BaseElement = startEvent
134134
commandQueue = append(commandQueue, activityCommand{
135135
element: &be,
136136
})
137137
}
138-
instance.State = BPMN20.Active
138+
instance.State = Active
139139
// TODO: check? export process EVENT
140-
case BPMN20.Active:
140+
case Active:
141141
jobs := state.findActiveJobsForContinuation(instance)
142142
for _, j := range jobs {
143143
commandQueue = append(commandQueue, continueActivityCommand{
@@ -173,7 +173,7 @@ func (state *BpmnEngineState) run(instance *processInstanceInfo) (err error) {
173173
if BPMN20.ExclusiveGateway == (*sourceActivity.Element()).GetType() {
174174
nextFlows, err = exclusivelyFilterByConditionExpression(nextFlows, instance.VariableHolder.Variables())
175175
if err != nil {
176-
instance.State = BPMN20.Failed
176+
instance.State = Failed
177177
return err
178178
}
179179
}
@@ -201,7 +201,7 @@ func (state *BpmnEngineState) run(instance *processInstanceInfo) (err error) {
201201
commandQueue = append(commandQueue, nextCommands...)
202202
case errorType:
203203
err = cmd.(errorCommand).err
204-
instance.State = BPMN20.Failed
204+
instance.State = Failed
205205
break
206206
case checkExclusiveGatewayDoneType:
207207
activity := cmd.(checkExclusiveGatewayDoneCommand).gatewayActivity
@@ -211,7 +211,7 @@ func (state *BpmnEngineState) run(instance *processInstanceInfo) (err error) {
211211
}
212212
}
213213

214-
if instance.State == BPMN20.Completed || instance.State == BPMN20.Failed {
214+
if instance.State == Completed || instance.State == Failed {
215215
// TODO need to send failed State
216216
state.exportEndProcessEvent(*process, *instance)
217217
}
@@ -230,7 +230,7 @@ func (state *BpmnEngineState) handleElement(process *ProcessInfo, instance *proc
230230
createFlowTransitions = true
231231
activity = &elementActivity{
232232
key: state.generateKey(),
233-
state: BPMN20.Completed,
233+
state: Completed,
234234
element: element,
235235
}
236236
case BPMN20.EndEvent:
@@ -239,17 +239,17 @@ func (state *BpmnEngineState) handleElement(process *ProcessInfo, instance *proc
239239
createFlowTransitions = false
240240
activity = &elementActivity{
241241
key: state.generateKey(),
242-
state: BPMN20.Completed,
242+
state: Completed,
243243
element: element,
244244
}
245245
case BPMN20.ServiceTask:
246246
taskElement := (*element).(BPMN20.TaskElement)
247247
_, activity = state.handleServiceTask(process, instance, &taskElement)
248-
createFlowTransitions = activity.State() == BPMN20.Completed
248+
createFlowTransitions = activity.State() == Completed
249249
case BPMN20.UserTask:
250250
taskElement := (*element).(BPMN20.TaskElement)
251251
activity = state.handleUserTask(process, instance, &taskElement)
252-
createFlowTransitions = activity.State() == BPMN20.Completed
252+
createFlowTransitions = activity.State() == Completed
253253
case BPMN20.IntermediateCatchEvent:
254254
ice := (*element).(BPMN20.TIntermediateCatchEvent)
255255
createFlowTransitions, activity, err = state.handleIntermediateCatchEvent(process, instance, ice, originActivity)
@@ -265,7 +265,7 @@ func (state *BpmnEngineState) handleElement(process *ProcessInfo, instance *proc
265265
case BPMN20.IntermediateThrowEvent:
266266
activity = &elementActivity{
267267
key: state.generateKey(),
268-
state: BPMN20.Active, // FIXME: should be Completed?
268+
state: Active, // FIXME: should be Completed?
269269
element: element,
270270
}
271271
cmds := state.handleIntermediateThrowEvent(process, instance, (*element).(BPMN20.TIntermediateThrowEvent), activity)
@@ -276,22 +276,22 @@ func (state *BpmnEngineState) handleElement(process *ProcessInfo, instance *proc
276276
case BPMN20.ExclusiveGateway:
277277
activity = elementActivity{
278278
key: state.generateKey(),
279-
state: BPMN20.Active,
279+
state: Active,
280280
element: element,
281281
}
282282
createFlowTransitions = true
283283
case BPMN20.EventBasedGateway:
284284
activity = &eventBasedGatewayActivity{
285285
key: state.generateKey(),
286-
state: BPMN20.Completed,
286+
state: Completed,
287287
element: element,
288288
}
289289
instance.appendActivity(activity)
290290
createFlowTransitions = true
291291
case BPMN20.InclusiveGateway:
292292
activity = elementActivity{
293293
key: state.generateKey(),
294-
state: BPMN20.Active,
294+
state: Active,
295295
element: element,
296296
}
297297
createFlowTransitions = true
@@ -321,7 +321,7 @@ func createNextCommands(process *ProcessInfo, instance *processInstanceInfo, ele
321321
case BPMN20.ExclusiveGateway:
322322
nextFlows, err = exclusivelyFilterByConditionExpression(nextFlows, instance.VariableHolder.Variables())
323323
if err != nil {
324-
instance.State = BPMN20.Failed
324+
instance.State = Failed
325325
cmds = append(cmds, errorCommand{
326326
err: err,
327327
elementId: (*element).GetId(),
@@ -332,7 +332,7 @@ func createNextCommands(process *ProcessInfo, instance *processInstanceInfo, ele
332332
case BPMN20.InclusiveGateway:
333333
nextFlows, err = inclusivelyFilterByConditionExpression(nextFlows, instance.VariableHolder.Variables())
334334
if err != nil {
335-
instance.State = BPMN20.Failed
335+
instance.State = Failed
336336
return []command{
337337
errorCommand{
338338
elementId: (*element).GetId(),
@@ -362,7 +362,7 @@ func (state *BpmnEngineState) handleIntermediateCatchEvent(process *ProcessInfo,
362362
var be BPMN20.BaseElement = ice
363363
activity = &elementActivity{
364364
key: state.generateKey(),
365-
state: BPMN20.Active, // FIXME: should be Completed?
365+
state: Active, // FIXME: should be Completed?
366366
element: &be,
367367
}
368368
throwLinkName := (*originActivity.Element()).(BPMN20.TIntermediateThrowEvent).LinkEventDefinition.Name
@@ -382,14 +382,14 @@ func (state *BpmnEngineState) handleEndEvent(process *ProcessInfo, instance *pro
382382
activeMessageSubscriptions := false
383383
for _, ms := range state.messageSubscriptions {
384384
if ms.ProcessInstanceKey == instance.InstanceKey {
385-
activeMessageSubscriptions = activeMessageSubscriptions || ms.State() == BPMN20.Active || ms.State() == BPMN20.Ready
385+
activeMessageSubscriptions = activeMessageSubscriptions || ms.State() == Active || ms.State() == Ready
386386
}
387387
if activeMessageSubscriptions {
388388
break
389389
}
390390
}
391391
if !activeMessageSubscriptions {
392-
instance.State = BPMN20.Completed
392+
instance.State = Completed
393393
}
394394
}
395395

@@ -399,7 +399,7 @@ func (state *BpmnEngineState) handleParallelGateway(process *ProcessInfo, instan
399399
var be BPMN20.BaseElement = element
400400
resultActivity = &gatewayActivity{
401401
key: state.generateKey(),
402-
state: BPMN20.Active,
402+
state: Active,
403403
element: &be,
404404
parallel: true,
405405
}
@@ -409,14 +409,14 @@ func (state *BpmnEngineState) handleParallelGateway(process *ProcessInfo, instan
409409
resultActivity.(*gatewayActivity).SetInboundFlowCompleted(sourceFlow.Id)
410410
continueFlow = resultActivity.(*gatewayActivity).parallel && resultActivity.(*gatewayActivity).AreInboundFlowsCompleted()
411411
if continueFlow {
412-
resultActivity.(*gatewayActivity).SetState(BPMN20.Completed)
412+
resultActivity.(*gatewayActivity).SetState(Completed)
413413
}
414414
return continueFlow, resultActivity
415415
}
416416

417417
func (state *BpmnEngineState) findActiveJobsForContinuation(instance *processInstanceInfo) (ret []*job) {
418418
for _, job := range state.jobs {
419-
if job.ProcessInstanceKey == instance.InstanceKey && job.JobState == BPMN20.Active {
419+
if job.ProcessInstanceKey == instance.InstanceKey && job.JobState == Active {
420420
ret = append(ret, job)
421421
}
422422
}
@@ -428,7 +428,7 @@ func (state *BpmnEngineState) findActiveJobsForContinuation(instance *processIns
428428
// if no ids are provided, all active subscriptions are returned
429429
func (state *BpmnEngineState) findActiveSubscriptions(instance *processInstanceInfo) (result []*MessageSubscription) {
430430
for _, ms := range state.messageSubscriptions {
431-
if ms.ProcessInstanceKey == instance.InstanceKey && ms.MessageState == BPMN20.Active {
431+
if ms.ProcessInstanceKey == instance.InstanceKey && ms.MessageState == Active {
432432
result = append(result, ms)
433433
}
434434
}

0 commit comments

Comments
 (0)