"쓰기 전에, 쓸 참이라고 적어. 결제와 기록 사이의 크래시가 비싼 놈이야."
보이지 않는 청구
유료 전사 API 를 부르는 순진한 방법: 요청 보내고, 응답 받고, 저장. 안 되는 순간까지는 잘 돼 — 근데 그 실패가 유독 고약해, 돈이 드니까. provider 가 청구한 뒤, 결과를 저장하기 전에 크래시가 떨어진다고 그려봐. 이제 넌 갖고 있지도 않은 전사에 결제했고 — 더 나쁘게 — 결제했다는 기록이 어디에도 없어. 돈이 조용히 나갔어. 영상 수천 개짜리 run 에서, 그런 보이지 않는 청구 몇 개는 놓치기 쉽고 재구성이 불가능해.
근본 문제: 되돌릴 수 없는 행위(돈 쓰기) 가 그걸 할 의도의 durable 기록 없이 일어났어. 지출이 기록되는 유일한 곳이 저장 실패한 응답이면, 응답을 잃는 게 청구 사실 전체를 잃는 거야.
의도를 먼저 기록해
Recall 은 순서로 고쳐: 어떤 유료 호출 전에도, executor 는 control plane 의 예약 ledger 를 건너야 해. 예약은 사실상 '나 이 정확한 작업에 돈 쓸 참이야' 라고 말하는 durable 행이야. POST 가 나가기 전에 쓰이고 커밋돼. 예약이 존재한 뒤에야 유료 호출이 일어나. 그다음 결과가 그 같은 예약에 기록돼.
이제 크래시를 다시 추적해. executor 가 예약 후 POST 전에 죽으면 — ledger 에 완료 응답 없는 예약이 보이고, 문제인 호출이 정확히 하나임을 알아. 결제 후 결과 기록 전에 죽으면 — 똑같아: 예약이 바로 거기, 확인해야 할 호출을 가리키며 있어. 지출은 절대 보이지 않을 수 없어, 돈이 움직이기 전에 그 의도가 durably 기록됐으니까.
이건 돈을 위한 write-ahead logging 이야
이 모양을 전에 봤어, 이 이름으로는 아니었어도. write-ahead logging 하는 DB 는 뭘 할 참인지를 하기 전에 기록해, 쓰기 중 크래시가 복구되게. 결제 시스템은 청구를 capture 하기 전에 authorization hold 를 걸어, 돈이 움직이기 전에 움직일 의도가 존재하게. Recall 은 동일한 원리를 유료 API 호출에 적용해: 의도의 durable 기록이 되돌릴 수 없는 행위에 선행한다. 예약은 지출을 위한 write-ahead log 야. 이 트랙의 다른 전부 — identity, 모호함, 재시도 정책 — 는 의도가 먼저 적혔다는 사실 위에 지어졌어.