"""Общие задачи Airflow для операций над миром стенда.""" from airflow.exceptions import AirflowException from airflow.models.dag import DagModel from airflow.utils.session import provide_session from airflow_clickhouse_plugin.hooks.clickhouse import ClickHouseHook from clickstream_generator.airflow_control import ( assert_clickhouse_matches_manifest, assert_live_generator_not_running_for_next_day, assert_next_day_snapshot, build_next_day_env, load_manifest_from_kafka, load_state_from_kafka, run_next_day, target_dag_trigger_error, ) def precheck_next_day(**context) -> None: """Проверяет точку продолжения и готовит настройки мира.""" assert_live_generator_not_running_for_next_day() manifest = load_manifest_from_kafka() state = load_state_from_kafka() assert_next_day_snapshot(manifest, state) context["ti"].xcom_push( key="generator_env", value=build_next_day_env(manifest), ) def run_next_day_task(**context) -> None: """Генерирует следующий модельный день от проверенного state.""" env = context["ti"].xcom_pull( task_ids="precheck_next_day", key="generator_env", ) run_next_day(env) def check_manifest_task(**context) -> None: """Сверяет витрину ClickHouse с manifest стартовой истории.""" manifest = load_manifest_from_kafka() hook = ClickHouseHook(clickhouse_conn_id="clickhouse_default", database="default") assert_clickhouse_matches_manifest(manifest, hook) @provide_session def assert_target_dag_not_paused(dag_id: str, session=None) -> None: """ Проверяет, что зависимый DAG можно запустить. Context7: для Airflow 2.10.5 у старого TriggerDagRunOperator нет надёжного fail_when_dag_is_paused, поэтому паузу проверяем заранее через DagModel. """ dag_model = session.query(DagModel).filter(DagModel.dag_id == dag_id).one_or_none() error = target_dag_trigger_error(dag_id, dag_model) if error: raise AirflowException(error)