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

작업이 걷는 길

~13 min · state-machine, transitions, recovery

Level 0Finder 에서 헤매는 중
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"작업은 함수 호출이 아냐. 길을 걷는 작은 생물이고, 걸음마다 기록이 남아."

왜 상태로 나눠야 하나

순진하게 짜면 파일 작업은 값을 돌려주거나 예외를 던지는 함수 하나야. 그 모델로는 현실을 못 담아. 작업은 충돌 결정을 기다리는 중일 수도, 사용자가 잠깐 세워둔 중일 수도, 복사 절반쯤일 수도, 볼륨이 사라져 막힌 중일 수도, 크래시 뒤 되살아난 중일 수도 있거든. 그래서 Waygate 는 작업마다 지나갈 수 있는 상태와 그 사이 허용된 이동만 정해두고, 지금 어느 상태인지를 저널에 계속 남겨.

잘 풀릴 때 걷는 길

큰길은 이래. plannedvalidating → (충돌 때문에 사람 선택이 필요하면 awaitingDecision) → readyrunningverifyingcommitted. 화살표 하나하나가 저널에 증거가 붙는 고비야. 상태에 이렇게 정확히 이름을 붙여둬야 크래시 뒤에 날카롭게 물을 수 있어. 우린 어느 상태였고, 거기서 다음으로 넘어가도 안전한가?

널 살리는 상태들

큰길 바깥에 전체를 믿을 만하게 만드는 상태들이 있어. 진행 중이던 작업은 paused, canceled, failed, interrupted, needsReview 중 하나가 될 수 있어. 제일 중요한 규칙은 이거야. 증거가 뒷받침할 때만 자동으로 이어서 진행해. 검증까지 끝난 임시본이 있으면 이어가도 돼. 애매한 건 — 원본 삭제 직전에 죽어버린 이동 같은 건 — needsReview 에 앉아 사람을 기다리지, 절대 알아서 다시 시도하지 않아.

작업은 기록을 남기며 상태를 건너가고, 증거가 뒷받침할 때만 자동으로 이어져. 상태 이름이 작업이 처할 수 있는 모든 상황을 덮으니까 — 멈춤도, 중단도, 검토 대기도 — 복구는 정체불명에 대한 짐작이 아니라 알려진 상태에 대한 정확한 질문이 돼. 애매하면 재시도가 아니라 검토로 가.
awaitingDecision 은 오류가 아니야. 복사가 계획만으로 못 푸는 충돌을 만나면 실패하지도 짐작하지도 않아. awaitingDecision 으로 들어가 선택지를 내놓지. 상태로 나눠두면 '사람이 골라줘야 해' 가 맥락을 다 날려버리는 예외가 아니라, 멀쩡히 이어갈 수 있는 정식 상태가 돼.

Code

작업 상태와 이동·text
  planned
     |
     v
  validating ---> awaitingDecision   (only if a collision needs a choice)
     |                 |
     |  <--------------+  (decision recorded)
     v
  ready --> running --> verifying --> committed   (the happy path)

  From ANY active state:
     --> paused        (cooperative, at a safe checkpoint)
     --> canceled      (cleans only positively-owned artifacts)
     --> failed        (a clean, known error)
     --> interrupted   (crash / kill / unmount)
     --> needsReview    (uncertain -- waits for a human, never auto-retries)
상태는 드러내놓고, 이동만이 유일한 통로·swift
enum OperationState: String {
    case planned, validating, awaitingDecision, ready
    case running, verifying, committed
    case paused, canceled, failed, interrupted, needsReview
}

// Recovery asks a precise question, per state:
func resumable(_ state: OperationState, evidence: Evidence) -> Bool {
    switch state {
    case .staged where evidence.verifiedCopyExists: return true   // safe to continue
    case .interrupted where evidence.destructiveBarrierPassed == false: return true
    default: return false   // uncertain -> needsReview, a human decides
    }
}

External links

Exercise

볼륨 넘는 이동 하나를 상태 그림으로 그려봐. 화살표마다 크래시 뒤에 그 화살표를 안전하게 건너려면 저널에 뭐가 있어야 하는지 적고. '자동으로 이어가기' 가 위험한 화살표는 어느 거야? 왜 거긴 needsReview 로 가야 해?
Hint
위험한 화살표는 제자리로 옮긴 다음의 원본 삭제야. 목적지 사본이 완전하고 검증까지 됐다는 증명이 없으면, 자동 삭제는 멀쩡한 유일본을 날릴 수 있어. 그 화살표는 딱 떨어지는 증거를 요구하고, 없으면 되돌릴 수 없는 일이 벌어지기 전에 사람이 확인하도록 needsReview 에 세워둬.

Progress

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

댓글 0

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

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