mirror of
https://github.com/status-im/spiff-arena.git
synced 2025-02-11 01:06:36 +00:00
02855719b8
0e61be85 Merge pull request #289 from sartography/improvement/execution-and-serialization-cleanup 527684da fix some typos in the class & method docs 0dff44a4 Merge branch 'main' into improvement/execution-and-serialization-cleanup 64737498 Allow for other PythonScriptEngine environments besides task data (#288) dd63e916 remove some unused tests & diagrams 24aae519 clean up various small stuff 3b2dc35d use context when opening files for parsing 69eec3eb update class/method docs 24528dfb move all spec conversion classes to top level 5af33b11 remove some unused methods related to old serializer 931b90fb reorganize serializer 4e81ed29 consolidate pointless serializer classes d62acf02 change task_spec._update_hook to return a boolean indicating whether the task is ready git-subtree-dir: SpiffWorkflow git-subtree-split: 0e61be85c47474a33037e6f398e64c96e02f13ad
109 lines
3.8 KiB
Python
109 lines
3.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
from copy import deepcopy
|
|
|
|
from SpiffWorkflow.task import TaskState
|
|
from .BpmnSpecMixin import BpmnSpecMixin
|
|
from ..exceptions import WorkflowDataException
|
|
|
|
|
|
class SubWorkflowTask(BpmnSpecMixin):
|
|
"""
|
|
Task Spec for a bpmn node containing a subworkflow.
|
|
"""
|
|
def __init__(self, wf_spec, name, subworkflow_spec, transaction=False, **kwargs):
|
|
"""
|
|
Constructor.
|
|
|
|
:param bpmn_wf_spec: the BpmnProcessSpec for the sub process.
|
|
:param bpmn_wf_class: the BpmnWorkflow class to instantiate
|
|
"""
|
|
super(SubWorkflowTask, self).__init__(wf_spec, name, **kwargs)
|
|
self.spec = subworkflow_spec
|
|
self.transaction = transaction
|
|
|
|
@property
|
|
def spec_type(self):
|
|
return 'Subprocess'
|
|
|
|
def _on_ready_before_hook(self, my_task):
|
|
subworkflow = my_task.workflow.create_subprocess(my_task, self.spec, self.name)
|
|
subworkflow.completed_event.connect(self._on_subworkflow_completed, my_task)
|
|
subworkflow.data = deepcopy(my_task.workflow.data)
|
|
|
|
def _on_ready_hook(self, my_task):
|
|
|
|
super()._on_ready_hook(my_task)
|
|
self.start_workflow(my_task)
|
|
|
|
def _on_subworkflow_completed(self, subworkflow, my_task):
|
|
|
|
if len(subworkflow.spec.data_outputs) == 0:
|
|
# Copy all workflow data if no outputs are specified
|
|
my_task.data = deepcopy(subworkflow.last_task.data)
|
|
else:
|
|
end = subworkflow.get_tasks_from_spec_name('End', workflow=subworkflow)
|
|
# Otherwise only copy data with the specified names
|
|
for var in subworkflow.spec.data_outputs:
|
|
try:
|
|
var.copy(end[0], my_task, data_output=True)
|
|
except WorkflowDataException as wde:
|
|
wde.add_note("A Data Output was not provided as promised.")
|
|
raise wde
|
|
|
|
my_task._set_state(TaskState.READY)
|
|
|
|
def _update_hook(self, my_task):
|
|
wf = my_task.workflow._get_outermost_workflow(my_task)
|
|
if my_task.id not in wf.subprocesses:
|
|
return super()._update_hook(my_task)
|
|
|
|
def _on_cancel(self, my_task):
|
|
subworkflow = my_task.workflow.get_subprocess(my_task)
|
|
if subworkflow is not None:
|
|
subworkflow.cancel()
|
|
|
|
def start_workflow(self, my_task):
|
|
|
|
subworkflow = my_task.workflow.get_subprocess(my_task)
|
|
start = subworkflow.get_tasks_from_spec_name('Start', workflow=subworkflow)
|
|
|
|
if len(subworkflow.spec.data_inputs) == 0:
|
|
# Copy all task data into start task if no inputs specified
|
|
start[0].set_data(**my_task.data)
|
|
else:
|
|
# Otherwise copy only task data with the specified names
|
|
for var in subworkflow.spec.data_inputs:
|
|
try:
|
|
var.copy(my_task, start[0], data_input=True)
|
|
except WorkflowDataException as wde:
|
|
wde.add_note("You are missing a required Data Input for a call activity.")
|
|
raise wde
|
|
for child in subworkflow.task_tree.children:
|
|
child.task_spec._update(child)
|
|
|
|
my_task._set_state(TaskState.WAITING)
|
|
|
|
def task_will_set_children_future(self, my_task):
|
|
my_task.workflow.delete_subprocess(my_task)
|
|
|
|
|
|
class CallActivity(SubWorkflowTask):
|
|
|
|
def __init__(self, wf_spec, name, subworkflow_spec, **kwargs):
|
|
super(CallActivity, self).__init__(wf_spec, name, subworkflow_spec, False, **kwargs)
|
|
|
|
@property
|
|
def spec_type(self):
|
|
return 'Call Activity'
|
|
|
|
|
|
class TransactionSubprocess(SubWorkflowTask):
|
|
|
|
def __init__(self, wf_spec, name, subworkflow_spec, **kwargs):
|
|
super(TransactionSubprocess, self).__init__(wf_spec, name, subworkflow_spec, True, **kwargs)
|
|
|
|
@property
|
|
def spec_type(self):
|
|
return 'Transactional Subprocess'
|
|
|