Skip to content

Commit

Permalink
fix depth calculation in task iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
essweine committed Sep 28, 2023
1 parent a49ae7d commit 561f129
Show file tree
Hide file tree
Showing 7 changed files with 533 additions and 52 deletions.
31 changes: 18 additions & 13 deletions SpiffWorkflow/bpmn/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,27 +61,32 @@ def _next(self):
if len(self.task_list) == 0:
raise StopIteration()

task = self.task_list.pop(-1)
task = self.task_list.pop(0)
subprocess = task.workflow.top_workflow.subprocesses.get(task.id)

if all([
if task.task_spec.name == self.end_at_spec:
self.task_list = []
elif all([
len(task._children) > 0 or subprocess is not None,
task.state >= self.min_state,
self.depth < self.max_depth,
task.task_spec.name != self.end_at_spec,
]):
add_tasks = [t for t in reversed(task.children)]
if subprocess is None:
next_tasks = task.children
elif self.depth_first:
next_tasks = [subprocess.task_tree] + task.children
else:
next_tasks = task.children = [subprocess.task_tree]

if self.depth_first:
if subprocess is not None:
add_tasks.append(subprocess.task_tree)
self.task_list.extend(add_tasks)
self.task_list = next_tasks + self.task_list
else:
if subprocess is not None:
add_tasks = [subprocess.task_tree] + add_tasks
self.task_list = add_tasks + self.task_list
self.depth += 1
elif len(self.task_list) > 0 and task.parent != self.task_list[0].parent:
self.depth -= 1
self.task_list.extend(next_tasks)
self._update_depth(task)

elif self.depth_first and len(self.task_list) > 0:
self._handle_leaf_depth(task)

return task


Expand Down
40 changes: 32 additions & 8 deletions SpiffWorkflow/util/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,19 +204,43 @@ def _next(self):
if len(self.task_list) == 0:
raise StopIteration()

task = self.task_list.pop(-1)
if all([
task = self.task_list.pop(0)

if task.task_spec.name == self.end_at_spec:
self.task_list = []
elif all([
len(task._children) > 0,
task.state >= self.min_state,
self.depth < self.max_depth,
task.task_spec.name != self.end_at_spec,
]):
if self.depth_first:
self.task_list.extend(reversed(task.children))
self.task_list = task.children + self.task_list
else:
self.task_list = reversed(task.children) + self.task_list
self.depth += 1
elif len(self.task_list) > 0 and task.parent != self.task_list[0].parent:
self.depth -= 1
self.task_list.extend(task.children)
self._update_depth(task)
elif self.depth_first and len(self.task_list) > 0:
self._handle_leaf_depth(task)

return task

def _update_depth(self, task):

if self.depth_first:
# Since we visit the children before siblings, we always increment depth when adding children
self.depth += 1
else:
# In this case, we have to check for a common ancestor at the same depth
first, second = task, self.task_list[0]
for i in range(self.depth):
first = first.parent if first is not None else None
second = second.parent if second is not None else None
if first != second:
self.depth += 1

def _handle_leaf_depth(self, task):

ancestor = self.task_list[0].parent
current = task.parent
while current is not None and current != ancestor:
current = current.parent
self.depth -= 1
245 changes: 245 additions & 0 deletions tests/SpiffWorkflow/camunda/data/training_workflow.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
<?xml version="1.0" encoding="UTF-8"?>
<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:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1aw0vtr" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.1.2">
<bpmn:process id="TrainingWorkflow" name="Training Workflow" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>SequenceFlow_1tfpe3x</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="SequenceFlow_1tfpe3x" sourceRef="StartEvent_1" targetRef="Task_SetVariables" />
<bpmn:endEvent id="Done" name="Done">
<bpmn:incoming>SequenceFlow_1wcfi2i</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="SequenceFlow_0opv547" sourceRef="Task_SetVariables" targetRef="Task_12bl214" />
<bpmn:scriptTask id="Task_SetVariables" name="Set Variable" scriptFormat="python">
<bpmn:incoming>SequenceFlow_1tfpe3x</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_0opv547</bpmn:outgoing>
<bpmn:script>test = "1234"
resources = [
{
"category": "Zayo POC CFS - CommsCloudDemo-007",
"description": "TEST for CommsCloudDemo-007",
"externalId": "CommsCloudDemo-007",
"notificationContact": "[email protected]",
"state": "failed",
"note": [{
"author": "platform",
"date": "2023-04-27T23:46:16Z",
"system": "platform",
"text": "Resource ad378070-e555-11ed-99de-c9cc5fa6d9bc failed: 503 Service Unavailable: Device 1255b0d0-b7b6-11ed-86dd-9136be24853f is not connected"
}],
"orderItem": [{
"id": "1",
"action": "add",
"state": "failed",
"service": {
"id": "04ed0810-d9be-11ed-99de-c9cc5fa6d9bc",
"name": "Test6 Create Service",
"state": "active",
"serviceCharacteristic": [{
"name": "serviceName",
"valueType": "String",
"value": "CFS-Site3ToSite4_1-1-1"
}, {
"name": "serviceCapacity",
"valueType": "Integer",
"value": 400
}, {
"name": "endPoint1",
"valueType": "Object",
"value": {
"siteName": "WS52NSITE3",
"shelf": 1,
"slot": 1,
"port": 1
}
}, {
"name": "endPoint2",
"valueType": "Object",
"value": {
"siteName": "WS52NSITE4",
"shelf": 1,
"slot": 1,
"port": 1
}
}],
"serviceSpecification": {
"id": "75f065a0-ba12-11ed-86dd-9136be24853f",
"href": "test.resourceTypes.zayoPocTestCFS",
"name": "Zayo POC CFS",
"version": "1.0",
"@baseType": "ServiceSpecification",
"@type": "test.resourceTypes.zayoPocTestCFS"
}
}
}],
"id": "a90fcfc0-e555-11ed-99de-c9cc5fa6d9bc",
"href": "/open-api/api/tmf/serviceOrder/a90fcfc0-e555-11ed-99de-c9cc5fa6d9bc",
"completionDate": "2023-04-27T23:46:17Z",
"orderDate": "2023-04-27 19:45:58.000 -0400",
"startDate": "2023-04-27T23:46:04Z",
"processId": "ac564893-e555-11ed-85f6-0242ac100028",
"@baseType": "ServiceOrder",
"@type": "ServiceOrder"
}]
resource = resources[0]
print("====&gt; RESOURCE: " + str(resource))</bpmn:script>
</bpmn:scriptTask>
<bpmn:sequenceFlow id="SequenceFlow_04yo1qo" sourceRef="Task_12bl214" targetRef="ExclusiveGateway_0wymcsj" />
<bpmn:sequenceFlow id="SequenceFlow_0vfy96y" sourceRef="Task_1p6vtlh" targetRef="ExclusiveGateway_0iylfkq" />
<bpmn:scriptTask id="Task_12bl214" name="Print Variables" scriptFormat="python">
<bpmn:incoming>SequenceFlow_0opv547</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_04yo1qo</bpmn:outgoing>
<bpmn:script>#from utils import print_variables

# print("RESOURCES: " + str(resources))

#print_variables(task)</bpmn:script>
</bpmn:scriptTask>
<bpmn:callActivity id="Task_1p6vtlh" name="Call Sub Function" calledElement="TrainingWorkflow2">
<bpmn:extensionElements>
<camunda:in source="resources" target="resources" />
<camunda:in source="resource_length" target="resource_length" />
<camunda:out source="var1[0]" target="var1" />
<camunda:executionListener event="start">
<camunda:script scriptFormat="python">resource_length = len(resources)</camunda:script>
</camunda:executionListener>
<camunda:executionListener event="end">
<camunda:script scriptFormat="python">variable1 = len(var1)
del var1</camunda:script>
</camunda:executionListener>
</bpmn:extensionElements>
<bpmn:incoming>SequenceFlow_0m5gbyd</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_0vfy96y</bpmn:outgoing>
</bpmn:callActivity>
<bpmn:sequenceFlow id="SequenceFlow_0m5gbyd" sourceRef="ExclusiveGateway_0wymcsj" targetRef="Task_1p6vtlh" />
<bpmn:task id="Task_Rgt0" name="Do Resources == 0">
<bpmn:incoming>SequenceFlow_1lq7zz4</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_0xcqsx4</bpmn:outgoing>
</bpmn:task>
<bpmn:sequenceFlow id="SequenceFlow_1lq7zz4" sourceRef="ExclusiveGateway_0wymcsj" targetRef="Task_Rgt0">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression" language="python">len(resources) == 0</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="SequenceFlow_0xcqsx4" sourceRef="Task_Rgt0" targetRef="ExclusiveGateway_0iylfkq" />
<bpmn:sequenceFlow id="SequenceFlow_12ua2ob" sourceRef="ExclusiveGateway_0iylfkq" targetRef="Task_13gvp5y" />
<bpmn:exclusiveGateway id="ExclusiveGateway_0wymcsj" default="SequenceFlow_0m5gbyd">
<bpmn:incoming>SequenceFlow_04yo1qo</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_0m5gbyd</bpmn:outgoing>
<bpmn:outgoing>SequenceFlow_1lq7zz4</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:exclusiveGateway id="ExclusiveGateway_0iylfkq">
<bpmn:incoming>SequenceFlow_0vfy96y</bpmn:incoming>
<bpmn:incoming>SequenceFlow_0xcqsx4</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_12ua2ob</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="SequenceFlow_1wcfi2i" sourceRef="Task_13gvp5y" targetRef="Done" />
<bpmn:scriptTask id="Task_13gvp5y" name="Print Variables" scriptFormat="python">
<bpmn:incoming>SequenceFlow_12ua2ob</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_1wcfi2i</bpmn:outgoing>
<bpmn:script>print("====&gt; TASK VARIABLES: " + str(task.parent.data))</bpmn:script>
</bpmn:scriptTask>
<bpmn:textAnnotation id="TextAnnotation_1djoxcc">
<bpmn:text>test = "1234"
resources
resource</bpmn:text>
</bpmn:textAnnotation>
<bpmn:association id="Association_067y607" sourceRef="Task_SetVariables" targetRef="TextAnnotation_1djoxcc" />
<bpmn:textAnnotation id="TextAnnotation_0a3sv8x">
<bpmn:text>Enviroment - Python Objects
Script Engine
Workflow
Task</bpmn:text>
</bpmn:textAnnotation>
<bpmn:association id="Association_0ui9070" sourceRef="StartEvent_1" targetRef="TextAnnotation_0a3sv8x" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="TrainingWorkflow">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="248" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1tfpe3x_di" bpmnElement="SequenceFlow_1tfpe3x">
<di:waypoint x="215" y="266" />
<di:waypoint x="265" y="266" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_09gohuu_di" bpmnElement="Done">
<dc:Bounds x="1079" y="248" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1083" y="224" width="27" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0opv547_di" bpmnElement="SequenceFlow_0opv547">
<di:waypoint x="365" y="266" />
<di:waypoint x="420" y="266" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ScriptTask_1j52krz_di" bpmnElement="Task_SetVariables">
<dc:Bounds x="265" y="226" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_04yo1qo_di" bpmnElement="SequenceFlow_04yo1qo">
<di:waypoint x="520" y="266" />
<di:waypoint x="578" y="266" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_0vfy96y_di" bpmnElement="SequenceFlow_0vfy96y">
<di:waypoint x="775" y="266" />
<di:waypoint x="830" y="266" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ScriptTask_1k550up_di" bpmnElement="Task_12bl214">
<dc:Bounds x="420" y="226" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="TextAnnotation_1djoxcc_di" bpmnElement="TextAnnotation_1djoxcc">
<dc:Bounds x="365" y="146" width="100" height="68" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Association_067y607_di" bpmnElement="Association_067y607">
<di:waypoint x="360" y="228" />
<di:waypoint x="376" y="214" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="TextAnnotation_0a3sv8x_di" bpmnElement="TextAnnotation_0a3sv8x">
<dc:Bounds x="123" y="81" width="400" height="82" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Association_0ui9070_di" bpmnElement="Association_0ui9070">
<di:waypoint x="209" y="253" />
<di:waypoint x="288" y="163" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="CallActivity_194s6w7_di" bpmnElement="Task_1p6vtlh">
<dc:Bounds x="675" y="226" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0m5gbyd_di" bpmnElement="SequenceFlow_0m5gbyd">
<di:waypoint x="628" y="266" />
<di:waypoint x="675" y="266" />
<bpmndi:BPMNLabel>
<dc:Bounds x="616" y="248" width="72" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Task_0dt1vbk_di" bpmnElement="Task_Rgt0">
<dc:Bounds x="675" y="336" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1lq7zz4_di" bpmnElement="SequenceFlow_1lq7zz4">
<di:waypoint x="603" y="291" />
<di:waypoint x="603" y="376" />
<di:waypoint x="675" y="376" />
<bpmndi:BPMNLabel>
<dc:Bounds x="581" y="331" width="78" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_0xcqsx4_di" bpmnElement="SequenceFlow_0xcqsx4">
<di:waypoint x="775" y="376" />
<di:waypoint x="855" y="376" />
<di:waypoint x="855" y="291" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_12ua2ob_di" bpmnElement="SequenceFlow_12ua2ob">
<di:waypoint x="880" y="266" />
<di:waypoint x="930" y="266" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ExclusiveGateway_1jpie56_di" bpmnElement="ExclusiveGateway_0wymcsj" isMarkerVisible="true">
<dc:Bounds x="578" y="241" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ExclusiveGateway_13m2ywl_di" bpmnElement="ExclusiveGateway_0iylfkq" isMarkerVisible="true">
<dc:Bounds x="830" y="241" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1wcfi2i_di" bpmnElement="SequenceFlow_1wcfi2i">
<di:waypoint x="1030" y="266" />
<di:waypoint x="1079" y="266" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ScriptTask_0hi8i9a_di" bpmnElement="Task_13gvp5y">
<dc:Bounds x="930" y="226" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
Loading

0 comments on commit 561f129

Please sign in to comment.