"단일 launchd 소유 프로세스가 제품 몸통 전부야. UI 액션은 그 안으로 호출하지, 절대 두 번째 daemon을 안 낳아."
스피커는 단일 자원이야
오디오 출력은 물리적 물건 하나야. 두 프로세스가 둘 다 그걸 소유하려 들면 끊김이랑 레이스, 겹치거나 끊기는 오디오가 나와. 그래서 Bellows는 launchd가 관리하는 프로덕션 프로세스 딱 하나로 돌아. 그 프로세스가 제품 몸통 전체야. API를 서빙하고, 빌드된 UI를 서빙하고, 자기 lifespan 안에서 오디오 worker를 소유해. 별개 오디오 daemon도 side socket도 없어.
launchd가 살려두고, 앱이 하나로 지켜
launchd job은 load 때 시작해서 살아있게 설정돼. 프로세스가 죽으면 launchd가 되살리고. 그게 가용성을 맡아. 다른 절반은 앱이 자기한테 거는 규칙이야. UI 액션은 '돕겠다고' shadow daemon을 절대 fork 안 해. 모든 요청이 하나의 기존 worker를 몰아. 가용성은 launchd의 일이고, 단일성은 앱의 규율이야. 둘이 합쳐지면 스피커 소유자가 늘 정확히 하나, 늘 같은 하나가 돼.
왜 shadow daemon이 적이냐면
솔깃한 버그는 특정 작업 하려고 띄운 백그라운드 헬퍼야. 재생하는 빠른 두 번째 프로세스, 요청마다 fork된 worker. 각각이 단일 오디오 디바이스에 대한 새 청구자고, 이제 '지금 누가 재생하나'가 하나 넘는 답을 갖게 돼. 프로세스 수를 양쪽에서 눌러 정확히 하나로 유지하는 게, 오디오가 단일하고 멀쩡한 소유자를 가진 것처럼 굴게 만들어.