
Mac이 잠들면 자동화도 멈춘다
요약
Mac 환경에서 자동화 스케줄러(launchd)를 운영할 때 발생하는 DarkWake 및 Maintenance Sleep 문제를 다룹니다. 자동화가 시작되더라도 OS 상태 변화로 인해 중간에 중단될 수 있는 운영상의 현실과 이를 방지하기 위한 설계의 중요성을 설명합니다.
핵심 포인트
- launchd를 통한 자동 실행이 반드시 성공적인 운영을 보장하지 않음
- DarkWake 상태에서 실행된 작업이 Maintenance Sleep으로 전환될 위험 존재
- 자동화 설계 시 '시작'뿐만 아니라 '완료 시점의 컨텍스트 유지'가 필수적임
- 운영 안정성을 위해 --wait-for-user-active와 같은 대책 고려 필요
자동화가 있으면 사람은 안심하기 쉽다. 시간을 정하고, 메커니즘을 구축한 뒤, 나머지는 매일 아침 결과만 확인하면 된다고 생각하고 싶어진다. 하지만 Mac 위에서 동작하는 자동화에는 또 하나의 전제가 있다. 그 시간에 Mac이 끝까지 깨어 있어야 한다는 것이다. 이 점을 간과하면 올바른 메커니즘을 구축하더라도 아침의 전제는 조용히 무너진다.
RC 검증 주간에 드러난 것은 Connector의 성패뿐만이 아니었다. launchd를 넣는다고 끝나는 것도 아니었다. 자동 실행이 시작되더라도, DarkWake 상태로 06:30을 맞이하면 도중에 Maintenance Sleep으로 돌아갈 수 있다. 매일 동작하는 메커니즘은 동작을 시작하는 것뿐만 아니라, 끝까지 아침의 문맥(Context)에 남아 있는 것까지 포함하여 설계해야 했다.
Vol.12에서는 손으로 움직이는 것과 매일 움직이는 것이 별개의 품질이라고 썼다. 그 이야기가 이번 내용의 연장선이다. Step49.1에서 Daily Connector Automation을 분리하여, 일일 Connector가 "아침에 이미 정렬되어 있는" 상태를 목표로 했다. 하지만 2026-07-24의 Current Context에서는 그 다음 논점으로 DarkWake 문제가 명확히 기록되어 있다.
여기서 중요한 것은 아직 정식 v1.0.0이 아니라는 점이다. RC 검증 주간의 역할은 "동작했다"라는 성공담을 쓰는 것이 아니라, "어디까지 확인되었고 어디가 미완료인가"를 구분하는 것이었다. 그래서 이 기사에서도 해결되었다고 쓰지 않는다. 쓸 수 있는 것은 DarkWake 중의 launchd 기동이 새로운 운영 논점으로 보였고, 그 대책으로서 --wait-for-user-active가 추가되었다는 사실까지다.
테마는 Mac이 잠들면 자동화도 멈춘다는 운영상의 현실이다.
launchd를 넣은 시점에서 "이제 매일 아침 돌아가겠지"라고 느끼기 쉽다. 하지만 RC 검증 주간에는 그 감각이 조금씩 깎여 나갔다. 시작하는 것과 끝나는 것은 별개다. 끝나는 것과 운영자가 안심하고 결과를 볼 수 있는 것도 별개다. DarkWake 문제는 그 사이에 있는 보이지 않는 전제를 표면화했다.
Current Context에 나와 있듯이, 2026-07-24의 HEAD에서는 DarkWake 중에 06:30 실행이 시작되면 도중에 Maintenance Sleep으로 돌아갈 수 있음이 기록되어 있었다. 이는 Connector의 취득 로직에 관한 이야기가 아니다. 스케줄러가 기동한 후, OS 측의 상태 변화가 운영을 중단시킬 수 있다는 시간축의 이야기다.
여기서 놓치기 쉬운 점은 "시작했다"라는 사실이 곧바로 "아침에 도움이 된다"라는 의미가 되지는 않는다는 것이었다. 06:30에 launchd가 반응하더라도, 운영자가 아침에 화면을 열 때까지 처리가 남아 있지 않다면 전제는 성립하지 않는다. 이는 실패 로그의 유무보다 까다로운 문제였다. 실패라면 알아챌 수 있지만, 조용히 도중에 끊기면 처음에는 "오늘은 우연히 업데이트가 적은 것일지도 모른다"라고 해석하기 쉽기 때문이다.
게다가 이 문제는 Connector 단독으로 몇 번을 테스트해도 충분히 보이지 않는다. GA4, GSC, Clarity, Metricool의 취득 로직이 각각 올바르더라도, OS가 해당 시간대에 어떤 상태로 있는지는 별개의 계층에 있다. Vol.12에서 썼던 "동작하는 Connector와 매일 동작하는 메커니즘은 별개였다"라는 이야기가 여기서는 더욱 세분화되어, "매일 시작하는 것과 매일 끝까지 남아 있는 것도 별개였다"라고 다시 정의된 형태였다.
여기서 중요했던 것은 launchd를 넣은 것을 "완성"으로 취급하지 않은 것이라고 생각한다. 만약 완성으로 취급했다면, 다음에 발생한 마찰은 예외 처리의 부족으로 치부되었을지도 모른다. 하지만 실제로는 매일 아침의 무인 실행을 성립시키는 조건 그 자체를 아직 다 채우지 못했다. 그래서 대책은 Connector 측의 추가 구현이 아니라, launchd 실행만 통상 기동 대기 상태로 바꾸는 최소한의 수정으로 정리되었다.
--wait-for-user-active의 추가는 화려한 개선처럼 보이지 않는다. 하지만 이런 종류의 수정은 운영 OS에 있어 상당히 중요하다. 아침의 10분을 지켜주는 도구는 화려한 신기능보다, 이러한 눈에 띄지 않는 전제 조건의 축적으로 안정화되기 때문이다.
한편, 이 수정이 들어간 시점에서도 Current Context는 "무인 실기 확인은 미완료"라고 명시하고 있다. 이 부분은 절대로 건너뛰어서는 안 된다. 수정을 넣은 것과 그 수정으로 매일 아침의 전제가 충분히 지켜지는 것을 확인한 것은 별개의 문제다. 확인이 끝나지 않은 이상, 기사에서도 완성형으로는 쓰지 않는다.
비엔지니어(Non-engineer)의 입장에서 보면, 여기서 배운 것은 "자동화의 적은 고장뿐만이 아니다"라는 사실이었다. 고장이 났다면 비교적 이해하기 쉽다. 에러가 발생한다. 로그가 빨간색으로 변한다. 하지만 수면이나 기동 조건 같은 OS의 동작(Behavior)은 훨씬 더 조용하게 전제 조건을 파괴한다. 조용히 망가지는 것은 알아차리기까지 시간이 걸린다.
그렇기에 RC(Release Candidate) 검증 주간의 가치가 있다. 매일 아침 동일한 조건으로 확인하지 않는다면, 이런 종류의 위화감은 "오늘은 어쩌다 보니 늦었네"라며 그냥 넘어가 버리고 만다. 그냥 넘겨버리면 정식 버전으로 올린 뒤에 운영자가 매일 아침 불안을 떠안게 된다. 아침의 불안을 줄여주어야 할 도구가 또 다른 불안을 늘린다면 의미가 없다.
또 하나 인상 깊었던 것은 최소 수정(Minimal fix)의 의미다. 문제가 보이면 나도 모르게 크게 고치고 싶어진다. 하지만 검증 주간 도중에 크게 변경하면 무엇이 효과가 있었는지 알 수 없게 된다. --wait-for-user-active와 같은 최소 수정에 그친 것은 기술적인 신중함이기도 했고, 기록으로서의 성실함이기도 했다.
이러한 종류의 성실함은 비엔지니어에게 상당히 중요했다. 코드의 세부 사항을 모두 평가할 수는 없더라도, "어느 계층의 문제인지", "무엇을 고쳤는지", "무엇이 아직 미확인 상태인지"가 언어로 구분되어 있다면 공개나 버전(Version) 판단에 참여할 수 있다. 반대로 그 부분이 뒤섞이면 최종 판단은 분위기에 휩쓸리기 쉽다. DarkWake 문제가 가르쳐준 것은 기술적 과제 그 자체뿐만 아니라, 판단에 필요한 입도(Granularity)까지 언어화하는 것의 무게였다고 생각한다.
Human Approval(인간 승인)의 사상과도 조금 맞닿아 있다. 운영 환경의 쓰기 작업(Write operation)에서는 실행할 수 있는 것과 실행해도 좋은 것을 분리했다. 마찬가지로 무인 실행(Unattended execution)에서도 "기동했다는 사실"과 "아침의 전제 조건으로서 신뢰해도 좋다는 사실"은 분리해서 생각해야 했다. AI와 함께하는 개발에서는 작동하는 순간 전진하는 느낌이 강하게 든다. 그렇기에 그 전진감을 그대로 완성으로 간주하지 않기 위한 언어와 경계가 필요했다.
- launchd를 도입한 것과 매일 아침 끝까지 실행할 수 있는 것은 별개의 확인 항목이다
- DarkWake나 Maintenance Sleep 같은 OS의 동작도 운영 품질에 포함된다
- 자동화의 실패는 고장보다 먼저 "전제 조건의 누락"으로서 나타날 수 있다
- 검증 주간에는 큰 개수(Major revision)보다 최소 수정이 배움을 분리하기 쉽다
- 무인 실기 확인이 끝나기 전까지는 수정 후라도 완성형으로 작성하지 않는다
이어서 쓴다면, DarkWake 문제에 대한 최소 수정을 적용한 후에도 왜 Go(배포)를 서두르지 않았는가 하는 이야기로 이어진다. 다만 정식 v1.0.0은 미출시 상태이므로, 최종적인 성공담으로 다루지는 않는다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기