예제 #1
0
    def _continue_workflow(self, wf_ex, task_ex=None, reset=True):
        wf_handler.set_execution_state(wf_ex, states.RUNNING)

        wf_ctrl = wf_base.WorkflowController.get_controller(wf_ex)

        # Calculate commands to process next.
        cmds = wf_ctrl.continue_workflow(task_ex=task_ex, reset=reset)

        # When resuming a workflow we need to ignore all 'pause'
        # commands because workflow controller takes tasks that
        # completed within the period when the workflow was pause.
        cmds = filter(
            lambda c: not isinstance(c, commands.PauseWorkflow),
            cmds
        )

        # Since there's no explicit task causing the operation
        # we need to mark all not processed tasks as processed
        # because workflow controller takes only completed tasks
        # with flag 'processed' equal to False.
        for t_ex in wf_ex.task_executions:
            if states.is_completed(t_ex.state) and not t_ex.processed:
                t_ex.processed = True

        self._dispatch_workflow_commands(wf_ex, cmds)

        if not cmds:
            if not wf_utils.find_incomplete_task_executions(wf_ex):
                wf_handler.succeed_workflow(
                    wf_ex,
                    wf_ctrl.evaluate_workflow_final_context()
                )

        return wf_ex.get_clone()
예제 #2
0
    def _continue_workflow(self, wf_ex, task_ex=None, reset=True, env=None):
        wf_ex = wf_service.update_workflow_execution_env(wf_ex, env)

        wf_handler.set_execution_state(wf_ex,
                                       states.RUNNING,
                                       set_upstream=True)

        wf_ctrl = wf_base.WorkflowController.get_controller(wf_ex)

        # Calculate commands to process next.
        cmds = wf_ctrl.continue_workflow(task_ex=task_ex, reset=reset, env=env)

        # When resuming a workflow we need to ignore all 'pause'
        # commands because workflow controller takes tasks that
        # completed within the period when the workflow was pause.
        cmds = list(
            filter(lambda c: not isinstance(c, commands.PauseWorkflow), cmds))

        # Since there's no explicit task causing the operation
        # we need to mark all not processed tasks as processed
        # because workflow controller takes only completed tasks
        # with flag 'processed' equal to False.
        for t_ex in wf_ex.task_executions:
            if states.is_completed(t_ex.state) and not t_ex.processed:
                t_ex.processed = True

        self._dispatch_workflow_commands(wf_ex, cmds)

        if not cmds:
            if not wf_utils.find_incomplete_task_executions(wf_ex):
                wf_handler.succeed_workflow(
                    wf_ex, wf_ctrl.evaluate_workflow_final_context())

        return wf_ex.get_clone()
예제 #3
0
    def resume_workflow(self, execution_id):
        try:
            with db_api.transaction():
                # Must be before loading the object itself (see method doc).
                self._lock_workflow_execution(execution_id)

                wf_ex = db_api.get_workflow_execution(execution_id)

                if wf_ex.state != states.PAUSED:
                    return

                wf_handler.set_execution_state(wf_ex, states.RUNNING)

                wf_ctrl = wf_base.WorkflowController.get_controller(wf_ex)

                # Calculate commands to process next.
                cmds = wf_ctrl.continue_workflow()

                # When resuming a workflow we need to ignore all 'pause'
                # commands because workflow controller takes tasks that
                # completed within the period when the workflow was pause.
                cmds = filter(
                    lambda c: not isinstance(c, commands.PauseWorkflow),
                    cmds
                )

                # Since there's no explicit task causing the operation
                # we need to mark all not processed tasks as processed
                # because workflow controller takes only completed tasks
                # with flag 'processed' equal to False.
                for t_ex in wf_ex.task_executions:
                    if states.is_completed(t_ex.state) and not t_ex.processed:
                        t_ex.processed = True

                self._dispatch_workflow_commands(wf_ex, cmds)

                if not cmds:
                    if not wf_utils.find_incomplete_tasks(wf_ex):
                        wf_handler.succeed_workflow(
                            wf_ex,
                            wf_ctrl.evaluate_workflow_final_context()
                        )

                return wf_ex
        except Exception as e:
            LOG.error(
                "Failed to resume execution id=%s: %s\n%s",
                execution_id, e, traceback.format_exc()
            )
            self._fail_workflow(execution_id, e)
            raise e
예제 #4
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
예제 #5
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)
예제 #6
0
    def _continue_workflow(self, wf_ex, task_ex=None, reset=True, env=None):
        wf_ex = wf_service.update_workflow_execution_env(wf_ex, env)

        wf_handler.set_execution_state(
            wf_ex,
            states.RUNNING,
            set_upstream=True
        )

        wf_ctrl = wf_base.get_controller(wf_ex)

        # TODO(rakhmerov): Add YAQL error handling.
        # Calculate commands to process next.
        cmds = wf_ctrl.continue_workflow(task_ex=task_ex, reset=reset, env=env)

        # When resuming a workflow we need to ignore all 'pause'
        # commands because workflow controller takes tasks that
        # completed within the period when the workflow was paused.
        cmds = list(
            filter(
                lambda c: not isinstance(c, commands.PauseWorkflow),
                cmds
            )
        )

        # Since there's no explicit task causing the operation
        # we need to mark all not processed tasks as processed
        # because workflow controller takes only completed tasks
        # with flag 'processed' equal to False.
        for t_ex in wf_ex.task_executions:
            if states.is_completed(t_ex.state) and not t_ex.processed:
                t_ex.processed = True

        wf_spec = spec_parser.get_workflow_spec(wf_ex.spec)

        self._dispatch_workflow_commands(wf_ex, cmds, wf_spec)

        if not cmds:
            if not wf_utils.find_incomplete_task_executions(wf_ex):
                wf_handler.succeed_workflow(
                    wf_ex,
                    wf_ctrl.evaluate_workflow_final_context(),
                    wf_spec
                )

        return wf_ex.get_clone()
예제 #7
0
    def resume_workflow(self, execution_id):
        try:
            with db_api.transaction():
                # Must be before loading the object itself (see method doc).
                self._lock_workflow_execution(execution_id)

                wf_ex = db_api.get_workflow_execution(execution_id)

                if wf_ex.state != states.PAUSED:
                    return wf_ex

                wf_handler.set_execution_state(wf_ex, states.RUNNING)

                wf_ctrl = wf_base.WorkflowController.get_controller(wf_ex)

                # Calculate commands to process next.
                cmds = wf_ctrl.continue_workflow()

                # When resuming a workflow we need to ignore all 'pause'
                # commands because workflow controller takes tasks that
                # completed within the period when the workflow was pause.
                cmds = filter(
                    lambda c: not isinstance(c, commands.PauseWorkflow), cmds)

                # Since there's no explicit task causing the operation
                # we need to mark all not processed tasks as processed
                # because workflow controller takes only completed tasks
                # with flag 'processed' equal to False.
                for t_ex in wf_ex.task_executions:
                    if states.is_completed(t_ex.state) and not t_ex.processed:
                        t_ex.processed = True

                self._dispatch_workflow_commands(wf_ex, cmds)

                if not cmds:
                    if not wf_utils.find_incomplete_tasks(wf_ex):
                        wf_handler.succeed_workflow(
                            wf_ex, wf_ctrl.evaluate_workflow_final_context())

                return wf_ex
        except Exception as e:
            LOG.error("Failed to resume execution id=%s: %s\n%s", execution_id,
                      e, traceback.format_exc())
            self._fail_workflow(execution_id, e)
            raise e
예제 #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)
예제 #9
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)
예제 #10
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)
예제 #11
0
    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)