Temporal Workflow (durable execution)
Écrire un workflow long-running comme du code fonctionnel classique, mais avec exécution durable : retry automatique, reprise après crash, sleep durables. La promesse de Temporal — fork de Cadence (Uber) — appliquée aux orchestrations EDI.
Problème
Écrire un workflow saga PO/ORDRSP/DESADV/INVOIC/REMADV qui peut durer 30 jours, gère des retries sur appels externes, persiste son état entre crashes, est observable : c'est complexe. Les solutions classiques imposent soit un BPMN (Camunda) avec courbe d'apprentissage, soit un orchestrateur custom (boucle polling + DB + retry manual), soit des Step Functions JSON verbeux. Le code workflow est dilué dans la mécanique d'orchestration.
Forces
- Les workflows EDI durent longtemps : une saga PO → REMADV peut s'étaler sur 30-60 jours.
- Les retries doivent être robustes : chaque appel externe (validation, ERP, partenaire) peut échouer transitoirement.
- L'état doit survivre aux crashes : process ou nœud Kubernetes qui meurt ne doit pas perdre le workflow.
- Le code doit rester lisible : la logique métier ne doit pas être noyée dans la plomberie de l'orchestration.
- L'observabilité est exigée : pouvoir voir où en est chaque workflow, son historique complet d'événements.
Solution
Temporal (et son ancêtre Cadence) propose une primitive de durable execution : le code workflow s'écrit en fonctions normales, le SDK garantit que chaque appel déterministe est rejoué fidèlement après crash. Les activities (appels side-effects) sont retentées automatiquement selon une retry policy déclarative. Les timers permettent un sleep durable de plusieurs jours. Les signals autorisent l'injection externe d'événements dans un workflow en cours. Le serveur Temporal stocke l'event history complet en Cassandra ou PostgreSQL — c'est ce log qui garantit la durabilité.
Architecture Temporal :
┌───────────────────────────────────────┐
│ Application code (Workflow + Activities) │
│ - Workflow : code orchestrant │
│ - Activity : appel side-effect (HTTP, DB) │
└───────┬─────────────────┬─────────────────┘
│ │
SDK (Go/Java/Python/TS)
│ │
▼ ▼
┌──────────────────────────────────┐
│ Temporal Server │
│ - History service : event log │
│ - Matching service : task queue│
│ - Frontend / Worker │
└──────────┬───────────────────────┘
│
▼
┌──────────────────────────────────┐
│ Persistence (Cassandra/Postgres)│
│ stocke event history complet │
└──────────────────────────────────┘
Le code workflow est REJOUÉ à chaque réveil. L'event history
garantit la déterminisme. Les retries activité sont automatiques.
Timer = sleep duré durable. Signal = injection externe d'événement.
Implémentation EDI
Cas concret : workflow saga PO → ORDRSP → DESADV → INVOIC →
REMADV pour un partenaire automotive. Code Temporal (TypeScript)
simplifié :
async function orderSaga(input: OrderInput) { const ordrsp = await sendPO(input); await wait('48h'); const desadv = await receiveDesadv({...}); const invoice = await receiveInvoice({...}); const remadv = await sendPayment({...}); return remadv; }.
Chaque appel sendPO, receiveDesadv est
une activity retryable. Le wait('48h') est un
timer durable. Si le worker crash pendant le wait, le workflow
reprend où il en était. Si le partenaire est down 4 jours, le
retry transparent attend. Le dashboard Temporal montre l'état
chaque saga avec event history. Le code workflow garde la lisibilité
d'une fonction métier. Production en 2026 : Datadog, Snap,
Stripe, Doordash, HashiCorp Vault utilisent Temporal pour leurs
workflows critiques. Alternative open-source : Cadence
(fork original Uber), io.temporal.* SDK officiel.
Anti-patterns
- Code non déterministe dans le workflow : Math.random(), Date.now() directement dans le workflow — le replay diverge. Toujours passer par les API Temporal (workflow.random, workflow.now).
- Activities trop courtes : chaque activity a une overhead réseau, multiplier des activities triviales sature le système. Granularité métier-pertinente.
- Workflows trop longs en mémoire : un workflow qui accumule 100k events en mémoire devient lourd. Pour les sagas multi-mois, utiliser ContinueAsNew.
- Logique métier dans les activities : l'activity doit être un wrapper minimal autour de l'appel externe ; toute logique va dans le workflow.
- Pas de gestion d'erreur : retry par défaut sans circuit breaker ni timeout = retry storms en cas de panne partenaire prolongée.
Patterns liés
- Process Manager — pattern EIP parent.
- State Machine EDI — Temporal est une implémentation.
- Saga Orchestration — pattern naturellement implémenté en Temporal.
- Step Functions — variante managée AWS.
- Compensating Action — pattern qui s'écrit naturellement en activity Temporal.
Sources
- Temporal Documentation. La référence canonique pour l'écriture de workflows durables avec Temporal. docs.temporal.io
- Temporal Blog — Workflow Execution Model. Explication détaillée du replay et de la durabilité. temporal.io — workflow-engine-principles
- Cadence Documentation (Uber). Le fork original open-source dont Temporal est issu. cadenceworkflow.io
- Fateev M., Manas S. — Temporal: A Cloud-Native Programming Model for Reliable Distributed Applications, conférences QCon et InfoQ 2020-2023.
- Newman S. — Building Microservices, O'Reilly 2015 (2e éd. 2021). Chapitre sur la chorégraphie vs orchestration des sagas.
- Richardson C. — Microservices Patterns, Manning 2018. Chapitre 4 sur les Sagas et leur implémentation en orchestration.