C.W.K.
Stream
Lesson 04 of 05 · published

FileProvider 멈춤

~11 min · war-story, launchd, runtime-snapshot, sync-path

Level 0Empty Shelf
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"손으로 돌리면 돼. 서비스 매니저가 돌리면 hang 돼. 같은 경로, 같은 코드, 같은 기계."

재현을 거부하는 버그

진짜 미치게 하는 게 여기 있어. Recall 의 코드는 관례적 fleet 경로에 살고, 어떤 기계에선 그 경로가 파일 동기화 provider 로 뒷받침돼 — 파일을 '클라우드에' 두고 요청 시 materialize 하는 종류. SSH 로 들어가 손으로 코드를 돌리면 전부 완벽히 돼. 그다음 서비스 매니저가 같은 코드를, 같은 경로에서, 같은 기계에서 시작하면 — 백그라운드 프로세스가 hang 돼, 때론 의미 있는 줄 하나 실행하기도 전에 자기 작업 디렉터리를 해석하다가.

모든 디버깅 본능이 여기서 실패해, 네 본능은 재현하는 거니까 — 근데 재현이 안 돼. 네 인터랙티브 셸은 동기화 provider 의 요청-시 materialization 을 몰아붙일 수 있고; 다른 세션 컨텍스트에서 서비스 매니저가 띄운 프로세스는 절대 materialize 안 되는 파일을 기다리며 거기 앉아 있을 수 있어. 코드는 멀쩡해. 경로는 문자열이 일치한다는 의미에서만 '같아'. 그 문자열을 해석하는 컨텍스트는 전혀 안 같아.

고침: 편집하는 곳과 도는 곳을 분리해

프로그램 안에서 못 고쳐, 프로그램이 돌 기회조차 못 얻으니까. 고침은 구조적이야: 서비스를 동기화 경로에서 아예 돌리지 마. Recall 의 서비스 컨트롤러는 atomic 하게 생성된 runtime snapshot 을 평범한 로컬 application-support 디렉터리에 지어 — git 메타데이터, 캐시, 의존성 폴더, 빌드 출력을 빼고, 런타임 환경 파일을 넣어서. 그다음 서비스 매니저가 그 snapshot 에서, 동기화 provider 가 낀 데 없는 평범한 로컬 경로에서 프로세스를 시작해. 멈춤이 설계로 존재를 없애져.

이걸 안전하게 만드는 규율이 외울 가치 있는 부분이야: snapshot 은 두 번째 repository 가 아냐. 생성됐고, 버릴 수 있고, 절대 편집되면 안 돼. 관례적 checkout 이랑 git 이 코드의 유일한 진실로 남아. repo 에서 편집하고, git 으로 push 하고, 배포 시 snapshot 을 재생성해. 누가 snapshot 에서 '빨리 뭐 좀 고치는' 순간, 진실을 fork 했고 어떤 commit 도 설명 못 하는 행동의 기계를 만든 거야 — 그게 정확히 이 아키텍처 전체가 피하려 지어진 유령이야.

동반 디테일: 멈추기 전에 빌드해

같은 명령에 어렵게 얻은 순서 하나가 더 살아. control-plane 호스트에서, restart 는 현재 도는 프로세스를 멈추기 전에 프로덕션 프론트엔드를 빌드해. 사소한 순서 선택 같지만; 실패한 빌드가 아무 일 아닌 것과 실패한 빌드가 장애인 것의 차이야. 먼저 빌드하면, 깨진 빌드는 건강한 옛 서비스가 계속 서빙하게 둬. 먼저 멈추면, 깨진 빌드는 아무것도 안 도는 상태랑 압박 속에 고칠 깨진 트리를 남겨. 동작하는 걸 내리기 전에 실패할 수 있는 걸 해.

Code

repo 에서 편집; 생성된 snapshot 에서 실행·text
코드 진실 (여기서 편집, 서비스는 여기서 절대 안 돌림):
  동기화 경로의 관례적 checkout
    -> git commit / push / pull

런타임 (생성됨, 버릴 수 있음, 절대 편집 안 함):
  service restart|auto:
    1. 프론트엔드 빌드        <- 실패할 수 있는 걸 먼저
    2. 옛 프로세스 정지          (빌드 실패 = 옛것 계속 살아 있음)
    3. atomic runtime snapshot 을 평범한 로컬 dir 에 씀
         제외: .git, 캐시, node_modules, dist
         포함: 런타임 .env
    4. SNAPSHOT 에서 서비스 시작

# snapshot 은 두 번째 repo 가 아니다. 편집하면 진실이 fork 된다.

External links

Exercise

네 설정의 서비스, cron job, 예약 task 를 찾아 실제로 어디서 도는지 확인해. 그 경로가 클라우드 동기화 폴더, 네트워크 마운트, symlink 된 편의 경로야? 그다음 launch 컨텍스트를 비교해: 서비스 매니저한테서 받는 환경, 작업 디렉터리, 세션이 네 인터랙티브 셸에서와 어떻게 달라? 의미 있게 다르면, 분리를 설계해 — 편집 위치 vs 생성된 실행 위치 — 그리고 실행 사본이 두 번째 진실의 원천이 되는 걸 막으려면 뭘 금지해야 할지 적어봐.
Hint
탐침 둘: (1) 서비스 매니저가 하는 정확히 그 방식으로(손으로 테스트할 방식 말고) job 을 돌려보고 여전히 되는지 봐 — 그 둘의 틈이 이 부류 버그가 사는 곳이야. (2) 런타임 경로가 파일을 게으르게 materialize 하거나 네트워크로 해석하는 뭔가를 포함하는지 물어. 그렇다면 런타임을 평범한 로컬 경로로 옮기고 배포 시 생성해, 버전 관리를 유일한 진실로 두고.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.