Ejemplo n.º 1
0
def handle_expired_actions():
    LOG.debug("Running heartbeat checker...")

    interval = CONF.action_heartbeat.check_interval
    max_missed = CONF.action_heartbeat.max_missed_heartbeats

    exp_date = utils.utc_now_sec() - datetime.timedelta(
        seconds=max_missed * interval
    )

    with db_api.transaction():
        action_exs = db_api.get_running_expired_sync_action_executions(
            exp_date,
            CONF.action_heartbeat.batch_size
        )

        LOG.debug("Found {} running and expired actions.".format(
            len(action_exs))
        )

        if action_exs:
            LOG.info(
                "Actions executions to transit to error, because "
                "heartbeat wasn't received: {}".format(action_exs)
            )

            for action_ex in action_exs:
                result = mistral_lib.Result(
                    error="Heartbeat wasn't received."
                )

                action_handler.on_action_complete(action_ex, result)
Ejemplo n.º 2
0
def handle_expired_actions():
    LOG.debug("Running heartbeat checker...")

    interval = CONF.action_heartbeat.check_interval
    max_missed = CONF.action_heartbeat.max_missed_heartbeats

    exp_date = utils.utc_now_sec() - datetime.timedelta(seconds=max_missed *
                                                        interval)

    try:
        with db_api.transaction():
            action_exs = db_api.get_running_expired_sync_actions(exp_date)

            LOG.debug("Found {} running and expired actions.".format(
                len(action_exs)))

            if action_exs:
                LOG.info("Actions executions to transit to error, because "
                         "heartbeat wasn't received: {}".format(action_exs))

                for action_ex in action_exs:
                    result = mistral_lib.Result(
                        error="Heartbeat wasn't received.")

                    action_handler.on_action_complete(action_ex, result)
    finally:
        schedule(interval)
Ejemplo n.º 3
0
    def on_action_complete(self, action_ex_id, result, wf_action=False):
        with db_api.transaction():
            if wf_action:
                action_ex = db_api.get_workflow_execution(action_ex_id)
            else:
                action_ex = db_api.get_action_execution(action_ex_id)

            action_handler.on_action_complete(action_ex, result)

            return action_ex.get_clone()
Ejemplo n.º 4
0
    def on_action_complete(self, action_ex_id, result):
        with db_api.transaction():
            action_ex = db_api.get_action_execution(action_ex_id)

            task_ex = action_ex.task_execution

            if task_ex:
                wf_handler.lock_workflow_execution(
                    task_ex.workflow_execution_id)

            action_handler.on_action_complete(action_ex, result)

            return action_ex.get_clone()
Ejemplo n.º 5
0
    def on_action_complete(self, action_ex_id, result):
        with db_api.transaction():
            action_ex = db_api.get_action_execution(action_ex_id)

            task_ex = action_ex.task_execution

            if task_ex:
                wf_handler.lock_workflow_execution(
                    task_ex.workflow_execution_id
                )

            action_handler.on_action_complete(action_ex, result)

            return action_ex.get_clone()
Ejemplo n.º 6
0
    def on_action_complete(self, action_ex_id, result, wf_action=False,
                           async_=False):
        with db_api.transaction():
            if wf_action:
                action_ex = db_api.get_workflow_execution(action_ex_id)

                # If result is None it means that it's a normal subworkflow
                # output and we just need to fetch it from the model.
                # This is just an optimization to not send data over RPC
                if result is None:
                    result = ml_actions.Result(data=action_ex.output)
            else:
                action_ex = db_api.get_action_execution(action_ex_id)

            action_handler.on_action_complete(action_ex, result)

            return action_ex.get_clone()
Ejemplo n.º 7
0
    def on_action_complete(self, action_ex_id, result, wf_action=False,
                           async_=False):
        with db_api.transaction():
            if wf_action:
                action_ex = db_api.get_workflow_execution(action_ex_id)

                # If result is None it means that it's a normal subworkflow
                # output and we just need to fetch it from the model.
                # This is just an optimization to not send data over RPC
                if result is None:
                    result = ml_actions.Result(data=action_ex.output)
            else:
                action_ex = db_api.get_action_execution(action_ex_id)

            action_handler.on_action_complete(action_ex, result)

            return action_ex.get_clone()
Ejemplo n.º 8
0
class DefaultEngine(base.Engine):
    @action_queue.process
    @u.log_exec(LOG)
    @profiler.trace('engine-start-workflow')
    def start_workflow(self,
                       wf_identifier,
                       wf_input,
                       description='',
                       **params):

        with db_api.transaction():
            wf_ex = wf_handler.start_workflow(wf_identifier, wf_input,
                                              description, params)

            return wf_ex.get_clone()

    @action_queue.process
    @u.log_exec(LOG)
    def start_action(self,
                     action_name,
                     action_input,
                     description=None,
                     **params):
        with db_api.transaction():
            action = action_handler.build_action_by_name(action_name)

            action.validate_input(action_input)

            sync = params.get('run_sync')
            save = params.get('save_result')
            target = params.get('target')

            is_action_sync = action.is_sync(action_input)

            if sync and not is_action_sync:
                raise exceptions.InputException(
                    "Action does not support synchronous execution.")

            if not sync and (save or not is_action_sync):
                action.schedule(action_input, target)

                return action.action_ex.get_clone()

            output = action.run(action_input, target, save=False)

            state = states.SUCCESS if output.is_success() else states.ERROR

            if not save:
                # Action execution is not created but we need to return similar
                # object to a client anyway.
                return db_models.ActionExecution(name=action_name,
                                                 description=description,
                                                 input=action_input,
                                                 output=output.to_dict(),
                                                 state=state)

            action_ex_id = u.generate_unicode_uuid()

            values = {
                'id': action_ex_id,
                'name': action_name,
                'description': description,
                'input': action_input,
                'output': output.to_dict(),
                'state': state,
            }

            return db_api.create_action_execution(values)

    @db_utils.retry_on_deadlock
    @action_queue.process
    @u.log_exec(LOG)
    @profiler.trace('engine-on-action-complete')
    def on_action_complete(self,
                           action_ex_id,
                           result,
                           wf_action=False,
                           async=False):
        with db_api.transaction():
            if wf_action:
                action_ex = db_api.get_workflow_execution(action_ex_id)
            else:
                action_ex = db_api.get_action_execution(action_ex_id)

            action_handler.on_action_complete(action_ex, result)

            return action_ex.get_clone()