Patterns d'Orchestration de Workflows
Maîtrisez l'architecture d'orchestration de workflows avec Temporal, couvrant les décisions de conception fondamentales, les patterns de résilience et les bonnes pratiques pour construire des systèmes distribués fiables.
Quand Utiliser l'Orchestration de Workflows
Cas d'Usage Idéaux (Source: docs.temporal.io)
- Processus multi-étapes s'étendant sur plusieurs machines/services/bases de données
- Transactions distribuées nécessitant une sémantique tout-ou-rien
- Workflows longue durée (heures à années) avec persistance d'état automatique
- Récupération après défaillance devant reprendre à partir de la dernière étape réussie
- Processus métier: réservations, commandes, campagnes, approbations
- Gestion du cycle de vie des entités: suivi d'inventaire, gestion de compte, workflows de panier
- Automatisation infrastructure: pipelines CI/CD, provisionnement, déploiements
- Systèmes avec intervention humaine nécessitant timeouts et escalades
Quand NE PAS Utiliser
- Opérations CRUD simples (utiliser les appels API directs)
- Pipelines de traitement de données pures (utiliser Airflow, traitement batch)
- Requête/réponse sans état (utiliser les API standards)
- Streaming temps réel (utiliser Kafka, processeurs d'événements)
Décision de Conception Critique: Workflows vs Activities
La Règle Fondamentale (Source: temporal.io/blog/workflow-engine-principles):
- Workflows = Logique d'orchestration et prise de décision
- Activities = Interactions externes (APIs, bases de données, appels réseau)
Workflows (Orchestration)
Caractéristiques:
- Contiennent la logique métier et la coordination
- DOIVENT être déterministes (mêmes entrées → mêmes sorties)
- Ne peuvent pas effectuer d'appels externes directs
- État automatiquement préservé lors des défaillances
- Peuvent s'exécuter pendant des années malgré les défaillances infrastructure
Exemples de tâches workflow:
- Décider quelles étapes exécuter
- Gérer la logique de compensation
- Gérer les timeouts et les retries
- Orchestrer les workflows enfants
Activities (Interactions Externes)
Caractéristiques:
- Gèrent toutes les interactions avec systèmes externes
- Peuvent être non-déterministes (appels API, écritures BD)
- Incluent timeouts et logique de retry intégrée
- Doivent être idempotentes (appeler N fois = appeler une fois)
- Courte durée (secondes à minutes généralement)
Exemples de tâches activity:
- Appeler l'API de passerelle de paiement
- Écrire dans une base de données
- Envoyer des emails ou notifications
- Interroger des services externes
Framework de Décision de Conception
Touche-t-il des systèmes externes? → Activity
Est-ce de l'orchestration/logique de décision? → Workflow
Patterns Workflow Principaux
1. Pattern Saga avec Compensation
Objectif: Implémenter des transactions distribuées avec capacité de rollback
Pattern (Source: temporal.io/blog/compensating-actions-part-of-a-complete-breakfast-with-sagas):
Pour chaque étape:
1. Enregistrer la compensation AVANT d'exécuter
2. Exécuter l'étape (via activity)
3. En cas d'échec, exécuter toutes les compensations en ordre inverse (LIFO)
Exemple: Workflow de Paiement
- Réserver l'inventaire (compensation: libérer l'inventaire)
- Facturer le paiement (compensation: rembourser le paiement)
- Accomplir la commande (compensation: annuler l'accomplissement)
Exigences Critiques:
- Les compensations doivent être idempotentes
- Enregistrer la compensation AVANT d'exécuter l'étape
- Exécuter les compensations en ordre inverse
- Gérer les défaillances partielles gracieusement
2. Entity Workflows (Modèle Acteur)
Objectif: Workflow longue durée représentant une instance d'entité unique
Pattern (Source: docs.temporal.io/evaluate/use-cases-design-patterns):
- Une exécution workflow = une entité (panier, compte, article d'inventaire)
- Workflow persiste pendant la durée de vie de l'entité
- Reçoit des signaux pour les changements d'état
- Supporte les requêtes pour l'état actuel
Exemples de Cas d'Usage:
- Panier d'achat (ajouter articles, passer commande, expiration)
- Compte bancaire (dépôts, retraits, vérifications de solde)
- Inventaire produit (mises à jour de stock, réservations)
Avantages:
- Encapsule le comportement de l'entité
- Garantit la cohérence par entité
- Sourçage d'événements naturel
3. Fan-Out/Fan-In (Exécution Parallèle)
Objectif: Exécuter plusieurs tâches en parallèle, agréger les résultats
Pattern:
- Lancer des workflows enfants ou des activities parallèles
- Attendre que tous se terminent
- Agréger les résultats
- Gérer les défaillances partielles
Règle de Scaling (Source: temporal.io/blog/workflow-engine-principles):
- Ne pas scaler les workflows individuels
- Pour 1M tâches: lancer 1K workflows enfants × 1K tâches chacun
- Maintenir chaque workflow borné
4. Pattern Async Callback
Objectif: Attendre un événement externe ou une approbation humaine
Pattern:
- Workflow envoie une requête et attend un signal
- Système externe traite asynchronement
- Envoie un signal pour reprendre le workflow
- Workflow continue avec la réponse
Cas d'Usage:
- Workflows d'approbation humaine
- Callbacks webhook
- Processus externes longue durée
Gestion d'État et Déterminisme
Préservation d'État Automatique
Comment Temporal Fonctionne (Source: docs.temporal.io/workflows):
- État complet du programme préservé automatiquement
- Event History enregistre chaque commande et événement
- Récupération transparente après crashes
- Les applications restaurent l'état pré-défaillance
Contraintes de Déterminisme
Les Workflows S'Exécutent comme des Machines d'État:
- Le comportement de rejeu doit être cohérent
- Mêmes entrées → sorties identiques à chaque fois
Interdit dans les Workflows (Source: docs.temporal.io/workflows):
- ❌ Threading, locks, primitives de synchronisation
- ❌ Génération de nombres aléatoires (
random()) - ❌ État global ou variables statiques
- ❌ Heure système (
datetime.now()) - ❌ E/S directe de fichiers ou appels réseau
- ❌ Bibliothèques non-déterministes
Autorisé dans les Workflows:
- ✅
workflow.now()(heure déterministe) - ✅
workflow.random()(aléatoire déterministe) - ✅ Fonctions pures et calculs
- ✅ Appeler les activities (opérations non-déterministes)
Stratégies de Versioning
Défi: Changer le code workflow pendant que les anciennes exécutions tournent
Solutions:
- API de Versioning: Utiliser
workflow.get_version()pour les changements sûrs - Nouveau Type de Workflow: Créer un nouveau workflow, router les nouvelles exécutions vers lui
- Compatibilité Arrière: Assurer que les anciens événements se rejoueront correctement
Résilience et Gestion d'Erreurs
Politiques de Retry
Comportement Par Défaut: Temporal réessaie les activities indéfiniment
Configurer le Retry:
- Intervalle de retry initial
- Coefficient d'backoff (backoff exponentiel)
- Intervalle maximal (plafonner le délai de retry)
- Nombre maximal de tentatives (finalement échouer)
Erreurs Non-Réessayables:
- Entrée invalide (échecs de validation)
- Violations de règles métier
- Défaillances permanentes (ressource non trouvée)
Exigences d'Idempotence
Pourquoi C'est Critique (Source: docs.temporal.io/activities):
- Les activities peuvent s'exécuter plusieurs fois
- Les défaillances réseau déclenchent des retries
- L'exécution dupliquée doit être sûre
Stratégies d'Implémentation:
- Clés d'idempotence (déduplication)
- Vérifier-puis-agir avec contraintes uniques
- Opérations upsert au lieu d'insert
- Suivre les IDs de requête traités
Heartbeats d'Activity
Objectif: Détecter les activities longue durée bloquées
Pattern:
- Activity envoie un heartbeat périodique
- Inclut des informations de progression
- Timeout s'il n'y a pas de heartbeat reçu
- Permet un retry basé sur la progression
Bonnes Pratiques
Conception de Workflow
- Garder les workflows focalisés - Responsabilité unique par workflow
- Petits workflows - Utiliser les workflows enfants pour la scalabilité
- Limites claires - Workflow orchestre, activities exécutent
- Tester localement - Utiliser l'environnement de test avec time-skipping
Conception d'Activity
- Opérations idempotentes - Sûres pour le retry
- Courte durée - Secondes à minutes, pas des heures
- Configuration de timeout - Toujours définir les timeouts
- Heartbeat pour les tâches longues - Signaler la progression
- Gestion d'erreur - Distinguer retryable vs non-retryable
Pièges Courants
Violations de Workflow:
- Utiliser
datetime.now()au lieu deworkflow.now() - Threading ou opérations async dans le code workflow
- Appeler directement les APIs externes depuis le workflow
- Logique non-déterministe dans les workflows
Erreurs d'Activity:
- Opérations non-idempotentes (ne peuvent pas gérer les retries)
- Timeouts manquants (activities tournent indéfiniment)
- Pas de classification d'erreur (réessayer les erreurs de validation)
- Ignorer les limites de payload (2MB par argument)
Considérations Opérationnelles
Monitoring:
- Durée d'exécution du workflow
- Taux d'échec d'activity
- Tentatives de retry et backoff
- Nombre de workflows en attente
Scalabilité:
- Scalage horizontal avec workers
- Partitionnement de task queue
- Décomposition de workflows enfants
- Batching d'activities quand approprié
Ressources Supplémentaires
Documentation Officielle:
- Concepts Core Temporal: docs.temporal.io/workflows
- Patterns Workflow: docs.temporal.io/evaluate/use-cases-design-patterns
- Bonnes Pratiques: docs.temporal.io/develop/best-practices
- Pattern Saga: temporal.io/blog/saga-pattern-made-easy
Principes Clés:
- Workflows = orchestration, Activities = appels externes
- Le déterminisme est non-négociable pour les workflows
- L'idempotence est critique pour les activities
- La préservation d'état est automatique
- Concevoir pour la défaillance et la récupération