def test_success_callbak_no_race_condition(self): class CallbackWrapper: def wrap_task_instance(self, ti): self.task_id = ti.task_id self.dag_id = ti.dag_id self.execution_date = ti.execution_date self.task_state_in_callback = "" self.callback_ran = False def success_handler(self, context): # pylint: disable=unused-argument self.callback_ran = True session = settings.Session() temp_instance = session.query(TI).filter( TI.task_id == self.task_id).filter( TI.dag_id == self.dag_id).filter( TI.execution_date == self.execution_date).one() self.task_state_in_callback = temp_instance.state cw = CallbackWrapper() dag = DAG('test_success_callbak_no_race_condition', start_date=DEFAULT_DATE, end_date=DEFAULT_DATE + datetime.timedelta(days=10)) task = DummyOperator(task_id='op', email='*****@*****.**', on_success_callback=cw.success_handler, dag=dag) ti = TI(task=task, execution_date=datetime.datetime.now()) ti.state = State.RUNNING session = settings.Session() session.merge(ti) session.commit() cw.wrap_task_instance(ti) ti._run_raw_task() self.assertTrue(cw.callback_ran) self.assertEqual(cw.task_state_in_callback, State.RUNNING) ti.refresh_from_db() self.assertEqual(ti.state, State.SUCCESS)
def test_success_callbak_no_race_condition(self): class CallbackWrapper(object): def wrap_task_instance(self, ti): self.task_id = ti.task_id self.dag_id = ti.dag_id self.execution_date = ti.execution_date self.task_state_in_callback = "" self.callback_ran = False def success_handler(self, context): self.callback_ran = True session = settings.Session() temp_instance = session.query(TI).filter( TI.task_id == self.task_id).filter( TI.dag_id == self.dag_id).filter( TI.execution_date == self.execution_date).one() self.task_state_in_callback = temp_instance.state cw = CallbackWrapper() dag = DAG('test_success_callbak_no_race_condition', start_date=DEFAULT_DATE, end_date=DEFAULT_DATE + datetime.timedelta(days=10)) task = DummyOperator(task_id='op', email='*****@*****.**', on_success_callback=cw.success_handler, dag=dag) ti = TI(task=task, execution_date=datetime.datetime.now()) ti.state = State.RUNNING session = settings.Session() session.merge(ti) session.commit() cw.wrap_task_instance(ti) ti._run_raw_task() self.assertTrue(cw.callback_ran) self.assertEqual(cw.task_state_in_callback, State.RUNNING) ti.refresh_from_db() self.assertEqual(ti.state, State.SUCCESS)
def _run_raw_task(args, ti: TaskInstance) -> None: """Runs the main task handling code""" ti._run_raw_task( mark_success=args.mark_success, job_id=args.job_id, pool=args.pool, )
def _run_task_instance(self, ti, mark_success, pool, session=None): # set proper state and try number to keep logger in sync if isinstance(ti, SimpleTaskInstance): from airflow.models import TaskInstance dag = self.dag_bag.get_dag(ti.dag_id) task = dag.get_task(ti.task_id) ti = TaskInstance(task, ti.execution_date) ti.state = State.RUNNING ti._try_number += 1 # let save state session.merge(ti) session.commit() # backward compatible with airflow loggers from airflow.utils.log import logging_mixin logging_mixin.set_context(logging.root, ti) try: ti._run_raw_task(mark_success=mark_success, job_id=ti.job_id, pool=pool) finally: for handler in logging.root.handlers: if handler.name == "task": handler.close()
def _run_raw_task(args, ti: TaskInstance) -> None: """Runs the main task handling code""" unsupported_options = [o for o in RAW_TASK_UNSUPPORTED_OPTION if getattr(args, o)] if unsupported_options: raise AirflowException( "Option --raw does not work with some of the other options on this command. You " "can't use --raw option and the following options: {}. You provided the option {}. " "Delete it to execute the command".format( ", ".join(f"--{o}" for o in RAW_TASK_UNSUPPORTED_OPTION), ", ".join(f"--{o}" for o in unsupported_options), ) ) ti._run_raw_task( mark_success=args.mark_success, job_id=args.job_id, pool=args.pool, error_file=args.error_file, )
def run_task(task_instance: TaskInstance) -> State: task_instance._run_raw_task(test_mode=True) return task_instance.state