Temporal — '재시도·멱등성·멈춘 실행의 가시성'이 실제로 사는 곳
Temporal은 **내구성 있는 워크플로 오케스트레이션**입니다 — 워크플로 코드를 **결정론적으로 재생(replay)**해 죽은 프로세스가 상태를 잃지 않게 하고, 재시도·타임아웃·보상 트랜잭션·며칠짜리 대기가 **1급 개념**입니다. 이중 쓰기 종료 조건 문제가 계속 묘사하던 바로 그 제품이고 — **장기 실행 + 외부 대기** 패턴인 정산 플로우가 교과서적으로 맞습니다 — **코드 작성 방식을 바꾸는 결정론 제약**을 대가로.
이 페이지는 카드에 적힌 내용을 펼쳐 보여줄 뿐입니다 — 돌아가는 코드도, 열어볼 데모도 아직 없습니다. 무엇을 왜 만들려는지가 아래에 있습니다.
아직 범위 미정 — 산출물은 플랫폼 도입이 아니라 **실제 플로우 하나에 대한 적합성 테스트**입니다. 이미 장기 실행·외부 대기 모양(제출 → 확인 대기 → 대사 → 해제)을 가진 정산·마이그레이션 플로우를 골라 두 번 모델링합니다 — 한 번은 직접 만들 **크론 + 상태 테이블**로, 한 번은 **Temporal 워크플로**로. Temporal이 파는 네 가지 — 재시도, 멱등성, 멈춘 실행의 가시성, 실행 중 코드 변경 — 와, 그것이 더하는 두 비용으로 비교합니다 — **결정론 제약**(워크플로 코드에 직접 난수·시각 읽기·네트워크 호출 금지 — 액티비티로 이동)과 **운영 비용**(자체 호스팅 워커 비용 대 Temporal Cloud 액션 단가, 그리고 재생 비용을 키우는 워크플로당 이벤트 히스토리 크기). 같은 표에 둘 대안: Inngest(작은 백엔드에 가벼움), Restate, 그리고 직접 만든 크론 + 상태 테이블 자체. 출처: Temporal — 결정론적 재생을 통한 내구성 실행.
기술 노트
각 항목이 실제로 무엇을 보여주고 어떻게 동작하는지 — 위 카드보다 자세한 기술 설명입니다.
목적: **Temporal은 이 카탈로그가 서로 다른 문으로 계속 도착하는 질문에 대한 포장된 답입니다.** 패턴은 늘 같습니다 — 프로세스가 실행 중 자신의 죽음을 견디고, 성공한 부분은 다시 하지 않으면서 실패한 부분만 재시도하고, 외부의 무언가를 며칠 기다리고, 운영자가 어디서 멈췄는지 볼 수 있어야 합니다. `circuit-breaker-saga`는 장애 격리에서, `x402-settlement-retry`는 결제 재시도에서, `irreversible-switch-design`은 종료일이 있는 이중 쓰기 전환에서 여기 도달했습니다. **내구성 실행(durable execution)**이 셋 다 손으로 짓던 것의 이름입니다. **메커니즘은 한 아이디어 — 결정론적 재생 — 이고, 그것이 곧 전체 비용이기도 합니다.** Temporal은 변수를 보존하지 않습니다 — **이벤트의 이력**을 보존하고 그 이력에 대해 워크플로 코드를 다시 돌려 상태를 재구성합니다. 워커가 죽어도 있던 자리에서 정확히 재개되는 이유입니다. 그 재생이 옳으려면 워크플로 코드가 **결정론적**이어야 합니다 — 직접 시각 읽기·난수·네트워크 호출 금지. 이것들은 결과로 기록·재생되는 **'액티비티'**로 옮겨갑니다. 그 제약은 세부가 아니라 **코드 작성 방식을 바꾸고**, 도입 전에 플로우를 두 번 모델링할 정직한 이유입니다. **이것은 이 카탈로그가 전에 그린 갈림길을 가진 build-vs-buy 결정입니다.** 직접 만든 크론 + 상태 테이블이 바로 그 '대화 2' 선택지입니다 — 작동하고, 작은 백엔드에는 그것이 알맞은 양의 기계일 수 있습니다. Temporal은 플로우가 진짜로 장기 실행·외부 대기일 때 — 정확히 정산 모양일 때 — 그리고 그런 플로우 수가 **플로우마다 재시도·가시성을 재구현하는 것이 진짜 비용**이 될 만큼 많을 때 무게값을 합니다. `build-rent-or-own-the-rail`이 결제 레일의 같은 갈림길이고, 이건 **실행의** 갈림길입니다. 네 이점에 대고 값을 매길 두 비용은 **워크플로당 이벤트 히스토리 크기**와 **코드에 붙는 결정론 세금**입니다.
동작 방식: ### 세 카드가 따로 도착한 패턴 | 카드 | 내구성 실행에 도달한 경로 | | --- | --- | | `circuit-breaker-saga` | 장애 격리 / 보상 | | `x402-settlement-retry` | 결제를 안전하게 재시도 | | `irreversible-switch-design` | 종료일 있는 이중 쓰기 전환 | 셋 다 원하는 것 — 크래시 생존, 이중지불 없는 재시도, 외부 상태 대기, 멈춘 위치의 가시성. ### 결정론적 재생 — 메커니즘과 그 세금 | | 작동 방식 | 대가 | | --- | --- | --- | | 상태 | 변수 저장이 아니라 이벤트 이력 재생으로 재구성 | 이벤트 히스토리 크기가 재생 비용을 키움 | | 정확성 | 결정론적 워크플로 코드 필요 | 워크플로에 시각/난수/네트워크 금지 — 액티비티로 이동 | | 재개 | 워커 죽음 → 있던 자리에서 정확히 재개 | 제약을 받아들이는 이유 | ### Build vs buy | 선택지 | 알맞을 때 | | --- | --- | | 직접 만든 크론 + 상태 테이블 | 작은 백엔드, 적은 플로우 | | **Temporal** | 장기 실행 + 외부 대기 플로우가 많을 때 | | Inngest / Restate | 더 가벼운 중간 지대 | 두 비용(히스토리 크기, 결정론 세금)을 네 이점(재시도, 멱등성, 가시성, 실행 중 코드 변경)에 대고 값을 매기세요. ### 관련 카드 `circuit-breaker-saga`, `x402-settlement-retry`, `irreversible-switch-design`(이것을 원하는 플로우들), `build-rent-or-own-the-rail`(레일용, 같은 build-vs-buy 갈림길).