def get_task_state(cls, workbook_name, execution_id, task_id): task = db_api.task_get(workbook_name, execution_id, task_id) if not task: raise exc.EngineException("Task not found.") return task["state"]
def get_workflow_execution_state(cls, workbook_name, execution_id): execution = db_api.execution_get(workbook_name, execution_id) if not execution: raise exc.EngineException("Workflow execution not found " "[workbook_name=%s, execution_id=%s]" % (workbook_name, execution_id)) return execution["state"]
def run_existing_task(task_ex_id, reset=True): """This function runs existing task execution. It is needed mostly by scheduler. :param task_ex_id: Task execution id. :param reset: Reset action executions for the task. """ task_ex = db_api.get_task_execution(task_ex_id) task_spec = spec_parser.get_task_spec(task_ex.spec) wf_def = db_api.get_workflow_definition(task_ex.workflow_name) wf_spec = spec_parser.get_workflow_spec(wf_def.spec) # Throw exception if the existing task already succeeded. if task_ex.state == states.SUCCESS: raise exc.EngineException( 'Rerunning existing task that already succeeded is not supported.') # Exit if the existing task failed and reset is not instructed. # For a with-items task without reset, re-running the existing # task will re-run the failed and unstarted items. if (task_ex.state == states.ERROR and not reset and not task_spec.get_with_items()): return task_ex # Reset nested executions only if task is not already RUNNING. if task_ex.state != states.RUNNING: # Reset state of processed task and related action executions. if reset: action_exs = task_ex.executions else: action_exs = db_api.get_action_executions( task_execution_id=task_ex.id, state=states.ERROR, accepted=True) for action_ex in action_exs: action_ex.accepted = False # Explicitly change task state to RUNNING. set_task_state(task_ex, states.RUNNING, None, processed=False) _run_existing_task(task_ex, task_spec, wf_spec) return task_ex
def start_workflow_execution(cls, workbook_name, task_name, context): context = copy.copy(context) if context else {} db_api.start_tx() WORKFLOW_TRACE.info("New execution started - [workbook_name = '%s', " "task_name = '%s']" % (workbook_name, task_name)) # Persist execution and tasks in DB. try: workbook = cls._get_workbook(workbook_name) execution = cls._create_execution(workbook_name, task_name, context) tasks = cls._create_tasks( workflow.find_workflow_tasks(workbook, task_name), workbook, workbook_name, execution['id']) tasks_to_start, delayed_tasks = workflow.find_resolved_tasks(tasks) cls._add_variables_to_data_flow_context(context, execution) data_flow.prepare_tasks(tasks_to_start, context) db_api.commit_tx() except Exception as e: LOG.exception("Failed to create necessary DB objects.") raise exc.EngineException("Failed to create necessary DB objects:" " %s" % e) finally: db_api.end_tx() for task in delayed_tasks: cls._schedule_run(workbook, task, context) cls._run_tasks(tasks_to_start) return execution
def test_default_message(self): exc = exceptions.EngineException() self.assertIn("An unknown exception occurred", six.text_type(exc))
def test_default_code(self): exc = exceptions.EngineException() self.assertEqual(500, exc.http_code)
def failed_to_send(): raise exc.EngineException("Test")
def convey_task_result(cls, workbook_name, execution_id, task_id, state, result): db_api.start_tx() try: workbook = cls._get_workbook(workbook_name) #TODO(rakhmerov): validate state transition task = db_api.task_get(workbook_name, execution_id, task_id) wf_trace_msg = "Task '%s' [%s -> %s" % \ (task['name'], task['state'], state) wf_trace_msg += ']' if state == states.ERROR \ else ", result = %s]" % result WORKFLOW_TRACE.info(wf_trace_msg) task_output = data_flow.get_task_output(task, result) # Update task state. task, outbound_context = cls._update_task(workbook, task, state, task_output) execution = db_api.execution_get(workbook_name, execution_id) cls._create_next_tasks(task, workbook) # Determine what tasks need to be started. tasks = db_api.tasks_get(workbook_name, execution_id) new_exec_state = cls._determine_execution_state(execution, tasks) if execution['state'] != new_exec_state: wf_trace_msg = \ "Execution '%s' [%s -> %s]" % \ (execution_id, execution['state'], new_exec_state) WORKFLOW_TRACE.info(wf_trace_msg) execution = \ db_api.execution_update(workbook_name, execution_id, { "state": new_exec_state }) LOG.info("Changed execution state: %s" % execution) tasks_to_start, delayed_tasks = workflow.find_resolved_tasks(tasks) cls._add_variables_to_data_flow_context(outbound_context, execution) data_flow.prepare_tasks(tasks_to_start, outbound_context) db_api.commit_tx() except Exception as e: LOG.exception("Failed to create necessary DB objects.") raise exc.EngineException("Failed to create necessary DB objects:" " %s" % e) finally: db_api.end_tx() if states.is_stopped_or_finished(execution["state"]): return task for task in delayed_tasks: cls._schedule_run(workbook, task, outbound_context) if tasks_to_start: cls._run_tasks(tasks_to_start) return task