示例#1
0
def dispatch_workflow_commands(wf_ex, wf_cmds):
    # TODO(rakhmerov): I don't like these imports but otherwise we have
    # import cycles.
    from mistral.engine import task_handler
    from mistral.engine import workflow_handler as wf_handler

    if not wf_cmds:
        return

    for cmd in wf_cmds:
        if isinstance(cmd, (commands.RunTask, commands.RunExistingTask)):
            task_handler.run_task(cmd)
        elif isinstance(cmd, commands.SetWorkflowState):
            # TODO(rakhmerov): Make just a single call to workflow_handler
            if states.is_completed(cmd.new_state):
                wf_handler.stop_workflow(cmd.wf_ex, cmd.new_state, cmd.msg)
            else:
                wf_handler.set_workflow_state(wf_ex, cmd.new_state, cmd.msg)
        elif isinstance(cmd, commands.Noop):
            # Do nothing.
            pass
        else:
            raise exc.MistralError('Unsupported workflow command: %s' % cmd)

        if wf_ex.state != states.RUNNING:
            break
示例#2
0
def dispatch_workflow_commands(wf_ex, wf_cmds):
    # TODO(rakhmerov): I don't like these imports but otherwise we have
    # import cycles.
    from mistral.engine import task_handler
    from mistral.engine import workflow_handler as wf_handler

    if not wf_cmds:
        return

    for cmd in wf_cmds:
        if isinstance(cmd, (commands.RunTask, commands.RunExistingTask)):
            task_handler.run_task(cmd)
        elif isinstance(cmd, commands.SetWorkflowState):
            # TODO(rakhmerov): Make just a single call to workflow_handler
            if states.is_completed(cmd.new_state):
                wf_handler.stop_workflow(cmd.wf_ex, cmd.new_state, cmd.msg)
            else:
                wf_handler.set_workflow_state(wf_ex, cmd.new_state, cmd.msg)
        elif isinstance(cmd, commands.Noop):
            # Do nothing.
            pass
        else:
            raise exc.MistralError('Unsupported workflow command: %s' % cmd)

        if wf_ex.state != states.RUNNING:
            break
示例#3
0
    def pause_workflow(self, wf_ex_id):
        with db_api.transaction():
            wf_ex = wf_handler.lock_workflow_execution(wf_ex_id)

            wf_handler.set_workflow_state(wf_ex, states.PAUSED)

        return wf_ex
示例#4
0
    def _continue_workflow(wf_ex, task_ex=None, reset=True, env=None):
        wf_ex = wf_service.update_workflow_execution_env(wf_ex, env)

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

        wf_ctrl = wf_base.get_controller(wf_ex)

        # TODO(rakhmerov): Add 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.
        # TODO(rakhmerov): This all should be in workflow handler, it's too
        # specific for engine level.
        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

        dispatcher.dispatch_workflow_commands(wf_ex, cmds)

        if not cmds:
            wf_handler.check_workflow_completion(wf_ex)

        return wf_ex.get_clone()
示例#5
0
    def start_workflow(self, wf_identifier, wf_input, description='',
                       **params):
        with db_api.transaction():
            # TODO(rakhmerov): It needs to be hidden in workflow_handler and
            # Workflow abstraction.
            # The new workflow execution will be in an IDLE
            # state on initial record creation.
            wf_ex, wf_spec = wf_ex_service.create_workflow_execution(
                wf_identifier,
                wf_input,
                description,
                params
            )
            wf_handler.set_workflow_state(wf_ex, states.RUNNING)

            wf_ctrl = wf_base.get_controller(wf_ex, wf_spec)

            cmds = wf_ctrl.continue_workflow()

            dispatcher.dispatch_workflow_commands(wf_ex, cmds)

            return wf_ex.get_clone()
示例#6
0
def _process_commands(wf_ex, cmds):
    if not cmds:
        return

    from mistral.engine import task_handler
    from mistral.engine import workflow_handler as wf_handler

    for cmd in _rearrange_commands(cmds):
        if states.is_completed(wf_ex.state):
            break

        if wf_ex.state == states.PAUSED:
            # Save all commands after 'pause' to the backlog so that
            # they can be processed after the workflow is resumed.
            _save_command_to_backlog(wf_ex, cmd)

            continue

        if isinstance(cmd, (commands.RunTask, commands.RunExistingTask)):
            task_handler.run_task(cmd)
        elif isinstance(cmd, commands.SetWorkflowState):
            wf_handler.set_workflow_state(wf_ex, cmd.new_state, cmd.msg)
        else:
            raise exc.MistralError('Unsupported workflow command: %s' % cmd)
示例#7
0
def _process_commands(wf_ex, cmds):
    if not cmds:
        return

    from mistral.engine import task_handler
    from mistral.engine import workflow_handler as wf_handler

    for cmd in _rearrange_commands(cmds):
        if states.is_completed(wf_ex.state):
            break

        if wf_ex.state == states.PAUSED:
            # Save all commands after 'pause' to the backlog so that
            # they can be processed after the workflow is resumed.
            _save_command_to_backlog(wf_ex, cmd)

            continue

        if isinstance(cmd, (commands.RunTask, commands.RunExistingTask)):
            task_handler.run_task(cmd)
        elif isinstance(cmd, commands.SetWorkflowState):
            wf_handler.set_workflow_state(wf_ex, cmd.new_state, cmd.msg)
        else:
            raise exc.MistralError('Unsupported workflow command: %s' % cmd)