본문 바로가기
C.W.K.
Stream
Lesson 01 of 05 · published

없앨 수 없는 충돌 부류

~11 min · concurrency, version-control, architecture, design

Level 0젖은 흙
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

이건 왜 다르냐면

로그 경합이 사라진 건 로그 항목이 작고 자족적인 사실이라서야. 세션이 중앙 프로세스한테 넘기면 끝이지. 커밋은 그게 아냐. 작업이 벌어진 기계에만 존재하는 작업 트리의 상태고, 중앙화하려면 변경 전체를 기록자한테 실어보내야 해. 문제를 푸는 게 아니라 옮기는 거지.

그래서 이 충돌 부류는 없애는 대신 직렬화해. 그리고 그 차이가 중요한 게, 직렬화엔 제거엔 없는 비용이 붙거든. 누군가 기다리고, 죽은 세션이 잠금을 쥐고 있을 수 있고, 쥔 쪽이 영영 안 돌아올 때 뭘 할지에 대한 이야기가 통째로 필요해.

병렬 작업 하루에 실제로 뭐가 터지냐면

추상적인 판은 "커밋 둘이 충돌한다"야. 바쁜 하루를 재본 진짜 판은 더 지저분하고, 미리 알아둘 값어치가 있어.

공유 인덱스. 저장소엔 스테이징 영역이 하나야. 옆 세션이 스테이징한 작업이 거기 들어 있고, 커밋을 네 경로로 좁혀도 그들이 스테이징한 게 안 없어져. 뭘 추가할지만 고르는 거야.

느린 훅. 자산을 다시 만들고 서비스에 동기화하는, 진짜 일을 하는 사전 커밋 훅은 커밋 하나를 몇 분짜리 작업으로 바꿔. 그 창 동안 다른 모든 세션이 다투고, 잠금 파일이 다들 기다리는 대상이 되지.

삼방 갈라짐. 기계 하나는 앞서 있고, 하나는 뒤처져 있고, 하나는 트리가 더럽고, 각각 자기 자리에선 다 맞아. 모두의 가정을 참으로 만드는 순서가 없어.

이웃의 진행 중인 편집. 세션 둘이 같은 공유 설정 파일을 편집 중이고 하나는 반쯤 했어. 그 순간 그 파일을 커밋하면 앞뒤 안 맞는 상태를 네 이름으로 내보내는 거야.

답의 모양

수 넷, 문제마다 하나씩. 다음 네 강의가 차례로 다뤄. 착지를 나눌 수 없게 만드는 리스, 공유 인덱스가 내 커밋에 안 새게 하는 임시 인덱스, 갈라짐을 발견하는 대신 결정하는 의도적 베이스 선택, 그리고 공유 파일을 손으로 스테이징하지 말라는 규칙. 마지막 건 영리한 대안을 실제로 해봤고 훨씬 나빴기 때문에 존재해.

경합을 못 없애면 직렬화하고, 그다음엔 영영 안 돌아오는 보유자를 위해 설계해. 모든 잠금엔 "이걸 쥔 세션이 사라지면 어떡하지"에 대한 답이 필요하고, 그 답이 없는 잠금은 누가 실행 도중에 노트북을 덮는 첫 순간에 일시적 충돌을 영구적 장애로 바꿔놔.

Code

바쁜 하루, 서로 다른 실패 넷·text
SESSION A          SESSION B          SESSION C
(quest one)        (quest two)        (quest three)
     |                  |                  |
     |  stages 92 files across the repo    |
     |<-----------------|                  |
     |                  |                  |
  commit --only <my paths>                 |
     |   ^                                 |
     |   +-- does NOT unstage B's 92 files. one index per repo.
     |                                     |
     |                  |     edits shared config, half done
     |                  |<-----------------|
     |                                     |
  commit includes that half-edit if the path is named
     |
  pre-commit hook runs for 3 minutes (asset sweep)
     |   ^
     |   +-- index.lock held. B and C now blocked on A.
     |
  push -> REJECTED. remote moved while the hook ran.
     |   ^
     |   +-- and the commit already exists, on the wrong base.


FOUR PROBLEMS, FOUR MOVES
  shared index      -> build the commit in a scratch index
  slow hook         -> use plumbing; it does not fire hooks
  divergence        -> fetch first, choose the base, refuse if
                       genuinely diverged
  neighbor's edit   -> never name a shared file you did not
                       finish editing

External links

Exercise

네 자동화 프로세스 둘이 동시에 건드릴 수 있는 공유 가변 자원을 전부 나열해봐. 브랜치, 스테이징 영역, 배포 슬롯, 공유 설정 파일. 각각에 대해 기록자를 중앙화해서 다툼을 없앨 수 있는지 직렬화만 가능한지 적어. 그다음 직렬화하는 것마다 "쥔 쪽이 영영 안 돌아오면"에 대한 답을 써.
Hint
사람들이 잊는 자원은 딱 봐서 데이터가 아닌 것들이야. 브랜치, 빌드 에이전트, 릴리스 채널, 패키지 저장소의 공유 디렉터리. 데이터베이스 행이랑 똑같이 다투는데 대개 잠금이 아예 없어. 팀이 작아서 둘이 동시에 시도하는 일이 드물다는 게 직렬화를 대신해주고 있을 뿐이지.

Progress

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

댓글 0

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

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