Example 09 — Order Processing (Saga Pattern)¶
File: files/examples/order-processing.toml Industry: E-Commerce Tags: ecommerce, saga, orders
Features Demonstrated¶
- Strict sequential dependency chain (Saga)
- Task-level
on_failurecompensating transactions for every step registerfor order_id, payment_id, reservation_id, fulfillment_id, tracking_numberretries+retry_delayon payment and fulfillmenttimeoutper transaction stepignore_failureon notification tasksifconditional for loyalty points gateenvfor service endpoints
Why this pattern matters¶
An e-commerce order touches multiple external systems — payment gateway, inventory service, fulfillment provider, shipping carrier. Each step has a side effect that must be undone if a later step fails. You cannot simply re-run: you cannot charge the customer twice, and you cannot leave a reservation in inventory for an order that was never fulfilled.
The Saga pattern (compensating transactions) is the standard solution. wf's on_failure wiring makes it explicit and auditable: place-payment is directly wired to refund-payment, reserve-inventory to release-inventory. When a failure occurs, the forensic task runs with {{.failed_task}} and {{.error_message}} already populated — the compensating transaction knows exactly what happened and to what. Every transaction ID registered before the failure is available for the rollback to use.
Pipeline Structure¶
[validate-order]
└── [place-payment] → payment_id
└── [reserve-inventory] → reservation_id
└── [create-fulfillment] → fulfillment_id
└── [arrange-shipping] → tracking_number
├── [send-confirmation] (ignore_failure)
└── [credit-loyalty-points] (if order_total > 100)
Compensating transactions (on_failure):
place-payment → refund-payment
reserve-inventory → release-inventory
create-fulfillment → cancel-fulfillment
Run Commands¶
# Sequential (strict order required)
wf run order-processing --print-output
# Visualise the chain + forensic handlers
wf graph order-processing
wf graph order-processing --forensic # shows all compensating transactions
# Visualise as mermaid
wf graph order-processing --format mermaid
What to Observe¶
- Every task depends on the previous — pure sequential chain
wf inspectshows:order_id,payment_id,reservation_id,fulfillment_id,tracking_numbercredit-loyalty-pointsis gated by anifcondition onorder_total- The three forensic handlers (
refund-payment,release-inventory,cancel-fulfillment) are visible withwf graph --forensicbut excluded from normal execution send-confirmationhasignore_failure = true— notification failures don't abort the order
Testing the Saga¶
To see a compensating transaction fire, modify the TOML to temporarily make a task fail:
# Edit create-fulfillment to fail:
# cmd = "exit 1"
# Then run:
wf run order-processing --print-output
wf audit $(wf runs --limit 1 | awk 'NR==2{print $1}')
# forensic_triggered event for cancel-fulfillment appears