Example #1
0
def complete_task(task_ex, state, state_info):
    task = _build_task_from_execution(
        spec_parser.get_workflow_spec_by_id(task_ex.workflow_id),
        task_ex
    )

    try:
        task.complete(state, state_info)
    except exc.MistralException as e:
        wf_ex = task_ex.workflow_execution

        msg = (
            "Failed to complete task [wf=%s, task=%s]: %s\n%s" %
            (wf_ex, task_ex.name, e, tb.format_exc())
        )

        LOG.error(msg)

        task.set_state(states.ERROR, msg)

        wf_handler.fail_workflow(wf_ex, msg)

        return

    if task.is_completed():
        wf_handler.on_task_complete(task_ex)
Example #2
0
def run_task(wf_cmd):
    """Runs workflow task.

    :param wf_cmd: Workflow command.
    """

    task = _build_task_from_command(wf_cmd)

    try:
        task.run()
    except exc.MistralException as e:
        wf_ex = wf_cmd.wf_ex
        task_spec = wf_cmd.task_spec

        msg = (
            "Failed to run task [wf=%s, task=%s]: %s\n%s" %
            (wf_ex, task_spec.get_name(), e, tb.format_exc())
        )

        LOG.error(msg)

        task.set_state(states.ERROR, msg)

        wf_handler.fail_workflow(wf_ex, msg)

        return

    if task.is_completed():
        wf_handler.on_task_complete(task.task_ex)
Example #3
0
def run_task(wf_cmd):
    """Runs workflow task.

    :param wf_cmd: Workflow command.
    """

    task = _build_task_from_command(wf_cmd)

    try:
        task.run()
    except exc.MistralException as e:
        wf_ex = wf_cmd.wf_ex
        task_spec = wf_cmd.task_spec

        msg = ("Failed to run task [wf=%s, task=%s]: %s\n%s" %
               (wf_ex, task_spec.get_name(), e, tb.format_exc()))

        LOG.error(msg)

        task.set_state(states.ERROR, msg)

        wf_handler.fail_workflow(wf_ex, msg)

        return

    if task.is_completed():
        wf_handler.on_task_complete(task.task_ex)
Example #4
0
def continue_task(task_ex):
    wf_spec = spec_parser.get_workflow_spec_by_execution_id(
        task_ex.workflow_execution_id)

    task = _build_task_from_execution(wf_spec, task_ex)

    try:
        task.set_state(states.RUNNING, None)

        task.run()
    except exc.MistralException as e:
        wf_ex = task_ex.workflow_execution

        msg = ("Failed to run task [wf=%s, task=%s]: %s\n%s" %
               (wf_ex, task_ex.name, e, tb.format_exc()))

        LOG.error(msg)

        task.set_state(states.ERROR, msg)

        wf_handler.fail_workflow(wf_ex, msg)

        return

    if task.is_completed():
        wf_handler.schedule_on_task_complete(task_ex)
Example #5
0
def fail_task(task_ex, msg):
    task = _build_task_from_execution(
        spec_parser.get_workflow_spec_by_id(task_ex.workflow_id),
        task_ex
    )

    task.set_state(states.ERROR, msg)

    wf_handler.fail_workflow(task_ex.workflow_execution, msg)
Example #6
0
    def _stop_workflow(wf_ex, state, message=None):
        if state == states.SUCCESS:
            wf_ctrl = wf_base.get_controller(wf_ex)

            final_context = {}

            try:
                final_context = wf_ctrl.evaluate_workflow_final_context()
            except Exception as e:
                LOG.warning(
                    'Failed to get final context for %s: %s' % (wf_ex, e)
                )

            wf_spec = spec_parser.get_workflow_spec(wf_ex.spec)

            return wf_handler.succeed_workflow(
                wf_ex,
                final_context,
                wf_spec,
                message
            )
        elif state == states.ERROR:
            return wf_handler.fail_workflow(wf_ex, message)

        return wf_ex
Example #7
0
    def _check_workflow_completion(wf_ex, wf_ctrl):
        if states.is_paused_or_completed(wf_ex.state):
            return

        if wf_utils.find_incomplete_task_executions(wf_ex):
            return

        if wf_ctrl.all_errors_handled():
            wf_handler.succeed_workflow(
                wf_ex,
                wf_ctrl.evaluate_workflow_final_context()
            )
        else:
            state_info = wf_utils.construct_fail_info_message(wf_ctrl, wf_ex)

            wf_handler.fail_workflow(wf_ex, state_info)
Example #8
0
    def _check_workflow_completion(wf_ex, action_ex, wf_ctrl):
        if states.is_paused_or_completed(wf_ex.state):
            return

        if wf_utils.find_incomplete_tasks(wf_ex):
            return

        if wf_ctrl.all_errors_handled():
            wf_handler.succeed_workflow(
                wf_ex, wf_ctrl.evaluate_workflow_final_context())
        else:
            result_str = (str(action_ex.output.get('result', 'Unknown'))
                          if action_ex.output else 'Unknown')

            state_info = ("Failure caused by error in task '%s': %s" %
                          (action_ex.task_execution.name, result_str))

            wf_handler.fail_workflow(wf_ex, state_info)
Example #9
0
def on_action_complete(action_ex):
    """Handles action completion event.

    :param action_ex: Action execution.
    """

    task_ex = action_ex.task_execution

    if not task_ex:
        return

    task_spec = spec_parser.get_task_spec(task_ex.spec)

    wf_ex = task_ex.workflow_execution

    task = _create_task(
        wf_ex,
        task_spec,
        task_ex.in_context,
        task_ex
    )

    try:
        task.on_action_complete(action_ex)
    except exc.MistralException as e:
        task_ex = action_ex.task_execution
        wf_ex = task_ex.workflow_execution

        msg = ("Failed to handle action completion [wf=%s, task=%s,"
               " action=%s]: %s\n%s" %
               (wf_ex.name, task_ex.name, action_ex.name, e, tb.format_exc()))

        LOG.error(msg)

        task.set_state(states.ERROR, msg)

        wf_handler.fail_workflow(wf_ex, msg)

        return

    if task.is_completed():
        wf_handler.on_task_complete(task_ex)
Example #10
0
def on_action_complete(action_ex):
    """Handles action completion event.

    :param action_ex: Action execution.
    """

    task_ex = action_ex.task_execution

    if not task_ex:
        return

    task_spec = spec_parser.get_task_spec(task_ex.spec)

    wf_ex = task_ex.workflow_execution

    task = _create_task(
        wf_ex,
        spec_parser.get_workflow_spec_by_id(wf_ex.workflow_id),
        task_spec,
        task_ex.in_context,
        task_ex
    )

    try:
        task.on_action_complete(action_ex)
    except exc.MistralException as e:
        wf_ex = task_ex.workflow_execution

        msg = ("Failed to handle action completion [wf=%s, task=%s,"
               " action=%s]: %s\n%s" %
               (wf_ex.name, task_ex.name, action_ex.name, e, tb.format_exc()))

        LOG.error(msg)

        task.set_state(states.ERROR, msg)

        wf_handler.fail_workflow(wf_ex, msg)

        return

    if task.is_completed():
        wf_handler.on_task_complete(task_ex)
Example #11
0
    def _dispatch_workflow_commands(self, wf_ex, wf_cmds, wf_spec):
        if not wf_cmds:
            return

        for cmd in wf_cmds:
            if isinstance(cmd, commands.RunTask) and cmd.is_waiting():
                task_handler.defer_task(cmd)
            elif isinstance(cmd, commands.RunTask):
                task_ex = task_handler.run_new_task(cmd, wf_spec)

                if task_ex.state == states.ERROR:
                    wf_handler.fail_workflow(
                        wf_ex,
                        'Failed to start task [task_ex=%s]: %s' %
                        (task_ex, task_ex.state_info)
                    )
            elif isinstance(cmd, commands.RunExistingTask):
                task_ex = task_handler.run_existing_task(
                    cmd.task_ex.id,
                    reset=cmd.reset
                )

                if task_ex.state == states.ERROR:
                    wf_handler.fail_workflow(
                        wf_ex,
                        'Failed to start task [task_ex=%s]: %s' %
                        (task_ex, task_ex.state_info)
                    )
            elif isinstance(cmd, commands.SetWorkflowState):
                if states.is_completed(cmd.new_state):
                    self._stop_workflow(cmd.wf_ex, cmd.new_state, cmd.msg)
                else:
                    wf_handler.set_execution_state(wf_ex, cmd.new_state)
            elif isinstance(cmd, commands.Noop):
                # Do nothing.
                pass
            else:
                raise RuntimeError('Unsupported workflow command: %s' % cmd)

            if wf_ex.state != states.RUNNING:
                break
Example #12
0
    def _check_workflow_completion(wf_ex, action_ex, wf_ctrl):
        if states.is_paused_or_completed(wf_ex.state):
            return

        if wf_utils.find_incomplete_tasks(wf_ex):
            return

        if wf_ctrl.all_errors_handled():
            wf_handler.succeed_workflow(
                wf_ex,
                wf_ctrl.evaluate_workflow_final_context()
            )
        else:
            result_str = str(action_ex.output.get('result', "Unknown"))

            state_info = (
                "Failure caused by error in task '%s': %s" %
                (action_ex.task_execution.name, result_str)
            )

            wf_handler.fail_workflow(wf_ex, state_info)
Example #13
0
    def _check_workflow_completion(wf_ex, wf_ctrl):
        if states.is_paused_or_completed(wf_ex.state):
            return

        # Workflow is not completed if there are any incomplete task
        # executions that are not in WAITING state. If all incomplete
        # tasks are waiting and there are unhandled errors, then these
        # tasks will not reach completion. In this case, mark the
        # workflow complete.
        incomplete_tasks = wf_utils.find_incomplete_task_executions(wf_ex)

        if any(not states.is_waiting(t.state) for t in incomplete_tasks):
            return

        if wf_ctrl.all_errors_handled():
            wf_handler.succeed_workflow(
                wf_ex, wf_ctrl.evaluate_workflow_final_context())
        else:
            state_info = wf_utils.construct_fail_info_message(wf_ctrl, wf_ex)

            wf_handler.fail_workflow(wf_ex, state_info)
Example #14
0
def run_task(wf_cmd):
    """Runs workflow task.

    :param wf_cmd: Workflow command.
    """

    task = _build_task_from_command(wf_cmd)

    try:
        task.run()
    except exc.MistralException as e:
        wf_ex = wf_cmd.wf_ex
        task_spec = wf_cmd.task_spec

        msg = ("Failed to run task [wf=%s, task=%s]: %s\n%s" %
               (wf_ex, task_spec.get_name(), e, tb.format_exc()))

        LOG.error(msg)

        task.set_state(states.ERROR, msg)

        wf_handler.fail_workflow(wf_ex, msg)

        return

    if not task.task_ex:
        # It is possible that task execution was not created
        # (and therefore not associated with Task instance).
        # For example, in case of 'join' that has already been
        # created by a different transaction. In this case
        # we should skip post completion scheduled checks.
        return

    if task.is_waiting():
        _schedule_refresh_task_state(task.task_ex)

    if task.is_completed():
        wf_handler.schedule_on_task_complete(task.task_ex)
Example #15
0
    def _on_task_state_change(self, task_ex, wf_ex, wf_spec):
        task_spec = wf_spec.get_tasks()[task_ex.name]

        if task_handler.is_task_completed(task_ex, task_spec):
            task_handler.after_task_complete(task_ex, task_spec, wf_spec)

            # Ignore DELAYED state.
            if task_ex.state == states.RUNNING_DELAYED:
                return

            wf_ctrl = wf_base.get_controller(wf_ex, wf_spec)

            # Calculate commands to process next.
            try:
                cmds = wf_ctrl.continue_workflow()
            except exc.YaqlEvaluationException as e:
                LOG.error(
                    'YAQL error occurred while calculating next workflow '
                    'commands [wf_ex_id=%s, task_ex_id=%s]: %s',
                    wf_ex.id, task_ex.id, e
                )

                wf_handler.fail_workflow(wf_ex, str(e))

                return

            # Mark task as processed after all decisions have been made
            # upon its completion.
            task_ex.processed = True

            self._dispatch_workflow_commands(wf_ex, cmds, wf_spec)

            self._check_workflow_completion(wf_ex, wf_ctrl, wf_spec)
        elif task_handler.need_to_continue(task_ex, task_spec):
            # Re-run existing task.
            cmds = [commands.RunExistingTask(task_ex, reset=False)]

            self._dispatch_workflow_commands(wf_ex, cmds, wf_spec)
Example #16
0
def continue_task(task_ex):
    task = _build_task_from_execution(task_ex)

    try:
        task.run()
    except exc.MistralException as e:
        wf_ex = task_ex.workflow_execution

        msg = (
            "Failed to run task [wf=%s, task=%s]: %s\n%s" %
            (wf_ex, task_ex.name, e, tb.format_exc())
        )

        LOG.error(msg)

        task.set_state(states.ERROR, msg)

        wf_handler.fail_workflow(wf_ex, msg)

        return

    if task.is_completed():
        wf_handler.on_task_complete(task_ex)
    def _check_workflow_completion(wf_ex, wf_ctrl, wf_spec):
        if states.is_paused_or_completed(wf_ex.state):
            return

        # Workflow is not completed if there are any incomplete task
        # executions that are not in WAITING state. If all incomplete
        # tasks are waiting and there are unhandled errors, then these
        # tasks will not reach completion. In this case, mark the
        # workflow complete.
        incomplete_tasks = wf_utils.find_incomplete_task_executions(wf_ex)

        if any(not states.is_waiting(t.state) for t in incomplete_tasks):
            return

        if wf_ctrl.all_errors_handled():
            wf_handler.succeed_workflow(
                wf_ex,
                wf_ctrl.evaluate_workflow_final_context(),
                wf_spec
            )
        else:
            state_info = wf_utils.construct_fail_info_message(wf_ctrl, wf_ex)

            wf_handler.fail_workflow(wf_ex, state_info)
Example #18
0
def fail_task(task_ex, msg):
    task = _build_task_from_execution(task_ex)

    task.set_state(states.ERROR, msg)

    wf_handler.fail_workflow(task_ex.workflow_execution, msg)
Example #19
0
def fail_task(task_ex, msg):
    task = _build_task_from_execution(task_ex)

    task.set_state(states.ERROR, msg)

    wf_handler.fail_workflow(task_ex.workflow_execution, msg)