Fixing workflow handlers to return all possible commands
Change-Id: I0f2f7746d7071c5eded30e75e41e80dfbe792af7
This commit is contained in:
parent
e458708b73
commit
3015931b7f
@ -56,6 +56,8 @@ class RunTask(EngineCommand):
|
|||||||
self._before_task_start()
|
self._before_task_start()
|
||||||
self._run_task()
|
self._run_task()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def _prepare_task(self, exec_db, wf_handler):
|
def _prepare_task(self, exec_db, wf_handler):
|
||||||
if self.task_db:
|
if self.task_db:
|
||||||
return
|
return
|
||||||
@ -195,10 +197,16 @@ class RollbackWorkflow(EngineCommand):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
CMD_MAP = {
|
RESERVED_COMMANDS = {
|
||||||
'run_task': RunTask,
|
|
||||||
'fail': FailWorkflow,
|
'fail': FailWorkflow,
|
||||||
'succeed': SucceedWorkflow,
|
'succeed': SucceedWorkflow,
|
||||||
'pause': PauseWorkflow,
|
'pause': PauseWorkflow,
|
||||||
'rollback': PauseWorkflow
|
'rollback': PauseWorkflow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_reserved_command(cmd_name):
|
||||||
|
if cmd_name not in RESERVED_COMMANDS:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return RESERVED_COMMANDS[cmd_name]()
|
||||||
|
@ -127,7 +127,8 @@ class DefaultEngine(base.Engine):
|
|||||||
return
|
return
|
||||||
|
|
||||||
for cmd in commands:
|
for cmd in commands:
|
||||||
cmd.run(exec_db, wf_handler)
|
if not cmd.run(exec_db, wf_handler):
|
||||||
|
break
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_db_execution(wf_db, wf_spec, wf_input, params):
|
def _create_db_execution(wf_db, wf_spec, wf_input, params):
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
import testtools
|
|
||||||
|
|
||||||
from mistral.db.v2 import api as db_api
|
from mistral.db.v2 import api as db_api
|
||||||
from mistral.openstack.common import log as logging
|
from mistral.openstack.common import log as logging
|
||||||
@ -53,8 +52,6 @@ workflows:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# TODO(rakhmerov): Delete this decorator when tests pass.
|
|
||||||
@testtools.skip('')
|
|
||||||
class EngineInstructionsTest(base.EngineTestCase):
|
class EngineInstructionsTest(base.EngineTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(EngineInstructionsTest, self).setUp()
|
super(EngineInstructionsTest, self).setUp()
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
from mistral.engine1 import commands
|
|
||||||
from mistral import exceptions as exc
|
from mistral import exceptions as exc
|
||||||
from mistral.openstack.common import log as logging
|
from mistral.openstack.common import log as logging
|
||||||
from mistral import utils
|
from mistral import utils
|
||||||
@ -78,9 +77,9 @@ class WorkflowHandler(object):
|
|||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
task_specs = self._find_next_tasks(task_db)
|
commands = self._find_next_commands(task_db)
|
||||||
|
|
||||||
if len(task_specs) == 0:
|
if len(commands) == 0:
|
||||||
# If there are no running tasks at this point we can conclude that
|
# If there are no running tasks at this point we can conclude that
|
||||||
# the workflow has finished.
|
# the workflow has finished.
|
||||||
if not self._find_running_tasks():
|
if not self._find_running_tasks():
|
||||||
@ -98,16 +97,16 @@ class WorkflowHandler(object):
|
|||||||
task_out_ctx
|
task_out_ctx
|
||||||
)
|
)
|
||||||
|
|
||||||
return [commands.RunTask(t_s) for t_s in task_specs]
|
return commands
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def _find_next_tasks(self, task_db):
|
def _find_next_commands(self, task_db):
|
||||||
"""Finds tasks that should run next.
|
"""Finds commands that should run next.
|
||||||
|
|
||||||
A concrete algorithm of finding such tasks depends on a concrete
|
A concrete algorithm of finding such tasks depends on a concrete
|
||||||
workflow handler.
|
workflow handler.
|
||||||
:param task_db: Task DB model causing the operation (completed).
|
:param task_db: Task DB model causing the operation (completed).
|
||||||
:return: List of task specifications.
|
:return: List of engine commands.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -46,15 +46,15 @@ class DirectWorkflowHandler(base.WorkflowHandler):
|
|||||||
# so we may need to get rid of it at all.
|
# so we may need to get rid of it at all.
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def _find_next_tasks(self, task_db):
|
def _find_next_commands(self, task_db):
|
||||||
"""Finds tasks that should run after completing given task.
|
"""Finds commands that should run after completing given task.
|
||||||
|
|
||||||
Expression 'on_complete' is not mutually exclusive to 'on_success'
|
Expression 'on_complete' is not mutually exclusive to 'on_success'
|
||||||
and 'on_error'.
|
and 'on_error'.
|
||||||
:param task_db: Task DB model.
|
:param task_db: Task DB model.
|
||||||
:return: List of task specifications.
|
:return: List of task specifications.
|
||||||
"""
|
"""
|
||||||
task_specs = []
|
commands = []
|
||||||
|
|
||||||
t_name = task_db.name
|
t_name = task_db.name
|
||||||
t_state = task_db.state
|
t_state = task_db.state
|
||||||
@ -67,29 +67,34 @@ class DirectWorkflowHandler(base.WorkflowHandler):
|
|||||||
on_error = tasks_spec[t_name].get_on_error()
|
on_error = tasks_spec[t_name].get_on_error()
|
||||||
|
|
||||||
if on_error:
|
if on_error:
|
||||||
task_specs = self._get_tasks_to_schedule(on_error, ctx)
|
commands = self._get_next_commands(on_error, ctx)
|
||||||
|
|
||||||
elif t_state == states.SUCCESS:
|
elif t_state == states.SUCCESS:
|
||||||
on_success = tasks_spec[t_name].get_on_success()
|
on_success = tasks_spec[t_name].get_on_success()
|
||||||
|
|
||||||
if on_success:
|
if on_success:
|
||||||
task_specs = self._get_tasks_to_schedule(on_success, ctx)
|
commands = self._get_next_commands(on_success, ctx)
|
||||||
|
|
||||||
if states.is_finished(t_state):
|
if states.is_finished(t_state):
|
||||||
on_complete = tasks_spec[t_name].get_on_complete()
|
on_complete = tasks_spec[t_name].get_on_complete()
|
||||||
|
|
||||||
if on_complete:
|
if on_complete:
|
||||||
task_specs += self._get_tasks_to_schedule(on_complete, ctx)
|
commands += self._get_next_commands(on_complete, ctx)
|
||||||
|
|
||||||
LOG.debug("Found tasks: %s" % task_specs)
|
LOG.debug("Found commands: %s" % commands)
|
||||||
|
|
||||||
return task_specs
|
return commands
|
||||||
|
|
||||||
def _get_tasks_to_schedule(self, task_conditions, ctx):
|
def _get_next_commands(self, cmd_conditions, ctx):
|
||||||
task_specs = []
|
commands = []
|
||||||
|
|
||||||
for t_name, condition in task_conditions.iteritems():
|
for t_name, condition in cmd_conditions.iteritems():
|
||||||
if not condition or expr.evaluate(condition, ctx):
|
if not condition or expr.evaluate(condition, ctx):
|
||||||
task_specs.append(self.wf_spec.get_tasks()[t_name])
|
commands.append(self.build_command(t_name))
|
||||||
|
|
||||||
return task_specs
|
return commands
|
||||||
|
|
||||||
|
def build_command(self, cmd_name):
|
||||||
|
cmd = commands.get_reserved_command(cmd_name)
|
||||||
|
|
||||||
|
return cmd or commands.RunTask(self.wf_spec.get_tasks()[cmd_name])
|
||||||
|
@ -57,8 +57,9 @@ class ReverseWorkflowHandler(base.WorkflowHandler):
|
|||||||
return [self.wf_spec.get_tasks()[t_name]
|
return [self.wf_spec.get_tasks()[t_name]
|
||||||
for t_name in task_spec.get_requires() or []]
|
for t_name in task_spec.get_requires() or []]
|
||||||
|
|
||||||
def _find_next_tasks(self, task_db):
|
def _find_next_commands(self, task_db):
|
||||||
"""Finds all tasks with resolved dependencies.
|
"""Finds all tasks with resolved dependencies and return them
|
||||||
|
in the form of engine commands.
|
||||||
|
|
||||||
:param task_db: Task DB model causing the operation.
|
:param task_db: Task DB model causing the operation.
|
||||||
:return: Tasks with resolved dependencies.
|
:return: Tasks with resolved dependencies.
|
||||||
@ -89,7 +90,7 @@ class ReverseWorkflowHandler(base.WorkflowHandler):
|
|||||||
if not t_db or t_db.state == states.IDLE:
|
if not t_db or t_db.state == states.IDLE:
|
||||||
resolved_task_specs.append(t_spec)
|
resolved_task_specs.append(t_spec)
|
||||||
|
|
||||||
return resolved_task_specs
|
return [commands.RunTask(t_s) for t_s in resolved_task_specs]
|
||||||
|
|
||||||
def _find_tasks_without_dependencies(self, task_spec):
|
def _find_tasks_without_dependencies(self, task_spec):
|
||||||
"""Given a target task name finds tasks with no dependencies.
|
"""Given a target task name finds tasks with no dependencies.
|
||||||
|
Loading…
Reference in New Issue
Block a user