Example #1
0
    def check_and_complete(self):
        """Completes the workflow if it needs to be completed.

        The method simply checks if there are any tasks that are not
        in a terminal state. If there aren't any then it performs all
        necessary logic to finalize the workflow (calculate output etc.).
        :return: Number of incomplete tasks.
        """

        if states.is_paused_or_completed(self.wf_ex.state):
            return 0

        # Workflow is not completed if there are any incomplete task
        # executions.
        incomplete_tasks_count = db_api.get_incomplete_task_executions_count(
            workflow_execution_id=self.wf_ex.id,
        )

        if incomplete_tasks_count > 0:
            return incomplete_tasks_count

        LOG.debug("Workflow completed [id=%s]", self.wf_ex.id)

        # NOTE(rakhmerov): Once we know that the workflow has completed,
        # we need to expire all the objects in the DB session to make sure
        # to read the most relevant data from the DB (that's already been
        # committed in parallel transactions). Otherwise, some data like
        # workflow context may be stale and decisions made upon it will be
        # wrong.
        db_api.expire_all()

        wf_ctrl = wf_base.get_controller(self.wf_ex, self.wf_spec)

        if wf_ctrl.any_cancels():
            msg = _build_cancel_info_message(wf_ctrl, self.wf_ex)

            self._cancel_workflow(msg)
        elif wf_ctrl.all_errors_handled():
            ctx = wf_ctrl.evaluate_workflow_final_context()

            self._succeed_workflow(ctx)
        else:
            msg = _build_fail_info_message(wf_ctrl, self.wf_ex)
            final_context = wf_ctrl.evaluate_workflow_final_context()

            self._fail_workflow(final_context, msg)

        return 0
Example #2
0
    def check_and_complete(self):
        """Completes the workflow if it needs to be completed.

        The method simply checks if there are any tasks that are not
        in a terminal state. If there aren't any then it performs all
        necessary logic to finalize the workflow (calculate output etc.).
        :return: Number of incomplete tasks.
        """

        if states.is_paused_or_completed(self.wf_ex.state):
            return 0

        # Workflow is not completed if there are any incomplete task
        # executions.
        incomplete_tasks_count = db_api.get_incomplete_task_executions_count(
            workflow_execution_id=self.wf_ex.id,
        )

        if incomplete_tasks_count > 0:
            return incomplete_tasks_count

        LOG.debug("Workflow completed [id=%s]", self.wf_ex.id)

        # NOTE(rakhmerov): Once we know that the workflow has completed,
        # we need to expire all the objects in the DB session to make sure
        # to read the most relevant data from the DB (that's already been
        # committed in parallel transactions). Otherwise, some data like
        # workflow context may be stale and decisions made upon it will be
        # wrong.
        db_api.expire_all()

        wf_ctrl = wf_base.get_controller(self.wf_ex, self.wf_spec)

        if wf_ctrl.any_cancels():
            msg = _build_cancel_info_message(wf_ctrl, self.wf_ex)

            self._cancel_workflow(msg)
        elif wf_ctrl.all_errors_handled():
            ctx = wf_ctrl.evaluate_workflow_final_context()

            self._succeed_workflow(ctx)
        else:
            msg = _build_fail_info_message(wf_ctrl, self.wf_ex)
            final_context = wf_ctrl.evaluate_workflow_final_context()

            self._fail_workflow(final_context, msg)

        return 0