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

상태기계가 진실을 말해

~12 min · state-machine, transitions, cancellation, truth

Level 0마른 펜촉
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"상태는 진입 조건과 증거가 참일 때만 참이야."

status 이름이 진실을 말하게 해

상태 이름은 운영자와 사용자에게 하는 약속이야. queued는 가능하지만 아직 claim 안 됐고, running은 attempt가 진행 중이며, done은 guarded 번역이나 리뷰가 착지했다는 뜻이야. failed는 오류를 남기고 명시적 retry를 거쳐 queued로 돌아갈 수 있어.

합법 전이를 한곳에 모아

허용 전이를 한곳에서 정의하고 나머지는 거절해. done은 terminal이야. failed는 retry 연산으로만 queued에 돌아가고, 다음 claim이 새 attempt 기록을 만들어.

스키마가 설명 못 할 역사를 거절해

아무 update나 상태를 바꾸게 두면 finished_at 없는 done, error 없는 failed, started_at 없는 running 같은 불가능한 역사가 생겨. 검증은 dashboard 수리 script가 아니라 전환 옆에 있어야 해.

운영 불변식. 상태는 진입 조건과 증거가 참일 때만 참이야.

crash를 시간선에 넣어

이 설계는 평온한 demo가 아니라 아무 순간에 process가 사라지는 시간선에서 시험해야 해. 수락 전, commit 뒤, claim 뒤, 외부 호출 뒤, 결과 저장 뒤에 각각 crash를 놓고 database가 무엇을 말하는지 적어. 사용자가 같은 요청을 다시 보내도 돈과 문장이 두 번 생기지 않아야 해.

직접 설계해

각 상태의 진입 조건을 쓰고 validator가 거절할 불가능한 행 세 개를 찾아. status와 timestamp, error, attempt 행을 같이 써. 복구 script가 추측으로 행을 덮지 않고 어떤 증거로 전환하는지 설명해.

관찰 가능성이 복구 가능성이야

운영자가 SQL 한 번으로 queued, running, failed, done을 구분하고 다음 안전 행동을 알 수 있어야 해. 알 수 없는 침묵을 queue라고 부르면 기다림은 이미 데이터를 잃은 거야.

운영 증거를 남겨

done에는 finished_at이, running에는 started_at이, failed에는 error가 필요해. 증거 없는 상태는 이름과 행이 어긋난 역사야. 전이 함수가 이 조합을 한곳에서 거절해야 dashboard가 거짓을 수리하지 않아도 돼.

느린 외부 호출은 transaction 밖에 두고, claim과 완료만 짧고 atomic하게 만들어. 그래야 기다림이 database 전체를 잠그지 않아.

Code

진실한 상태 전이만 허용해·python
ALLOWED = {
    "queued": {"running", "failed"},
    "running": {"done", "failed"},
    "failed": {"queued"},
    "done": set(),
}

def transition(current, target):
    if target not in ALLOWED[current]:
        raise ValueError(f"illegal transition {current}->{target}")
    return target

print(transition("failed", "queued"))

External links

Exercise

각 상태의 진입 조건을 쓰고 validator가 거절할 불가능한 행 세 개를 찾아.
Hint
crash 위치를 하나씩 옮겨가며 데이터가 남는지 봐.

Progress

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

댓글 0

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

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