워크플로우
워크플로우
섹션 제목: “워크플로우”워크플로우는 크래시와 재시작을 견디는 내구성 있고 장기 실행되는 작업입니다. 결제, 주문 이행, 다단계 승인과 같은 중요한 비즈니스 프로세스에 대한 신뢰성 보장을 제공합니다.
왜 워크플로우인가?
섹션 제목: “왜 워크플로우인가?”함수는 일시적입니다. 호스트가 크래시하면 진행 중인 작업이 손실됩니다. 워크플로우는 상태를 영속화합니다:
| 측면 | 함수 | 워크플로우 |
|---|---|---|
| 상태 | 메모리 내 | 영속화됨 |
| 크래시 | 작업 손실 | 재개 |
| 기간 | 초에서 분 | 시간에서 월 |
| 완료 | 최선의 노력 | 보장됨 |
워크플로우 작동 방식
섹션 제목: “워크플로우 작동 방식”워크플로우 코드는 일반 Lua 코드처럼 보입니다:
local funcs = require("funcs")local time = require("time")
local result = funcs.call("app.api:charge_card", payment)time.sleep("24h")local status = funcs.call("app.api:check_status", result.id)
if status == "failed" then funcs.call("app.api:refund", result.id)end워크플로우 엔진은 호출을 가로채고 결과를 기록합니다. 프로세스가 크래시하면 기록된 히스토리에서 실행이 리플레이됩니다. 같은 코드로 같은 결과를 얻습니다.
funcs.call(), time.sleep(), uuid.v4(), time.now() 같은 작업이 가로채져 결과가 기록됩니다. 리플레이 시에는 재실행하지 않고 기록된 값이 반환됩니다.
워크플로우 패턴
섹션 제목: “워크플로우 패턴”Saga 패턴
섹션 제목: “Saga 패턴”실패 시 보상:
local funcs = require("funcs")
local inventory = funcs.call("app.inventory:reserve", items)if inventory.error then return nil, inventory.errorend
local payment = funcs.call("app.payments:charge", amount)if payment.error then funcs.call("app.inventory:release", inventory.id) return nil, payment.errorend
local shipping = funcs.call("app.shipping:create", order)if shipping.error then funcs.call("app.payments:refund", payment.id) funcs.call("app.inventory:release", inventory.id) return nil, shipping.errorend
return {inventory = inventory, payment = payment, shipping = shipping}시그널 대기
섹션 제목: “시그널 대기”외부 이벤트(승인 결정, 웹훅, 사용자 액션) 대기:
local funcs = require("funcs")
funcs.call("app.approvals:submit", request)
local inbox = process.inbox()local msg = inbox:receive() -- 시그널이 도착할 때까지 블록
if msg.approved then funcs.call("app.orders:fulfill", request.order_id)else funcs.call("app.notifications:send_rejection", request)end언제 무엇을 사용할까
섹션 제목: “언제 무엇을 사용할까”| 사용 사례 | 선택 |
|---|---|
| HTTP 요청 처리 | 함수 |
| 데이터 변환 | 함수 |
| 백그라운드 작업 | 프로세스 |
| 사용자 세션 상태 | 프로세스 |
| 실시간 메시징 | 프로세스 |
| 결제 처리 | 워크플로우 |
| 주문 이행 | 워크플로우 |
| 다단계 승인 | 워크플로우 |
워크플로우 시작
섹션 제목: “워크플로우 시작”워크플로우는 프로세스와 같은 방식으로 생성됩니다. process.spawn()을 다른 호스트와 함께 사용합니다:
-- temporal 워커에서 워크플로우 생성local pid = process.spawn("app.workflows:order_processor", "app:temporal_worker", order_data)
-- 워크플로우에 시그널 보내기process.send(pid, "update", {status = "approved"})호출자 관점에서 API는 동일합니다. 차이점은 호스트입니다. 워크플로우는 process.host 대신 temporal.worker에서 실행됩니다.
process.spawn()으로 자식을 생성하면, 같은 프로바이더의 자식 워크플로우가 되어 내구성 보장이 유지됩니다.
실패와 슈퍼비전
섹션 제목: “실패와 슈퍼비전”프로세스는 process.service를 사용하여 감독되는 서비스로 실행할 수 있습니다:
# 프로세스 정의- name: session_handler kind: process.lua source: file://session_handler.lua method: main
# 프로세스를 래핑하는 감독 서비스- name: session_manager kind: process.service process: app:session_handler host: app:processes lifecycle: auto_start: true restart: max_attempts: 10워크플로우는 슈퍼비전 트리를 사용하지 않습니다. 워크플로우 프로바이더(Temporal)가 자동으로 관리하며, 영속성, 재시도, 복구를 모두 처리합니다.
워크플로우 정의 (동적으로 생성됨):
- name: order_processor kind: workflow.lua source: file://order_processor.lua method: main modules: - funcs - time워크플로우 프로바이더:
- name: temporal_worker kind: temporal.worker client: app:temporal_client task_queue: "orders" lifecycle: auto_start: true프로덕션 워크플로우 인프라는 Temporal을 참조하세요.