Esempio n. 1
0
def sleep_with_cancel_support(ctx, use_legacy_cancel, **kwargs):
    node_instance = get_instance(ctx)

    node_instance.execute_operation(
        'test_interface.operation',
        kwargs={'key': 'before-sleep',
                'value': None})

    node_instance.set_state('asleep')
    is_cancelled = False
    for i in range(10):
        if api.has_cancel_request():
            is_cancelled = True
            break
        time.sleep(1)

    if is_cancelled:
        if use_legacy_cancel:
            return api.EXECUTION_CANCELLED_RESULT
        else:
            raise api.ExecutionCancelled()

    node_instance.execute_operation(
        'test_interface.operation',
        kwargs={'key': 'after-sleep',
                'value': None})
Esempio n. 2
0
def sleep_with_cancel_support(ctx, use_legacy_cancel, **kwargs):
    node_instance = get_instance(ctx)

    node_instance.execute_operation('test_interface.operation',
                                    kwargs={
                                        'key': 'before-sleep',
                                        'value': None
                                    })

    node_instance.set_state('asleep')
    is_cancelled = False
    for i in range(10):
        if api.has_cancel_request():
            is_cancelled = True
            break
        time.sleep(1)

    if is_cancelled:
        if use_legacy_cancel:
            return api.EXECUTION_CANCELLED_RESULT
        else:
            raise api.ExecutionCancelled()

    node_instance.execute_operation('test_interface.operation',
                                    kwargs={
                                        'key': 'after-sleep',
                                        'value': None
                                    })
Esempio n. 3
0
    def get(self, retry_on_failure=True):
        """Get the task result. Will block until the task execution ends.

        :return: The task result
        """
        done = threading.Event()

        api.cancel_callbacks.add(done.set)
        self.on_result(lambda _result: done.set())
        done.wait()
        api.cancel_callbacks.discard(done.set)

        if api.has_cancel_request():
            if self._result is self._NOT_SET:
                self.result = api.ExecutionCancelled()
                raise self.result

        ctx = self.task.workflow_context
        if not ctx.internal.graph_mode:
            ctx.internal.task_graph.remove_task(self.task)

        if self.task.get_state() in (TASK_FAILED, TASK_RESCHEDULED):
            handler_result = self.task.handle_task_terminated()
            if handler_result.retried_task and retry_on_failure:
                handler_result.retried_task.apply_async()
                return handler_result.retried_task.async_result.get()
            else:
                raise self.result
        return self._result
def _wait_for_sent_tasks(ctx, graph):
    """Wait for tasks that are in the SENT state to return"""
    for task in graph.tasks_iter():
        # Check type.
        ctx.logger.debug(
            'Parallel task to failed task: {0}. State: {1}'.format(
                task.id, task.get_state()))
    try:
        deadline = time.time() + ctx.wait_after_fail
    except AttributeError:
        deadline = time.time() + 1800
    while deadline > time.time():
        try:
            cancelled = api.has_cancel_request()
        except AttributeError:
            cancelled = graph._is_execution_cancelled()
        if cancelled:
            raise api.ExecutionCancelled()
        try:
            finished_tasks = graph._finished_tasks()
        except AttributeError:
            finished_tasks = graph._terminated_tasks()
        for task in finished_tasks:
            try:
                graph._handle_terminated_task(task)
            except RuntimeError:
                ctx.logger.error('Unhandled Failed task: {0}'.format(task))
        if not any(task.get_state() == tasks.TASK_SENT
                   for task in graph.tasks_iter()):
            break
        else:
            time.sleep(0.1)
Esempio n. 5
0
def run_jobs(**kwargs):  # pylint: disable=W0613
    """ Workflow to execute long running batch operations """
    success = True
    root_nodes, job_instances_map = build_graph(ctx.nodes)
    monitor = Monitor(job_instances_map, ctx.logger)

    new_exec_nodes = root_nodes

    # Monitoring and next executions loop
    while new_exec_nodes or monitor.is_something_executing(
    ) and not api.has_cancel_request():
        # perform new executions
        jobs_result_list = []
        for new_node in new_exec_nodes:
            monitor.add_node(new_node)
            if new_node.is_job:
                jobs_result_list += new_node.launch_all_instances()

        wait_jobs_to_finish(jobs_result_list)
        # Monitor the infrastructure
        monitor.update_status()
        exec_nodes_finished = []
        new_exec_nodes = []
        for node_name, exec_node in monitor.get_executions_iterator():
            if exec_node.check_status():
                if exec_node.completed:
                    exec_node.clean_all_instances()
                    exec_nodes_finished.append(node_name)
                    new_nodes_to_execute = exec_node.get_children_ready()
                    for new_node in new_nodes_to_execute:
                        new_exec_nodes.append(new_node)
            else:
                # Something went wrong in the node, cancel execution
                cancel_all(monitor.get_executions_iterator())
                return

        # remove finished nodes
        for node_name in exec_nodes_finished:
            monitor.finish_node(node_name)

        wait_jobs_to_finish(jobs_result_list)

    if monitor.is_something_executing():
        ctx.logger.info("Cancelling jobs...")
        cancel_all(monitor.get_executions_iterator())
        success = False

    deleted_reservations = []
    for instance_name in job_instances_map:
        instance = job_instances_map[instance_name]
        if instance.reservation not in deleted_reservations and instance.reservation:
            instance.delete_reservation()
            deleted_reservations.append(instance.reservation)

    if not success:
        raise api.ExecutionCancelled()
    ctx.logger.info(
        "------------------Workflow Finished-----------------------")
    return
def run_jobs(**kwargs):  # pylint: disable=W0613
    """ Workflow to execute long running batch operations """

    root_nodes, job_instances_map = build_graph(ctx.nodes)
    monitor = Monitor(job_instances_map, ctx.logger)
    ctx.logger.info('WORKFLOWS.PY::RUN_JOBS() L390')

    # Execution of first job instances
    tasks_list = []
    for root in root_nodes:
        tasks_list += root.queue_all_instances()
        monitor.add_node(root)
    wait_tasks_to_finish(tasks_list)

    prev_status = str()

    # Monitoring and next executions loop
    while monitor.is_something_executing() and not api.has_cancel_request():
        # Monitor the infrastructure
        monitor.update_status()
        exec_nodes_finished = []
        new_exec_nodes = []
        for node_name, exec_node in monitor.get_executions_iterator():
            if exec_node.check_status():

                if exec_node.status != prev_status:
                    ctx.logger.info('SPIROS TEMP exec_node.status = ' + str(exec_node.status))
                prev_status = exec_node.status

                if exec_node.completed:
                    exec_node.clean_all_instances()
                    exec_nodes_finished.append(node_name)
                    new_nodes_to_execute = exec_node.get_children_ready()
                    for new_node in new_nodes_to_execute:
                        new_exec_nodes.append(new_node)
            else:
                # Something went wrong in the node, cancel execution
                cancel_all(monitor.get_executions_iterator())
                return

        # remove finished nodes
        for node_name in exec_nodes_finished:
            monitor.finish_node(node_name)
        # perform new executions
        tasks_list = []
        for new_node in new_exec_nodes:
            tasks_list += new_node.queue_all_instances()
            monitor.add_node(new_node)
        wait_tasks_to_finish(tasks_list)

    if monitor.is_something_executing():
        cancel_all(monitor.get_executions_iterator())

    ctx.logger.info(
        "------------------Workflow Finished-----------------------")
    return
Esempio n. 7
0
 def _inner(*args, **kwargs):
     task = args[0]
     if api.has_cancel_request():
         return task.async_result
     if task.execute_after and task.execute_after > time.time():
         t = threading.Timer(task.execute_after - time.time(),
                             _inner,
                             args=args,
                             kwargs=kwargs)
         t.daemon = True
         t.start()
         return task.async_result
     with current_workflow_ctx.push(task.workflow_context):
         return f(*args, **kwargs)
Esempio n. 8
0
    def _is_finished(self):
        if api.has_cancel_request():
            self._error = api.ExecutionCancelled()
            return True

        if not self._tasks:
            return True

        if self._error:
            if not self._waiting_for:
                return True
            deadline = self._error_time + self.ctx.wait_after_fail
            if time.time() > deadline:
                return True
            else:
                self._wake_after_fail = threading.Timer(
                    deadline - time.time(), self._tasks_wait.set)
                self._wake_after_fail.daemon = True
                self._wake_after_fail.start()
        return False
Esempio n. 9
0
 def _check_execution_cancelled():
     if api.has_cancel_request():
         raise api.ExecutionCancelled()
Esempio n. 10
0
 def _check_execution_cancelled():
     if api.has_cancel_request():
         raise api.ExecutionCancelled()
Esempio n. 11
0
 def _is_execution_cancelled(self):
     return api.has_cancel_request()
Esempio n. 12
0
 def _is_execution_cancelled():
     return api.has_cancel_request()