Workflow Automation

Maîtriser les flux de travail durables : une plongée en profondeur dans Temporal

Dans le paysage moderne des systèmes distribués, la création de microservices fiables ne représente que la moitié du combat. L'autre moitié, ou souvent la plus difficile, consiste à orchestrer des interactions complexes entre ces services sans perdre l'état lors de partitions réseau ou de pannes de serveurs. Voici Temporal. Temporal est une plateforme qui apporte les workflows distribués au code. Elle résout les problèmes d'erreurs transitoires, de cohérence des données et de scalabilité en garantissant que les processus métier à long terme survivent aux pannes d'infrastructure. Au lieu d'écrire une logique de retry fragile ou d'implémenter des machines à états personnalisées à l'aide de bases de données et de files d'attente, les développeurs peuvent écrire du code linéaire que Temporal exécute de manière durable.

Les problèmes avec l'orchestration traditionnelle

Traditionnellement, si vous deviez traiter une commande, débiter une carte bancaire, mettre à jour l'inventaire et envoyer un e-mail de confirmation, vous écririez une fonction qui appelle ces API de manière séquentielle. Si la passerelle de paiement dépassait le délai d'attente, votre système pourrait rester bloqué indéfiniment ou entrer dans un état incohérent. Pour remédier à cela, les ingénieurs construisent souvent des mécanismes de retry complexes, des disjoncteurs et des patterns Saga en utilisant des courtiers de messages comme Kafka ou RabbitMQ. Cette approche conduit à du « code spaghetti » où la logique métier est entremêlée avec les préoccupations liées à l'infrastructure. Il est difficile à tester, ardu à déboguer et complexe à mettre à l'échelle. Temporal change ce paradigme en fournissant une « machine virtuelle » pour votre logique métier. Elle enregistre automatiquement l'exécution de votre code. Si votre nœud de travail meurt en plein milieu de l'exécution, Temporal redémarre le nœud et reprend le workflow exactement là où il s'était arrêté, en préservant toutes les variables internes et l'état.

Concepts clés : Workflow vs Activité

Pour tirer pleinement parti de Temporal, vous devez comprendre ses deux abstractions fondamentales : 1. **Workflows :** Il s'agit de fonctions durables et à long terme. Elles doivent être déterministes. Cela signifie qu'elles ne peuvent pas contenir de génération de nombres aléatoires, d'horodatages actuels ou d'appels réseau directs. Elles définissent la logique et l'ordre des opérations. 2. **Activités :** Il s'agit de fonctions à court terme et non déterministes qui effectuent un travail réel, comme appeler une API externe, interroger une base de données ou traiter des données. Les activités font le pont entre votre code de workflow durable et le monde extérieur. En séparant ces préoccupations, Temporal garantit que votre logique métier reste propre et testable, tandis qu'il gère la complexité de l'exécution, des nouvelles tentatives et de la gestion de l'état.

Mise en œuvre pratique

Examinons un exemple pratique en Go, l'un des langages principaux de Temporal. Nous définirons un workflow qui traite une commande, interagit avec un service de paiement et gère les échecs de manière élégante. ```go func ProcessOrderWorkflow(ctx workflow.Context, order OrderID) error { // Définir la politique de retry pour les activités ao := workflow.ActivityOptions{ StartToCloseTimeout: 10 * time.Second, RetryPolicy: &temporal.RetryPolicy{ MaximumAttempts: 5, }, } ctx = workflow.WithActivityOptions(ctx, ao) // Exécuter la première activité var paymentStatus string err := workflow.ExecuteActivity(ctx, ProcessPaymentActivity, order).Get(ctx, &paymentStatus) if err != nil { // Le workflow peut gérer l'erreur ou la faire remonter return err } // Logique conditionnelle basée sur le résultat de l'activité if paymentStatus == "FAILED" { return errors.New("Échec du traitement du paiement") } // Exécuter l'activité suivante err = workflow.ExecuteActivity(ctx, SendConfirmationEmailActivity, order.CustomerEmail).Get(ctx, nil) if err != nil { // Journaliser l'erreur mais continuer le traitement de la mise à jour de l'inventaire workflow.GetLogger(ctx).Error("Échec de l'e-mail", "error", err) } // Mettre à jour l'inventaire return workflow.ExecuteActivity(ctx, UpdateInventoryActivity, order).Get(ctx, nil) } ``` Dans cet exemple, si `ProcessPaymentActivity` échoue, Temporal tentera automatiquement de la réexécuter selon la politique de retry. Si l'échec persiste, le workflow peut décider de la marche à suivre. Notez que le code du workflow lui-même est simple et lisible, exempt de logique de retry répétitive.

Avantages pour le développement d'entreprise

Au-delà de la simplification du code, Temporal offre des avantages opérationnels significatifs. Il fournit une observabilité intégrée via son interface utilisateur, vous permettant de suivre l'exécution de chaque instance de workflow. Vous pouvez voir exactement où un workflow s'est bloqué, quelles données ont été transmises entre les activités et pourquoi une activité a échoué. Cela réduit considérablement le temps moyen de résolution (MTTR) des problèmes de production. De plus, Temporal prend en charge des patterns avancés tels que les workflows enfants, les signaux et les requêtes. Les signaux vous permettent d'envoyer des mises à jour à un workflow en cours d'exécution, tandis que les requêtes vous permettent d'inspecter son état actuel sans arrêter l'exécution. Cela rend Temporal adapté à tout, des tâches par lots simples aux flux d'intégration utilisateur complexes en plusieurs étapes.

Conclusion

Temporal représente un changement de paradigme dans notre approche des systèmes distribués. En traitant les workflows comme des citoyens de premier ordre dans le code, il permet aux développeurs de construire des applications résilientes et évolutives sans se perdre dans les complexités du consensus distribué et de la gestion des erreurs. Pour les équipes souhaitant moderniser leur architecture et réduire la charge cognitive liée à la gestion des microservices, Temporal est un outil inestimable. Que vous utilisiez Go, Python, Java ou TypeScript, l'adoption de Temporal peut transformer votre fiabilité opérationnelle et la vitesse de développement.
Share: