docs: 실패의 단위를 정한다 — panic은 scope 트리를 타고 올라간다
"panic이 unrecoverable한 건 프로세스까지인가"라는 질문에 답이 없었다. 답이 없었던 이유는 동시성 모델을 안 정했기 때문이고, 두 질문이 사실 하나다. 정한 것: 실패의 단위는 프로세스가 아니라 태스크다. panic은 콜 스택의 root가 아니라 scope 트리의 root까지 올라간다. scope가 이미 그 모양이기 때문이다 — 렉시컬이고, 블록을 나가는 것이 join이며, 자식이 죽었다는 사실이 부모에게 도달하는 지점이 문법에 이미 있다. 전파는 취소를 정하지 않고도 정의된다. 취소가 생기면 형제들이 언제 멈추는지가 바뀔 뿐 scope가 실패한다는 사실은 안 바뀐다. 그래서 지금 적어도 v1의 취소 설계를 앞당겨 닫지 않는다. 여전히 미정인 것과 그 대가도 적었다: 취소가 없으면 형제 하나가 끝나지 않을 때 죽은 자식의 panic이 join에 도달하지 못한다. 실패가 hang에 가려진다. 그리고 "격리 경계는 recover가 아니다"의 구분선을 명시했다 — 실패한 계산이 만든 값은 경계를 넘지 못하고, 경계가 얻는 것은 죽었다는 사실과 메시지뿐이다. 테스트 러너가 이미 그 원칙대로 돈다. v0는 태스크가 하나라 규칙이 축약된 형태로만 관측되지만, 그 형태로 테스트에 고정했다. 테스트 주석에 "자식 셋이 안 도는 것은 취소가 아니라 순차 실행의 부산물"이라고 적어 뒀다 — 나중에 이걸 취소로 오해하지 않도록. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
This commit is contained in:
@@ -1624,3 +1624,32 @@ let () =
|
||||
check "samples/app의 테스트가 돈다" (List.length rs >= 4);
|
||||
check "samples/app의 테스트가 전부 통과한다"
|
||||
(List.for_all (fun (r : Interp.test_result) -> r.t_failure = None) rs)
|
||||
|
||||
(* panic은 scope 트리를 타고 올라간다. 자식이 panic하면 그 scope는 실패하고,
|
||||
scope 뒤의 코드는 실행되지 않는다.
|
||||
|
||||
v0는 태스크가 하나라 이 규칙이 축약된 형태로만 관측된다. 아래에서 "자식
|
||||
셋"이 안 도는 것은 취소가 아니라 순차 실행의 부산물이다 — 취소는 아직
|
||||
정하지 않았다. 고정하는 것은 전파이지 형제의 운명이 아니다. *)
|
||||
let () =
|
||||
match
|
||||
run_src
|
||||
(console
|
||||
^ "pub fn main(c: Console, root: TaskScope)\n\
|
||||
\ effects {Console.print, TaskScope.spawn} {\n\
|
||||
\ c.print(\"scope 앞\")\n\
|
||||
\ scope work = root {\n\
|
||||
\ work.spawn(fn() { c.print(\"자식 하나\") })\n\
|
||||
\ work.spawn(fn() { panic(\"자식 둘이 죽었다\") })\n\
|
||||
\ }\n\
|
||||
\ c.print(\"scope 뒤\")\n\
|
||||
}")
|
||||
with
|
||||
| out, Some e ->
|
||||
check "자식의 panic이 scope 밖으로 전파된다" (has_sub e.message "자식 둘이 죽었다");
|
||||
check "panic 전의 출력은 남는다" (has_sub out "자식 하나");
|
||||
check "scope 뒤는 실행되지 않는다" (not (has_sub out "scope 뒤"))
|
||||
| _, None ->
|
||||
check "자식의 panic이 scope 밖으로 전파된다" false;
|
||||
check "panic 전의 출력은 남는다" false;
|
||||
check "scope 뒤는 실행되지 않는다" false
|
||||
|
||||
Reference in New Issue
Block a user