본문 바로가기
C.W.K.
Stream
Lesson 02 of 04 · published

census 와 거기서 나오는 drift

~13 min · firelink, census, probes, git

Level 0식은 재
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"census 는 뭐가 맞아야 하는지 안 물어. 직접 가서 봐."

census 가 실제로 재는 것들

census 는 Firelink 가 '보는' 행위야. 멤버마다 정해진 사실들을 읽기만 해서 재. 폴더랑 repository 가 있는지. Git 브랜치는 뭐고, 안 커밋한 파일이 있는지, upstream 이랑 얼마나 벌어졌는지. GitHub 에 있는지. 버전은 뭔지. 네이티브 번들이 깔렸는지, 그 프로세스가 실제로 도는지. 등록된 서비스 상태는 어떤지. web endpoint 가 살았는지. launchd 가 쥐고 있는지. Tailscale Serve 가 어떻게 물려 있는지. 하나도 적힌 걸 가져온 게 아냐. 전부 지금, host 에서 잰 값이지. 아는 허브랑 기억하는 허브의 차이가 여기서 갈려.

사람들이 제일 자주 걸리는 게 커밋 안 한 변경이야. '다른 Mac 에서 커밋 깜빡한 게 어느 repo 지?' census 는 이걸 기억이 아니라 측정으로 답해. Git status 를 실제로 돌려서 손댄 파일이랑 앞뒤로 벌어진 커밋 수를 보고하거든. 맨 첫 레슨에 나왔던 그 허브 질문 중 하나가, 여기서 이렇게 답을 얻어.

drift 는 본 것과 적힌 게 만나는 자리야

잰 값은 전부 적힌 것과 견줘보고, 그 틈이 drift 보고서가 돼. roster 에서 빠진 관리 repo. 없거나 서로 안 맞는 network 선언. 없거나 망가진 operation 설정. 적혀 있는데 안 깔린 서비스. 없는 GitHub repo. 알 수 없는 버전. 이 클라이언트에선 못 여는 실행 대상. drift 는 실패가 아냐. 지도랑 실제 땅이 어긋난 자리를 정직하게 적어둔 거고, 어떻게 할지는 사람이 정하라고 꺼내놓은 거야.

census 는 보기만 하고 고치진 않아

probe 는 전부 읽기만 해. census 는 보고 시각을 찍을 뿐이야. 몰래 되돌려 쓰지도, 지우지도, 은퇴시키지도, 다시 쓰지도, 제품 의도를 짐작하지도 않아. repo 에 커밋 안 한 게 있다, 서비스가 없다, 버전을 모르겠다. 이런 건 얼마든지 알려줘. 그러고는 멈춰. 그걸 어떻게 할지는 사람 몫이니까. 보는 게 census 일의 전부고, 만지지 않고 보기만 하니까 아무 때나 돌려도 안전한 거야.

관찰은 넓게 하되 읽기만 해. 많이 재고 아무것도 안 바꾸는 census 는 원하는 만큼 자주 돌려도 되고, 믿어도 되고, 사고의 원인이 될 일도 없어. '읽기'가 쓰기도 할 수 있게 되는 순간, 돌리기가 무서운 물건을 만든 거야.

Code

census: 읽기만 하는 probe 여럿, 전부 시각 기록·python
def observe(member) -> ObservedState:
    now = clock.now()
    return ObservedState(
        measured_at   = now,
        on_disk       = repo_dir_exists(member),
        git           = git_probe(member),      # branch, dirty paths, ahead/behind
        github        = github_presence(member), # exists / absent / inaccessible
        version       = discover_version(member),# from cwk-product.json, else unknown
        installed_app = bundle_installed(member), # native app present?
        process       = process_running(member), # and is it actually running?
        service       = service_state(member),   # running|stopped|missing|unknown
        endpoint      = endpoint_health(member),  # HTTP health probe
        launchd       = launchd_owned(member),    # owned by the expected job?
    )
    # Every field is MEASURED. Nothing here writes, deletes, or repairs.
    # Compare against declared truth elsewhere -> that produces DRIFT.

External links

Exercise

네가 돌리는 뭔가를 놓고, '이 서비스 멀쩡하고 최신이야?' 에 정직하게 답하려면 뭘 재야 하는지 다 적어봐. config 에 적힌 것과 직접 재야 하는 걸 갈라놓고. 그다음 확인해. 네가 재는 것들은 전부 읽기만 해? 실수로 뭔가를 바꿀 수 있는 probe 를 찾아서, 순수하게 읽는 부분이랑 따로 신중하게 쓰는 부분으로 어떻게 가를지 적어봐.
Hint
로그인을 하거나, 서비스를 깨우거나, 확인한다고 파일을 건드리는 probe 는 사실 쓰기야. 부작용 있는 읽기가 사람들을 모니터 돌리기 무섭게 만들어. 보는 일이랑 만지는 일을 갈라놔.

Progress

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

댓글 0

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

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