깃허브 액션 예약 실행이 시간을 안 지킵니다
정해진 시각에 저에게 원고를 보내주는 자동화를 만들어 뒀습니다. 서버 없이 0원으로 굴러갑니다. 그런데 어느 날 원고가 안 왔습니다. 코드는 멀쩡했고 오류도 없었습니다. 실행 기록을 세어보니 21시간 동안 128번 돌아야 할 것이 17번 돌아 있었습니다.
무엇을 만들었나
쓰레드에 올릴 원고를 며칠 치 미리 써두고 각 편에 나갈 시각을 적어둡니다. 그 시각이 되면 자동화가 원고를 텔레그램으로 보내고, 저는 폰에서 복사해 붙여넣습니다. 정해진 시각에 알림이 와야 굴러가는 구조입니다.
깃허브 액션의 예약 실행으로 만들었습니다. 저장소에 파일 하나를 두고 10분마다 돌라고 클로드에게 요청하면 끝입니다.
서버가 없으니 관리할 것도 없고, 공개 저장소라 요금도 0원입니다. 전체 흐름은 이렇습니다.
위에서 내려오는 화살표 하나가 이 글의 전부입니다. 저 깨우는 일만 깃허브가 하고 나머지는 전부 제 코드가 합니다. 그런데 못 고치는 자리가 하필 저기입니다.
감으로 알면 못 고칩니다
원고가 안 온 날 저는 코드부터 봤습니다. 아무 문제가 없었습니다. 그래서 방향을 바꿔 자동화가 실제로 몇 시에 돌았는지를 세어보기로 했습니다. 깃허브는 실행 기록을 전부 갖고 있습니다. 클로드 코드에게 최근 회차의 시작 시각을 뽑아 간격을 계산해 달라고 했습니다.
| 10분마다면 돌아야 할 횟수 | 128번 |
| 실제로 돈 횟수 | 17번 |
| 회차 사이 평균 간격 | 80분 |
| 가장 길게 벌어진 간격 | 214분 |
세 시간 반 동안 한 번도 안 돈 구간이 있었습니다. 이 숫자를 보고 나서야 고칠 대상이 정해졌습니다. 그 전까지는 그게 코드인 줄 알았습니다.
고장이 아니라 사양입니다
깃허브의 예약 실행은 전 세계 사용자가 하나의 대기줄에 같이 서는 구조입니다. 부하가 몰리면 회차가 뒤로 밀리고, 충분히 밀리면 그 회차는 아예 버려집니다. 매시 정각에 요청이 몰리기 때문에 그 부근이 제일 심합니다. 무료 플랜이면 그 줄에서 우선순위가 가장 낮습니다.
돈을 낸다고 해결되지 않습니다. 유료는 순서가 조금 앞당겨질 뿐이고, 깃허브는 어느 플랜에서도 정시를 약속하지 않습니다. 결함이 아니라 무료로 제공되는 것에 정시라는 약속이 애초에 안 들어 있었던 것입니다. 저는 그 약속이 있는 줄 알고 그 위에 구조를 얹었습니다.
제일 위험한 건 조용하다는 것입니다
원고가 안 나갔는데 깃허브 화면에는 아무 문제가 없어 보입니다. 실행 기록은 전부 초록불이고 실패 알림도 안 옵니다. 안 돈 회차는 애초에 만들어지지 않았으니 실패할 것도 없기 때문입니다.
견적 발송을 자동화하면서 같은 이야기를 한 적이 있습니다. 자동화는 조용히 실패합니다. 사람이 하던 일은 안 하면 티가 납니다. 기계에 넘긴 일은 안 해도 티가 안 납니다.
서버를 사면 해결되기는 합니다
AWS에 리눅스 서버를 하나 띄우고 cron 을 걸면 이 문제는 사라집니다. 그 서버 안의 시계는 우리 것이라 남의 부하와 상관이 없습니다.
대신 하루 세 번 쓰자고 720시간을 켜둡니다. 0원이던 항목이 매달 나가는 돈이 되고, 보안 패치와 재부팅과 감시가 우리 일이 됩니다. 깃허브 방식은 불안정한 대신 남이 운영해 주고, 이건 정확한 대신 우리가 운영합니다.
저는 이 거래를 안 하기로 했습니다. 고정비를 줄이려다 관리할 것을 늘리면 남는 장사가 아닙니다. 웹호스팅처럼 남이 잘 운영해 주는 영역은 그냥 맡기는 게 맞다고 봅니다.
서버를 사지 않고 고쳤습니다
발상을 바꿨습니다. 시계를 정확하게 만들 수 없다면, 부정확한 시계를 견디도록 코드를 고치면 됩니다.
원래는 깨어난 회차가 다음 원고의 예약 시각을 보고 25분 안쪽이면 그 원고를 맡아 기다렸다가 정확한 시각에 보내는 구조였습니다. 회차가 10분마다 돈다는 전제에서는 맞습니다. 실제 간격이 평균 80분이면 25분짜리 창은 대부분 그냥 지나갑니다.
그래서 창을 120분으로 넓혔습니다. 이제 회차는 두 시간 앞의 원고까지 미리 맡아두고, 실행 중인 상태로 예약 시각까지 기다렸다가 그 시각에 정확히 보냅니다. 깨어나는 시각은 못 정하지만 깨어난 김에 할 일을 미리 챙기게 만든 것입니다.
고친 것은 숫자 두 개입니다. 미리 맡는 창을 25에서 120으로, 기다리는 시간이 길어졌으니 실행 시간 상한을 35분에서 135분으로. 비용은 그대로 0원입니다. 겹쳐서 두 번 보내는 것은 concurrency 설정으로 막습니다. 기다리는 시간이 길수록 이게 중요해집니다.
고치지 않고 감수한 것도 있습니다
이 자동화는 원고를 보내는 일과, 제가 올렸다고 답장하면 그걸 읽어 기록에 표시를 남기는 일을 같이 합니다. 두 번째는 여전히 몇십 분에서 몇 시간씩 늦습니다. 이건 고치지 않기로 했습니다.
기준은 하나였습니다. 늦으면 사라지는 일인가, 늦어도 남아 있는 일인가.
21시에 나갔어야 할 원고가 자정에 나가면 의미가 없습니다. 그래서 고쳤습니다. 답장은 텔레그램이 24시간 보관하기 때문에 세 시간 뒤에 읽어도 그대로 있습니다. 늦어봐야 화면의 숫자가 늦게 맞을 뿐이고 잃는 것이 없어서 그냥 뒀습니다.
이 구분을 안 하면 전부 고치려 들게 되고, 전부 고치려면 결국 서버를 사게 됩니다.
정리
무료 도구가 나쁘다는 이야기가 아닙니다. 이 자동화는 지금도 0원으로 잘 돕니다. 다만 깃허브의 예약 실행에는 "언젠가 돈다"가 들어 있고 "정확히 그 시각에 돈다"는 안 들어 있습니다. 정시가 꼭 필요하면 그 부분만 값을 치르면 됩니다. 전부를 서버로 옮길 필요는 없습니다.
자동화를 만들 때 이게 지금 잘 도는가와 내가 없어도 계속 도는가를 같이 본다고 적은 적이 있습니다. 하나를 더 붙여야겠습니다. 안 돌 때 내가 알 수 있는가.
비슷한 상황이라면 편하게 물어보세요. [email protected]
← 목록으로