Exemple #1
0
    def process_workflow_event(cls, workflow_state, wf_ex_event):
        # Append additional workflow context to the event.
        event_name = cls.add_context_to_workflow_event(workflow_state, wf_ex_event)

        # Check if event is valid.
        if event_name not in events.WORKFLOW_EXECUTION_EVENTS:
            raise exc.InvalidEvent(event_name)

        # Capture current workflow status.
        current_workflow_status = workflow_state.status
        new_workflow_status = current_workflow_status

        # Check if the current workflow status can be transitioned.
        if current_workflow_status not in WORKFLOW_STATE_MACHINE_DATA:
            raise exc.InvalidWorkflowStatusTransition(current_workflow_status, event_name)

        # If the current workflow status can be transitioned and there is no match on the
        # event, then there is not status transition.
        if event_name not in WORKFLOW_STATE_MACHINE_DATA[current_workflow_status]:
            return

        new_workflow_status = WORKFLOW_STATE_MACHINE_DATA[current_workflow_status][event_name]

        # Assign new workflow status if there is change.
        if current_workflow_status != new_workflow_status:
            workflow_state.status = new_workflow_status
Exemple #2
0
    def request_workflow_status(self, status):
        # Record current workflow status.
        current_status = self.get_workflow_status()

        # Create an event for the request.
        wf_ex_event = events.WorkflowExecutionEvent(status)

        # Push the event to all the active tasks. The event may trigger status changes to the task.
        for task_state in self.workflow_state.get_tasks_by_status(statuses.ACTIVE_STATUSES):
            machines.TaskStateMachine.process_event(self.workflow_state, task_state, wf_ex_event)

        # Process the workflow status change event.
        machines.WorkflowStateMachine.process_event(self.workflow_state, wf_ex_event)

        # Get workflow status after event is processed.
        updated_status = self.get_workflow_status()

        # Ignore if workflow hasn't changed from paused to pausing.
        if (status == statuses.PAUSED and
                current_status == statuses.PAUSING and
                updated_status == statuses.PAUSING):
            return

        # Ignore if workflow hasn't changed from canceled to canceling.
        if (status == statuses.CANCELED and
                current_status == statuses.CANCELING and
                updated_status == statuses.CANCELING):
            return

        # Otherwise, if status has not changed as expected, then raise exception.
        if status != current_status and current_status == updated_status:
            raise exc.InvalidWorkflowStatusTransition(current_status, wf_ex_event.name)
Exemple #3
0
    def process_task_event(cls, workflow_state, tk_ex_event):
        # Append additional workflow context to the event.
        event_name = cls.add_context_to_task_event(workflow_state, tk_ex_event)

        # Check if event is valid.
        if event_name not in events.TASK_EXECUTION_EVENTS:
            raise exc.InvalidEvent(event_name)

        # Capture current workflow status.
        current_workflow_status = workflow_state.status
        new_workflow_status = current_workflow_status

        # Check if the current workflow status can be transitioned.
        if current_workflow_status not in WORKFLOW_STATE_MACHINE_DATA:
            raise exc.InvalidWorkflowStatusTransition(current_workflow_status,
                                                      event_name)

        # If the current workflow status can be transitioned and there is no match on the
        # event, then there is not status transition.
        if event_name not in WORKFLOW_STATE_MACHINE_DATA[
                current_workflow_status]:
            return

        new_workflow_status = WORKFLOW_STATE_MACHINE_DATA[
            current_workflow_status][event_name]

        # Assign new workflow status if there is change.
        if current_workflow_status != new_workflow_status:
            workflow_state.status = new_workflow_status

        # If the final workflow status here is completed, then ensure there is no unreachable
        # barrier task(s). A barrier task is unreachable if the workflow is completed but then one
        # or more criteria for the task is satisified. In this case, log the task and fail the
        # workflow to notify that the execution is incomplete but unable to proceed.
        if workflow_state.status in statuses.COMPLETED_STATUSES:
            unreachable_barriers = workflow_state.get_unreachable_barriers()

            # If there are unreachable barrier tasks, then change workflow status to failed
            # and write an error log for each case.
            if unreachable_barriers:
                workflow_state.status = statuses.FAILED

                for entry in unreachable_barriers:
                    e = exc.UnreachableJoinError(entry["id"], entry["route"])
                    workflow_state.conductor.log_error(e,
                                                       task_id=entry["id"],
                                                       route=entry["route"])
Exemple #4
0
    def request_workflow_status(self, status):
        # Record current workflow status.
        current_status = self.get_workflow_status()

        # Create an event for the request.
        wf_ex_event = events.WorkflowExecutionEvent(status)

        # Push the event to all the active tasks. The event may trigger status changes to the task.
        for task_state in self.workflow_state.get_tasks_by_status(
                statuses.ACTIVE_STATUSES):
            machines.TaskStateMachine.process_event(self.workflow_state,
                                                    task_state, wf_ex_event)

        # Process the workflow status change event.
        machines.WorkflowStateMachine.process_event(self.workflow_state,
                                                    wf_ex_event)

        # Get workflow status after event is processed.
        updated_status = self.get_workflow_status()

        # If status has not changed as expected, then raise exception.
        if status != current_status and current_status == updated_status:
            raise exc.InvalidWorkflowStatusTransition(current_status,
                                                      wf_ex_event.name)