Skip to content

Commit 8aae4a4

Browse files
committed
fixed bug where the subflow would not be connected to any other action in the set of its actions; also renamed the source_code function to generate
Signed-off-by: Pedro Escaleira <pedroescaleira@hotmail.com>
1 parent 197a540 commit 8aae4a4

File tree

2 files changed

+111
-101
lines changed

2 files changed

+111
-101
lines changed

serverlessworkflow/sdk/state_machine_generator.py

Lines changed: 104 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def __init__(
4747
"The provided state machine can not be of the HierarchicalMachine type."
4848
)
4949

50-
def source_code(self):
50+
def generate(self):
5151
self.definitions()
5252
self.transitions()
5353

@@ -240,122 +240,130 @@ def callback_state_details(self):
240240
actions=[action],
241241
)
242242

243-
def generate_composite_state(
243+
def get_subflow_state(
244+
self, machine_state: NestedState, state_name: str, actions: List[Action]
245+
):
246+
added_states = {}
247+
for i, action in enumerate(actions):
248+
if action.subFlowRef:
249+
if isinstance(action.subFlowRef, str):
250+
workflow_id = action.subFlowRef
251+
workflow_version = None
252+
else:
253+
workflow_id = action.subFlowRef.workflowId
254+
workflow_version = action.subFlowRef.version
255+
none_found = True
256+
for sf in self.subflows:
257+
if sf.id == workflow_id and (
258+
(workflow_version and sf.version == workflow_version)
259+
or not workflow_version
260+
):
261+
none_found = False
262+
new_machine = HierarchicalMachine(
263+
model=None, initial=None, auto_transitions=False
264+
)
265+
266+
# Generate the state machine for the subflow
267+
for index, state in enumerate(sf.states):
268+
StateMachineGenerator(
269+
state=state,
270+
state_machine=new_machine,
271+
is_first_state=index == 0,
272+
get_actions=self.get_actions,
273+
subflows=self.subflows,
274+
).generate()
275+
276+
# Convert the new_machine into a NestedState
277+
added_states[i] = self.subflow_state_name(
278+
action=action, subflow=sf
279+
)
280+
nested_state = NestedState(added_states[i])
281+
machine_state.add_substate(nested_state)
282+
self.state_machine_to_nested_state(
283+
state_name=state_name,
284+
state_machine=new_machine,
285+
nested_state=nested_state,
286+
)
287+
288+
if none_found:
289+
warnings.warn(
290+
f"Specified subflow [{workflow_id} {workflow_version if workflow_version else ''}] not found.",
291+
category=UserWarning,
292+
)
293+
return added_states
294+
295+
def generate_actions_info(
244296
self,
245297
machine_state: NestedState,
246298
state_name: str,
247299
actions: List[Dict[str, Any]],
248300
action_mode: str = "sequential",
249301
):
250302
parallel_states = []
251-
252303
if actions:
304+
new_subflows_names = self.get_subflow_state(
305+
machine_state=machine_state, state_name=state_name, actions=actions
306+
)
253307
for i, action in enumerate(actions):
254-
fn_name = (
255-
self.get_function_name(action.functionRef)
256-
if isinstance(action.functionRef, str)
257-
else (
258-
action.functionRef.refName
259-
if isinstance(action.functionRef, FunctionRef)
260-
else None
308+
name = None
309+
if action.functionRef:
310+
name = (
311+
self.get_function_name(action.functionRef)
312+
if isinstance(action.functionRef, str)
313+
else (
314+
action.functionRef.refName
315+
if isinstance(action.functionRef, FunctionRef)
316+
else None
317+
)
261318
)
262-
)
263-
if fn_name:
264-
if fn_name not in machine_state.states.keys():
265-
machine_state.add_substate(NestedState(fn_name))
319+
if name not in machine_state.states.keys():
320+
machine_state.add_substate(NestedState(name))
321+
elif action.subFlowRef:
322+
name = new_subflows_names.get(i)
323+
if name:
266324
if action_mode == "sequential":
267325
if i < len(actions) - 1:
268-
next_fn_name = (
269-
self.get_function_name(actions[i + 1].functionRef)
270-
if isinstance(actions[i + 1].functionRef, str)
271-
else (
272-
actions[i + 1].functionRef.refName
273-
if isinstance(
274-
actions[i + 1].functionRef, FunctionRef
326+
# get next name
327+
next_name = None
328+
if actions[i + 1].functionRef:
329+
next_name = (
330+
self.get_function_name(actions[i + 1].functionRef)
331+
if isinstance(actions[i + 1].functionRef, str)
332+
else (
333+
actions[i + 1].functionRef.refName
334+
if isinstance(
335+
actions[i + 1].functionRef, FunctionRef
336+
)
337+
else None
275338
)
276-
else None
277339
)
278-
)
279-
if (
280-
next_fn_name
281-
not in self.state_machine.get_state(
282-
state_name
283-
).states.keys()
284-
):
285-
machine_state.add_substate(NestedState(next_fn_name))
340+
if (
341+
next_name
342+
not in self.state_machine.get_state(
343+
state_name
344+
).states.keys()
345+
):
346+
machine_state.add_substate(NestedState(next_name))
347+
elif actions[i + 1].subFlowRef:
348+
next_name = new_subflows_names.get(i + 1)
286349
self.state_machine.add_transition(
287350
trigger="",
288-
source=f"{state_name}.{fn_name}",
289-
dest=f"{state_name}.{next_fn_name}",
351+
source=f"{state_name}.{name}",
352+
dest=f"{state_name}.{next_name}",
290353
)
291354
if i == 0:
292-
machine_state.initial = fn_name
355+
machine_state.initial = name
293356
elif action_mode == "parallel":
294-
parallel_states.append(fn_name)
357+
parallel_states.append(name)
295358
if action_mode == "parallel":
296359
machine_state.initial = parallel_states
297360

298-
def generate_actions_info(
299-
self,
300-
machine_state: NestedState,
301-
state_name: str,
302-
actions: List[Action],
303-
action_mode: str = "sequential",
304-
):
305-
if actions:
306-
if self.get_actions:
307-
self.generate_composite_state(
308-
machine_state,
309-
state_name,
310-
actions,
311-
action_mode,
312-
)
313-
for action in actions:
314-
if action.subFlowRef:
315-
if isinstance(action.subFlowRef, str):
316-
workflow_id = action.subFlowRef
317-
workflow_version = None
318-
else:
319-
workflow_id = action.subFlowRef.workflowId
320-
workflow_version = action.subFlowRef.version
321-
none_found = True
322-
for sf in self.subflows:
323-
if sf.id == workflow_id and (
324-
(workflow_version and sf.version == workflow_version)
325-
or not workflow_version
326-
):
327-
none_found = False
328-
new_machine = HierarchicalMachine(
329-
model=None, initial=None, auto_transitions=False
330-
)
331-
332-
# Generate the state machine for the subflow
333-
for index, state in enumerate(sf.states):
334-
StateMachineGenerator(
335-
state=state,
336-
state_machine=new_machine,
337-
is_first_state=index == 0,
338-
get_actions=self.get_actions,
339-
subflows=self.subflows,
340-
).source_code()
341-
342-
# Convert the new_machine into a NestedState
343-
nested_state = NestedState(
344-
action.name
345-
if action.name
346-
else f"{sf.id}/{sf.version.replace(NestedState.separator, '-')}"
347-
)
348-
self.state_machine_to_nested_state(
349-
machine_state=machine_state,
350-
state_name=state_name,
351-
state_machine=new_machine,
352-
nested_state=nested_state,
353-
)
354-
if none_found:
355-
warnings.warn(
356-
f"Specified subflow [{workflow_id} {workflow_version if workflow_version else ''}] not found.",
357-
category=UserWarning,
358-
)
361+
def subflow_state_name(self, action: Action, subflow: Workflow):
362+
return (
363+
action.name
364+
if action.name
365+
else f"{subflow.id}/{subflow.version.replace(NestedState.separator, '-')}"
366+
)
359367

360368
def add_all_sub_states(
361369
cls,
@@ -367,15 +375,14 @@ def add_all_sub_states(
367375
for substate in original_state.states.values():
368376
new_state.add_substate(ns := NestedState(substate.name))
369377
cls.add_all_sub_states(substate, ns)
378+
new_state.initial = original_state.initial
370379

371380
def state_machine_to_nested_state(
372381
self,
373-
machine_state: NestedState,
374382
state_name: str,
375383
state_machine: HierarchicalMachine,
376384
nested_state: NestedState,
377385
) -> NestedState:
378-
machine_state.add_substate(nested_state)
379386
self.add_all_sub_states(state_machine, nested_state)
380387

381388
for trigger, event in state_machine.events.items():

serverlessworkflow/sdk/state_machine_helper.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@ def __init__(
3232
)
3333
for index, state in enumerate(workflow.states):
3434
StateMachineGenerator(
35-
state=state, state_machine=self.machine, is_first_state=index == 0, get_actions=self.get_actions, subflows=subflows
36-
).source_code()
37-
38-
35+
state=state,
36+
state_machine=self.machine,
37+
is_first_state=index == 0,
38+
get_actions=self.get_actions,
39+
subflows=subflows,
40+
).generate()
41+
3942
delattr(self.machine, "get_graph")
4043
self.machine.add_model(machine_type.self_literal)
4144

0 commit comments

Comments
 (0)