ExternalTaskSensor 왜 사용할까?
세탁이 끝나고 나면 무엇을 해야할까? 아마도 빨래를 이쁘게 개어서 수납을 해야할 것이다(말리는 게 먼저겠지만 그건 건조기가 해줬다고 치고...) 당연하게도 세탁이 끝나지 않았다면 빨래를 개지도 못할 것이다. 따라서 빨래를 개는 작업은 세탁이 끝난 이후에 진행할 수 밖에 없다. 그래서 보통 세탁기를 돌려놓고 다른 일을 하다가 세탁기가 끝났다는 벨소리를 울리면 그 때 빨래를 갤 것이다(머리속에서 울리는 익숙한 LG 세탁기의 벨소리...)
왜 빨래 이야기를 이렇게 장황하게 할까? 오늘 말할 ExternalTaskSensor가 딱 이러한 프로세스에 사용되기 때문이다. 이름에서도 대충 알 수 있듯이 ExternalTaskSensor는 외부 태스크가 끝났는지를 감지하는 센서이다. Airflow는 여러 DAG를 실행할 수 있는데, 위에서 본 빨래 예시처럼 어떤 DAG는 다른 DAG가 끝났는지를 확인하고 해당 DAG가 끝났다면 DAG를 실행하고 싶을 수 있다.
아래 그림이 명료하게 잘 나와있는 것 같다. DAG_B는 DAG_A가 끝났는지를 확인하고 태스크를 실행하고 싶다. 이때 ExternalTaskSensor를 이용해 DAG_A의 Task_2까지 마무리되었는지를 확인하고 이것이 성공적으로 끝났다면 Task_3를 수행할 수 있다.
execution_date_fn
ExternalTaskSensor는 사실 사용하는 것이 그리 어렵지 않아서 금방 DAG에 적용할 수가 있다. 나 또한 어렵지 않게 적용을 하고 실행 상태를 확인했는데, 이상하게 계속해서 up_for_schedule 상태에 stuck 되어 있었다. 분명 잘못한 것이 없는데 뭐가 문제일까 구글링 하다가 아주 치명적인 실수를 하나 했다는 것을 깨달았다. 문제는 execution_date_fn 파라미터였는데 해당 파라미터는 감지할 DAG의 논리적 실행시간인 execution_date를 받는 부분이었다.
내 상황에서는 이전에 실행되는 DAG(Sensored)가 오전 6시에 트리거가 되는 상황이었고, Sensoring하는 DAG가 6시 30분이었다. 그런데 왜 stuck이 됐을까 공식문서를 들여다보는데 바로 답이 있었다. 문제는 execution_date_fn 파라미터 였는데 해당 파라미터는 이전 DAG의 execution_date를 가져야 했다. 하지만 나는 해당 파라미터에 실행할 DAG의 execution_date를 넣었었고 그래서 계속해서 stuck되어 있었던 것이다. 이래서 공식문서를 잘 봐야하나보다😂