컴퓨트 유닛
Wippy는 함수, 프로세스, 워크플로우의 세 가지 코드 실행 방식을 제공합니다. 동일한 기본 메커니즘을 공유하지만 수명, 상태 저장 위치, 실패 시 동작이 다릅니다.
함수
함수는 가장 단순한 모델입니다. 호출하면 실행되고 결과를 반환합니다. 호출 간에 상태가 유지되지 않습니다.
local result = funcs.call("app.math:add", 2, 3)
함수는 호출자의 컨텍스트에서 실행됩니다. 호출자가 취소하거나 종료하면 실행 중인 함수도 함께 취소됩니다. 별도의 정리 작업이 필요 없어 간단합니다.
프로세스
프로세스는 액터입니다. 여러 메시지에 걸쳐 상태를 유지하고, 시작한 사람과 독립적으로 실행되며, 메시지 전달을 통해 통신합니다.
local pid = process.spawn("app.workers:handler", "app:processes")
process.send(pid, "job", {task = "process_data"})
프로세스를 생성하면 생성자의 코드가 완료된 후에도 계속 실행됩니다. 프로세스는 서로 모니터링하고 링크하여 실패한 자식을 자동으로 재시작하는 슈퍼비전 트리를 형성할 수 있습니다.
스케줄러는 워커 풀에서 수천 개의 프로세스를 멀티플렉싱합니다. 각 프로세스는 I/O를 기다릴 때 양보하여 다른 프로세스가 실행될 수 있게 합니다.
워크플로우
워크플로우는 반드시 완료되어야 하는 작업을 위한 것입니다. 상태를 워크플로우 프로바이더(Temporal 등)에 영속화하여 크래시, 재시작, 인프라 변경 후에도 중단된 지점에서 정확히 재개할 수 있습니다.
-- 며칠 동안 실행될 수 있고, 재시작을 견디며, 진행 상황을 잃지 않음
workflow.execute("app.orders:process", order_id)
단점은 지연 시간입니다. 모든 단계가 기록되므로 워크플로우는 함수나 프로세스보다 느립니다. 하지만 다단계 비즈니스 프로세스나 장기 실행 오케스트레이션에서는 그 내구성이 충분한 가치가 있습니다.
비교
| 함수 | 프로세스 | 워크플로우 | |
|---|---|---|---|
| 상태 | 없음 | 메모리 내 | 영속화됨 |
| 수명 | 단일 호출 | 종료 또는 크래시까지 | 모든 것을 견딤 |
| 통신 | 반환값 + 메시지 | 메시지 전달 | 액티비티 호출 + 메시지 |
| 실패 처리 | 호출자가 처리 | 슈퍼비전 트리 | 자동 재시도 |
| 지연 시간 | 최저 | 낮음 | 높음 |
같은 코드, 다른 동작
많은 모듈이 컨텍스트에 따라 자동으로 적응합니다. 예를 들어 함수에서 time.sleep()은 워커를 블록하고, 프로세스에서는 다른 프로세스가 실행될 수 있도록 양보하며, 워크플로우에서는 복구 시 올바르게 리플레이되는 타이머로 기록됩니다.