Make 시나리오 cron을 정각에 박으면 그날 슬롯을 놓치는 이유 (date:less 경계)
장재혁
@dr_jang
Make로 슬랙 자동발행 시나리오를 운영하면서 이틀을 날린 함정이라 기록으로 남긴다. 하루 4회(09/10/19/20 KST) 정해진 시각에 콘텐츠를 발행하는 단순한 구조였는데, 유독 그날 슬롯 한 건이 조용히 누락됐다. 에러도 안 나고 실행 로그상으로는 멀쩡한데, 발행만 안 된다.
구조
시나리오는 cron으로 시각에 트리거되고, 중간에 "오늘 이 슬롯이 발행 대상인가"를 거르는 필터가 한 겹 있었다. 필터 조건이 발행 예정 시각을 date:less로 비교하는 형태였다.
trigger: cron @ 19:00
filter: scheduledAt date:less now()
원인
cron을 19시 정각에 박아두니, 트리거가 도는 순간의 now()와 슬롯의 scheduledAt(=19:00)이 사실상 동일 시점이 된다. date:less는 strict less-than이라 같은 값에서는 통과를 못 한다. 즉 19시 슬롯은 19시에 트리거되는 순간 "아직 19시가 안 지났다"로 판정돼서 게이트에 걸러진다. 그날 19시 분량이 통째로 빠지는 게 이 경계 때문이었다.
시간이 조금이라도 지나면 통과하지만, cron은 다음 실행까지 안 돌아오니 그날 슬롯은 영영 못 잡는다.
해결
트리거를 슬롯 시각보다 1분 앞에 박았다. 19시 발행이면 cron을 18:59에 트리거한다. 그러면 필터가 도는 시점의 now()(18:59)가 scheduledAt(19:00)보다 확실히 작아서 date:less를 통과한다.
09:00 슬롯 → cron 08:59
19:00 슬롯 → cron 18:59
추가로 하나 더 물렸다. cron의 interval/restrict를 한 객체 안에 여러 시간대를 욱여넣으니 의도대로 안 돌았다. 시간대별로 restrict 객체를 분리해서 각각 박아야 정확히 4회만 돌았다. 한 객체에 여러 슬롯을 섞으면 Make 내부에서 합쳐 평가하면서 경계가 또 어긋난다.
교훈
경계 비교(less vs less or equal)와 트리거 시각이 같은 값으로 만나면 그 슬롯은 silent하게 새어나간다. 에러를 안 던지기 때문에 발견이 한참 늦는다는 게 제일 골치였다. 정각 트리거는 직관적이지만, 시간 게이트가 strict 비교를 쓰는 한 슬롯-1분 오프셋이 훨씬 안전하다.