

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Fonctions durables Lambda
<a name="durable-functions"></a>

Les fonctions durables de Lambda vous permettent de créer des applications résilientes en plusieurs étapes et des flux de travail d'IA pouvant être exécutés pendant un an tout en maintenant une progression fiable malgré les interruptions. Lorsqu'une fonction durable est exécutée, ce cycle de vie complet est appelé exécution durable, qui utilise des points de contrôle pour suivre la progression et rétablir automatiquement les défaillances par le biais d'une rediffusion, en la réexécutant depuis le début tout en omettant le travail terminé.

Dans chaque fonction, vous utilisez des opérations durables comme éléments fondamentaux. Les étapes exécutent la logique métier grâce aux nouvelles tentatives intégrées et au suivi de la progression, tandis que les temps d'attente suspendent l'exécution sans frais de calcul, ce qui les rend idéales pour les processus de longue durée tels que les human-in-the-loop flux de travail ou l'analyse des dépendances externes. Qu'il s'agisse de traiter des commandes, de coordonner des microservices ou d'orchestrer des applications d'IA agentic, les fonctions durables maintiennent automatiquement l'état et se rétablissent en cas de panne pendant que vous écrivez du code dans des langages de programmation familiers.

## Principaux avantages
<a name="durable-functions-benefits"></a>

**Écrivez du code résilient naturellement :** avec des structures de programmation familières, vous pouvez écrire du code qui gère automatiquement les défaillances. Grâce au point de contrôle intégré, aux nouvelles tentatives transparentes et à la restauration automatique, votre logique métier reste claire et ciblée.

**Payez uniquement pour ce que vous utilisez :** pendant les opérations d'attente, votre fonction est suspendue sans frais de calcul. Pour les flux de travail de longue durée qui attendent des heures ou des jours, vous ne payez que pour le temps de traitement réel, et non pour les temps d'attente inactifs.

**Simplicité opérationnelle :** avec le modèle sans serveur de Lambda, vous bénéficiez d'une mise à l'échelle automatique scale-to-zero, y compris sans gérer l'infrastructure. Les fonctions durables gèrent automatiquement la gestion des états, la logique des nouvelles tentatives et la reprise en cas de panne, réduisant ainsi les frais opérationnels.

## Quand utiliser des fonctions durables
<a name="durable-functions-use-cases"></a>

**Coordination de courte durée :** coordonnez les paiements, les stocks et les expéditions entre plusieurs services avec annulation automatique en cas de panne. Traitez les commandes par le biais de la validation, de l'autorisation de paiement, de l'allocation des stocks et de l'exécution avec une garantie d'exécution.

**Traitez les paiements en toute confiance :** créez des flux de paiement résilients qui maintiennent l'état des transactions en cas d'échec et gèrent automatiquement les nouvelles tentatives. Coordonnez l'autorisation en plusieurs étapes, les contrôles antifraude et le règlement entre les fournisseurs de paiement avec une auditabilité totale à chaque étape.

Créez **des flux de travail d'IA fiables :** créez des flux de travail d'IA en plusieurs étapes qui enchaînent les appels, intègrent les commentaires humains et gèrent les tâches de longue durée de manière déterministe en cas de panne. Reprenez automatiquement après la suspension et ne payez que pour le temps d'exécution actif.

**Orchestrez le traitement des commandes complexes :** coordonnez le traitement des commandes entre les systèmes d'inventaire, de paiement, d'expédition et de notification grâce à une résilience intégrée. Gérez automatiquement les défaillances partielles, préservez l'état des commandes malgré les interruptions et attendez efficacement les événements externes sans consommer de ressources informatiques.

**Automatisez les flux de travail commerciaux en plusieurs étapes :** créez des flux de travail fiables pour l'intégration des employés, l'approbation des prêts et les processus de conformité qui s'étendent sur des jours ou des semaines. Maintenez l'état du flux de travail lors des approbations humaines, des intégrations de systèmes et des tâches planifiées tout en offrant une visibilité complète sur l'état et l'historique des processus.

### Comment les fonctions durables se comparent aux Step Functions
<a name="durable-functions-vs-step-functions"></a>

Les fonctions durables et les Step Functions permettent d'orchestrer le flux de travail avec une gestion automatique des états. Les principales différences résident dans l'endroit où ils s'exécutent et dans la façon dont vous définissez les flux de travail :
+ **Fonctions durables :** exécution dans Lambda, utilisation de langages de programmation standard, gestion dans l'environnement Lambda
+ **Step Functions :** service autonome, DSL basé sur des graphiques ou concepteur visuel, entièrement géré sans maintenance

Les fonctions durables sont idéales pour le développement d'applications dans Lambda, où les flux de travail sont étroitement liés à la logique métier. Step Functions excelle dans l'orchestration des flux de travail entre les AWS services nécessitant une conception visuelle, des intégrations natives à plus de 220 services et une infrastructure sans maintenance.

Pour une comparaison détaillée, voir [Durable functions ou Step Functions](durable-step-functions.md).

## Comment ça marche
<a name="durable-functions-how-it-works"></a>

 En résumé, les fonctions durables sont des fonctions Lambda classiques utilisant un checkpoint/replay mécanisme permettant de suivre les progrès et de soutenir les opérations de longue durée grâce à des points de suspension définis par l'utilisateur, communément appelés « exécution durable ». Une fois que votre fonction a repris après une pause ou une interruption, le système effectue une rediffusion. Pendant la rediffusion, votre code s'exécute depuis le début mais ignore les points de contrôle terminés, utilisant les résultats enregistrés au lieu de réexécuter les opérations terminées. Ce mécanisme de rediffusion garantit la cohérence tout en permettant des exécutions de longue durée.

Pour exploiter ce checkpoint-and-replay mécanisme dans vos applications, Lambda fournit un SDK d'exécution durable. Le SDK élimine la complexité de la gestion des points de contrôle et de la rediffusion en exposant des primitives simples appelées opérations durables que vous utilisez dans votre code. Le SDK est disponible pour JavaScript Python et Java (version préliminaire) et s'intègre parfaitement à votre flux de travail de développement Lambda existant. TypeScript

Avec le SDK, vous pouvez encapsuler votre gestionnaire d'événements Lambda, qui fournit ensuite DurableContext un lien avec votre événement. Ce contexte vous donne accès à des opérations durables telles que les étapes et les attentes. Vous écrivez la logique de votre fonction sous forme de code séquentiel normal, mais au lieu d'appeler directement les services, vous regroupez ces appels par étapes pour des points de contrôle et des tentatives automatiques. Lorsque vous devez suspendre l'exécution, vous ajoutez des temps d'attente qui suspendent votre fonction sans encourir de frais. Le SDK gère toute la complexité de la gestion des états et de la rediffusion en arrière-plan, afin que votre code reste propre et lisible.

 ![\[Filter for Amazon Inspector results related to Lambda functions\]](http://docs.aws.amazon.com/fr_fr/lambda/latest/dg/images/how_durable_works.png) 

## Étapes suivantes
<a name="durable-functions-next-steps"></a>
+ [Commencez avec des fonctions durables](durable-getting-started.md)
+ [Découvrez le SDK d'exécution durable](durable-execution-sdk.md)
+ [Fonctions durables ou Step Functions](durable-step-functions.md)
+ [Surveillez et déboguez les fonctions durables](durable-monitoring.md)
+ [Vérifiez la sécurité et les autorisations](durable-security.md)
+ [Suivez les meilleures pratiques](durable-best-practices.md)

# Concepts de base
<a name="durable-basic-concepts"></a>

Lambda fournit une exécution durable SDKs pour JavaScript TypeScript, et Python. Ils SDKs constituent la base de la création de fonctions durables, fournissant les primitives dont vous avez besoin pour contrôler la progression, gérer les nouvelles tentatives et gérer le flux d'exécution. Pour obtenir une documentation complète et des exemples du SDK, consultez le [TypeScript SDKJavaScript/et le SDK](https://github.com/aws/aws-durable-execution-sdk-js) [Python](https://github.com/aws/aws-durable-execution-sdk-python) sur. GitHub

## Exécution durable
<a name="durable-execution-concept"></a>

Une **exécution durable** représente le cycle de vie complet d'une fonction durable Lambda, utilisant un point de contrôle et un mécanisme de réexécution pour suivre l'évolution de la logique métier, suspendre l'exécution et rétablir les opérations en cas de défaillance. Lorsque les fonctions reprennent après une suspension ou une interruption, les points de contrôle précédemment complétés sont rejoués et la fonction poursuit son exécution.

Le cycle de vie peut inclure plusieurs invocations d'une fonction Lambda pour terminer l'exécution, en particulier après des suspensions ou une reprise après défaillance. Cette approche permet à votre fonction de fonctionner pendant de longues périodes (jusqu'à un an) tout en maintenant une progression fiable malgré les interruptions.

**Comment fonctionne le replay**  
Lambda tient un journal de toutes les opérations durables (étapes, attentes et autres opérations) au fur et à mesure de l'exécution de votre fonction. Lorsque votre fonction doit être mise en pause ou rencontre une interruption, Lambda enregistre ce journal de points de contrôle et arrête l'exécution. Au moment de reprendre, Lambda invoque à nouveau votre fonction depuis le début et rejoue le journal des points de contrôle, en substituant des valeurs stockées aux opérations terminées. Cela signifie que votre code s'exécute à nouveau, mais que les étapes précédemment effectuées ne sont pas réexécutées. Leurs résultats enregistrés sont utilisés à la place.

Ce mécanisme de rediffusion est fondamental pour comprendre les fonctions durables. Votre code doit être déterministe lors de la rediffusion, c'est-à-dire qu'il produit les mêmes résultats avec les mêmes entrées. Évitez les opérations comportant des effets secondaires (comme la génération de nombres aléatoires ou l'obtention de l'heure actuelle) en dehors des étapes, car elles peuvent produire des valeurs différentes lors de la rediffusion et entraîner un comportement non déterministe.

## DurableContext
<a name="durable-context-concept"></a>

**DurableContext**est l'objet de contexte que reçoit votre fonction durable. Il fournit des méthodes pour des opérations durables, telles que des étapes et des attentes qui créent des points de contrôle et gèrent le flux d'exécution.

Votre fonction durable reçoit un contexte Lambda `DurableContext` au lieu du contexte par défaut :

------
#### [ TypeScript ]

```
import {
  DurableContext,
  withDurableExecution,
} from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const result = await context.step(async () => {
      return "step completed";
    });
    return result;
  },
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import (
    DurableContext,
    durable_execution,
    durable_step,
)

@durable_step
def my_step(step_context, data):
    # Your business logic
    return result

@durable_execution
def handler(event, context: DurableContext):
    result = context.step(my_step(event["data"]))
    return result
```

------

Le SDK Python pour les fonctions durables utilise des méthodes synchrones et ne les prend pas en charge. `await` Le TypeScript SDK utilise`async/await`.

## Étapes
<a name="steps-concept"></a>

**Steps** exécute une logique métier avec des tentatives intégrées et des points de contrôle automatiques. Chaque étape enregistre son résultat, ce qui garantit que votre fonction peut reprendre à partir de n'importe quelle étape terminée après une interruption.

------
#### [ TypeScript ]

```
// Each step is automatically checkpointed
const order = await context.step(async () => processOrder(event));
const payment = await context.step(async () => processPayment(order));
const result = await context.step(async () => completeOrder(payment));
```

------
#### [ Python ]

```
# Each step is automatically checkpointed
order = context.step(lambda: process_order(event))
payment = context.step(lambda: process_payment(order))
result = context.step(lambda: complete_order(payment))
```

------

## États d'attente
<a name="wait-states-concept"></a>

Les **états d'attente** sont des pauses planifiées pendant lesquelles votre fonction cesse de fonctionner (et de se recharger) jusqu'à ce qu'il soit temps de continuer. Utilisez-les pour attendre des périodes, des rappels externes ou des conditions spécifiques.

------
#### [ TypeScript ]

```
// Wait for 1 hour without consuming resources
await context.wait({ seconds:3600 });

// Wait for external callback
const approval = await context.waitForCallback(
  async (callbackId) => sendApprovalRequest(callbackId)
);
```

------
#### [ Python ]

```
# Wait for 1 hour without consuming resources
context.wait(3600)

# Wait for external callback
approval = context.wait_for_callback(
    lambda callback_id: send_approval_request(callback_id)
)
```

------

Lorsque votre fonction attend ou doit faire une pause, Lambda enregistre le journal des points de contrôle et arrête l'exécution. Au moment de reprendre, Lambda invoque à nouveau votre fonction et rejoue le journal des points de contrôle, en substituant des valeurs stockées aux opérations terminées.

Pour les flux de travail plus complexes, les fonctions Lambda durables sont également associées à des opérations avancées telles que `parallel()` l'exécution simultanée, le traitement `map()` de tableaux, les opérations imbriquées et `runInChildContext()` les interrogations. `waitForCondition()` [Reportez-vous](durable-examples.md) à la section Exemples pour obtenir des exemples détaillés et des conseils sur le moment d'utiliser chaque opération.

## Invocation d'autres fonctions
<a name="invoke-concept"></a>

**Invoke** permet à une fonction durable d'appeler d'autres fonctions Lambda et d'attendre leurs résultats. La fonction appelante est suspendue pendant que la fonction invoquée s'exécute, créant ainsi un point de contrôle qui préserve le résultat. Cela vous permet de créer des flux de travail modulaires dans lesquels des fonctions spécialisées gèrent des tâches spécifiques.

`context.invoke()`À utiliser pour appeler d'autres fonctions depuis votre fonction durable. L'invocation est un point de contrôle. Ainsi, si votre fonction est interrompue une fois la fonction invoquée terminée, elle reprend avec le résultat enregistré sans avoir à réinvoquer la fonction.

------
#### [ TypeScript ]

```
// Invoke another function and wait for result
const customerData = await context.invoke(
  'validate-customer',
  'arn:aws:lambda:us-east-1:123456789012:function:customer-service:1',
  { customerId: event.customerId }
);

// Use the result in subsequent steps
const order = await context.step(async () => {
  return processOrder(customerData);
});
```

------
#### [ Python ]

```
# Invoke another function and wait for result
customer_data = context.invoke(
    'arn:aws:lambda:us-east-1:123456789012:function:customer-service:1',
    {'customerId': event['customerId']},
    name='validate-customer'
)

# Use the result in subsequent steps
order = context.step(
    lambda: process_order(customer_data),
    name='process-order'
)
```

------

La fonction invoquée peut être une fonction Lambda durable ou standard. Si vous invoquez une fonction durable, la fonction appelante attend la fin de l'exécution durable complète. Ce modèle est courant dans les architectures de microservices où chaque fonction gère un domaine spécifique, ce qui vous permet de composer des flux de travail complexes à partir de fonctions spécialisées et réutilisables.

**Note**  
Les appels entre comptes ne sont pas pris en charge. La fonction invoquée doit se trouver dans le même AWS compte que la fonction appelante.

## Configuration fonctionnelle durable
<a name="durable-configuration-basic"></a>

Les fonctions durables ont des paramètres de configuration spécifiques qui contrôlent le comportement d'exécution et la conservation des données. Ces paramètres sont distincts de la configuration standard de la fonction Lambda et s'appliquent à l'ensemble du cycle de vie d'exécution durable.

L'**DurableConfig**objet définit la configuration des fonctions durables :

```
{
  "ExecutionTimeout": Integer,
  "RetentionPeriodInDays": Integer
}
```

### Execution timeout (Délai d'exécution)
<a name="durable-execution-timeout"></a>

Le **délai d'exécution** contrôle la durée pendant laquelle une exécution durable peut s'exécuter du début à la fin. Cela est différent du délai d'expiration de la fonction Lambda, qui contrôle la durée pendant laquelle une seule invocation de fonction peut être exécutée.

Une exécution durable peut s'étendre sur plusieurs invocations de fonctions Lambda au fur et à mesure qu'elle progresse entre les points de contrôle, les temps d'attente et les rediffusions. Le délai d'exécution s'applique au temps total écoulé pendant l'exécution durable, et non aux invocations de fonctions individuelles.

**Comprendre la différence**  
Le délai d'expiration de la fonction Lambda (maximum 15 minutes) limite chaque appel individuel de votre fonction. Le délai d'exécution durable (maximum 1 an) limite le temps total entre le début de l'exécution et sa fin, son échec ou son expiration. Au cours de cette période, votre fonction peut être invoquée plusieurs fois pendant qu'elle traite des étapes, attend et se rétablit après un échec.

Par exemple, si vous définissez un délai d'exécution durable de 24 heures et un délai d'expiration de la fonction Lambda de 5 minutes :
+ Chaque invocation de fonction doit être terminée dans les 5 minutes
+ L'ensemble de l'exécution durable peut durer jusqu'à 24 heures
+ Votre fonction peut être invoquée plusieurs fois pendant ces 24 heures
+ Les opérations d'attente ne sont pas prises en compte dans le délai d'expiration de la fonction Lambda, mais dans le délai d'exécution

Vous pouvez configurer le délai d'exécution lors de la création d'une fonction durable à l'aide de la console Lambda AWS CLI, ou. AWS SAM Dans la console Lambda, choisissez votre fonction, puis Configuration, Exécution durable. Définissez la valeur du délai d'exécution en secondes (par défaut : 86400 secondes/24 heures, minimum : 60 secondes, maximum : 31536000 secondes/1 an).

**Note**  
Le délai d'exécution et le délai d'expiration de la fonction Lambda sont des paramètres différents. La fonction Lambda timeout contrôle la durée pendant laquelle chaque appel individuel peut être exécuté (maximum 15 minutes). Le délai d'exécution contrôle le temps total écoulé pour l'ensemble de l'exécution durable (maximum 1 an).

### Période de conservation
<a name="durable-retention-period"></a>

La **période de conservation** contrôle la durée pendant laquelle Lambda conserve l'historique des exécutions et les données des points de contrôle après la fin d'une exécution durable. Ces données incluent les résultats des étapes, l'état d'exécution et le journal complet des points de contrôle.

Une fois la période de conservation expirée, Lambda supprime l'historique d'exécution et les données des points de contrôle. Vous ne pouvez plus récupérer les détails de l'exécution ni rejouer l'exécution. La période de rétention commence lorsque l'exécution atteint un état terminal (SUCCEDED, FAILED, STOPPED ou TIMED\$1OUT).

Vous pouvez configurer la période de rétention lors de la création d'une fonction durable à l'aide de la console Lambda AWS CLI, ou. AWS SAM Dans la console Lambda, choisissez votre fonction, puis Configuration, Exécution durable. Définissez la valeur de la période de conservation en jours (par défaut : 14 jours, minimum : 1 jour, maximum : 90 jours).

Choisissez une période de rétention en fonction de vos exigences de conformité, de vos besoins de débogage et de considérations financières. Des périodes de rétention plus longues permettent de consacrer plus de temps au débogage et à l'audit, mais augmentent les coûts de stockage.

## Consultez aussi
<a name="durable-basic-concepts-see-also"></a>
+ [Fonctions durables ou Step Functions](durable-step-functions.md) — Comparez les fonctions durables aux Step Functions pour savoir quand chaque approche est la plus efficace.

# Création de fonctions Lambda durables
<a name="durable-getting-started"></a>

Pour commencer à utiliser les fonctions durables Lambda, utilisez la console Lambda pour créer une fonction durable. En quelques minutes, vous pouvez créer et déployer une fonction durable qui utilise des étapes et des temps d'attente pour démontrer une exécution basée sur des points de contrôle.

Au cours de ce didacticiel, vous découvrirez les concepts fondamentaux des fonctions durables, tels que la façon d'utiliser l'`DurableContext`objet, de créer des points de contrôle avec des étapes et de suspendre l'exécution avec des temps d'attente. Vous découvrirez également comment fonctionne le replay lorsque votre fonction reprend après une attente.

Pour simplifier les choses, ce didacticiel explique comment créer votre fonction à l'aide de l'environnement d'exécution Python ou Node.js. Avec ces langages interprétés, vous pouvez modifier le code de fonction directement dans l'éditeur de code intégré à la console.

Les fonctions durables de Java (version préliminaire) ne peuvent actuellement être déployées que via des images de conteneur. Pour plus d'informations sur la création de fonctions durables à partir d'images de conteneurs, voir [Runtimes pris en charge pour les fonctions durables](durable-supported-runtimes.md) ou [Déployer des fonctions durables Lambda avec Infrastructure as Code](durable-getting-started-iac.md).

**Note**  
Les fonctions durables prennent actuellement en charge les environnements d'exécution Python et Node.js (JavaScript/TypeScript) et les images de conteneur (OCI), telles que Java. Pour obtenir la liste complète des versions d'exécution et des options d'image de conteneur prises en charge, voir [Runtimes pris en charge pour des fonctions durables.](durable-supported-runtimes.md) Pour plus d'informations sur l'utilisation d'images de conteneur avec Lambda, consultez la section Création d'images de [conteneur Lambda dans le guide du développeur](https://docs.aws.amazon.com/lambda/latest/dg/images-create.html) Lambda.

**Astuce**  
Pour apprendre à créer des **solutions sans serveur**, consultez le [Guide du développeur sans serveur](https://docs.aws.amazon.com/serverless/latest/devguide/).

## Conditions préalables
<a name="durable-getting-started-prerequisites"></a>

### Inscrivez-vous pour un Compte AWS
<a name="sign-up-for-aws"></a>

Si vous n'en avez pas Compte AWS, procédez comme suit pour en créer un.

**Pour vous inscrire à un Compte AWS**

1. Ouvrez l'[https://portal.aws.amazon.com/billing/inscription.](https://portal.aws.amazon.com/billing/signup)

1. Suivez les instructions en ligne.

   Dans le cadre de la procédure d’inscription, vous recevrez un appel téléphonique ou un SMS et vous saisirez un code de vérification en utilisant le clavier numérique du téléphone.

   Lorsque vous vous inscrivez à un Compte AWS, un *Utilisateur racine d'un compte AWS*est créé. Par défaut, seul l’utilisateur racine a accès à l’ensemble des Services AWS et des ressources de ce compte. La meilleure pratique de sécurité consiste à attribuer un accès administratif à un utilisateur, et à utiliser uniquement l’utilisateur racine pour effectuer les [tâches nécessitant un accès utilisateur racine](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#root-user-tasks).

AWS vous envoie un e-mail de confirmation une fois le processus d'inscription terminé. À tout moment, vous pouvez consulter l'activité actuelle de votre compte et gérer votre compte en accédant à [https://aws.amazon.com/](https://aws.amazon.com/)et en choisissant **Mon compte**.

### Création d’un utilisateur doté d’un accès administratif
<a name="create-an-admin"></a>

Une fois que vous vous êtes inscrit à un utilisateur administratif Compte AWS, que vous Utilisateur racine d'un compte AWS l'avez sécurisé AWS IAM Identity Center, que vous l'avez activé et que vous en avez créé un, afin de ne pas utiliser l'utilisateur root pour les tâches quotidiennes.

**Sécurisez votre Utilisateur racine d'un compte AWS**

1.  Connectez-vous en [AWS Management Console](https://console.aws.amazon.com/)tant que propriétaire du compte en choisissant **Utilisateur root** et en saisissant votre adresse Compte AWS e-mail. Sur la page suivante, saisissez votre mot de passe.

   Pour obtenir de l’aide pour vous connecter en utilisant l’utilisateur racine, consultez [Connexion en tant qu’utilisateur racine](https://docs.aws.amazon.com/signin/latest/userguide/console-sign-in-tutorials.html#introduction-to-root-user-sign-in-tutorial) dans le *Guide de l’utilisateur Connexion à AWS *.

1. Activez l’authentification multifactorielle (MFA) pour votre utilisateur racine.

   Pour obtenir des instructions, voir [Activer un périphérique MFA virtuel pour votre utilisateur Compte AWS root (console)](https://docs.aws.amazon.com/IAM/latest/UserGuide/enable-virt-mfa-for-root.html) dans le guide de l'utilisateur *IAM*.

**Création d’un utilisateur doté d’un accès administratif**

1. Activez IAM Identity Center.

   Pour obtenir des instructions, consultez [Activation d’ AWS IAM Identity Center](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-set-up-for-idc.html) dans le *Guide de l’utilisateur AWS IAM Identity Center *.

1. Dans IAM Identity Center, octroyez un accès administratif à un utilisateur.

   Pour un didacticiel sur l'utilisation du Répertoire IAM Identity Center comme source d'identité, voir [Configurer l'accès utilisateur par défaut Répertoire IAM Identity Center](https://docs.aws.amazon.com//singlesignon/latest/userguide/quick-start-default-idc.html) dans le *Guide de AWS IAM Identity Center l'utilisateur*.

**Connexion en tant qu’utilisateur doté d’un accès administratif**
+ Pour vous connecter avec votre utilisateur IAM Identity Center, utilisez l’URL de connexion qui a été envoyée à votre adresse e-mail lorsque vous avez créé l’utilisateur IAM Identity Center.

  Pour obtenir de l'aide pour vous connecter en utilisant un utilisateur d'IAM Identity Center, consultez la section [Connexion au portail AWS d'accès](https://docs.aws.amazon.com/signin/latest/userguide/iam-id-center-sign-in-tutorial.html) dans le *guide de l'Connexion à AWS utilisateur*.

**Attribution d’un accès à d’autres utilisateurs**

1. Dans IAM Identity Center, créez un ensemble d’autorisations qui respecte la bonne pratique consistant à appliquer les autorisations de moindre privilège.

   Pour obtenir des instructions, consultez [Création d’un ensemble d’autorisations](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-started-create-a-permission-set.html) dans le *Guide de l’utilisateur AWS IAM Identity Center *.

1. Attribuez des utilisateurs à un groupe, puis attribuez un accès par authentification unique au groupe.

   Pour obtenir des instructions, consultez [Ajout de groupes](https://docs.aws.amazon.com//singlesignon/latest/userguide/addgroups.html) dans le *Guide de l’utilisateur AWS IAM Identity Center *.

## Créez une fonction Lambda durable avec la console
<a name="getting-started-create-durable-function"></a>

Dans cet exemple, votre fonction durable traite une commande en plusieurs étapes avec un point de contrôle automatique. La fonction prend un objet JSON contenant un numéro de commande, valide la commande, traite le paiement et confirme la commande. Chaque étape est automatiquement contrôlée. Ainsi, si la fonction est interrompue, elle reprend à partir de la dernière étape terminée.

Votre fonction illustre également une opération d'attente, interrompant l'exécution pendant une courte période pour simuler l'attente d'une confirmation externe.

**Pour créer une fonction durable avec la console**

1. Ouvrez la [page Functions](https://console.aws.amazon.com/lambda/home#/functions) (Fonctions) de la console Lambda.

1. Choisissez **Créer une fonction**.

1. Sélectionnez **Créer à partir de zéro**.

1. Dans le volet **Informations de base**, pour **Nom de la fonction**, saisissez `myDurableFunction`.

1. Pour **Runtime**, choisissez **Node.js 24** ou **Python 3.14**.

1. Sélectionnez **Activer l'exécution durable**.

Lambda crée votre fonction durable avec un [rôle d'exécution](lambda-intro-execution-role.md) qui inclut des autorisations pour les opérations de point de contrôle (`lambda:CheckpointDurableExecutions`et). `lambda:GetDurableExecutionState`

**Note**  
Les environnements d'exécution Lambda incluent le SDK Durable Execution, qui vous permet de tester des fonctions durables sans créer de dépendances. Toutefois, nous vous recommandons d'inclure le SDK dans votre package de déploiement pour la production. Cela garantit la cohérence des versions et évite les mises à jour d'exécution potentielles susceptibles d'affecter votre fonction.

Utilisez l'éditeur de code intégré à la console pour ajouter votre code de fonction durable.

------
#### [ Node.js ]

**Pour modifier le code dans la console**

1. Cliquez sur l’onglet **Code**.

   Dans l'éditeur de code intégré de la console, vous devriez voir le code de fonction créé par Lambda. Si vous ne voyez pas l'onglet **index.mjs** dans l'éditeur de code, sélectionnez **index.mjs** dans l'explorateur de fichiers, comme le montre le schéma suivant.  
![\[\]](http://docs.aws.amazon.com/fr_fr/lambda/latest/dg/images/durable-nodejs.png)

1. Collez le code suivant dans l'onglet **index.mjs**, en remplaçant le code créé par Lambda.

   ```
   import {
     DurableContext,
     withDurableExecution,
   } from "@aws/durable-execution-sdk-js";
   
   export const handler = withDurableExecution(
     async (event, context) => {
       const orderId = event.orderId;
       
       // Step 1: Validate order
       const validationResult = await context.step(async (stepContext) => {
         stepContext.logger.info(`Validating order ${orderId}`);
         return { orderId, status: "validated" };
       });
       
       // Step 2: Process payment
       const paymentResult = await context.step(async (stepContext) => {
         stepContext.logger.info(`Processing payment for order ${orderId}`);
         return { orderId, status: "paid", amount: 99.99 };
       });
       
       // Wait for 10 seconds to simulate external confirmation
       await context.wait({ seconds: 10 });
       
       // Step 3: Confirm order
       const confirmationResult = await context.step(async (stepContext) => {
         stepContext.logger.info(`Confirming order ${orderId}`);
         return { orderId, status: "confirmed" };
       });
           
       return {
         orderId: orderId,
         status: "completed",
         steps: [validationResult, paymentResult, confirmationResult]
       };
     }
   );
   ```

1. Dans la section **DÉPLOYER**, choisissez **Déployer** pour mettre à jour le code de votre fonction :  
![\[\]](http://docs.aws.amazon.com/fr_fr/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

**Comprendre votre code de fonction durable**  
Avant de passer à l'étape suivante, examinons le code de la fonction et comprenons les principaux concepts relatifs aux fonctions durables.
+ L'`withDurableExecution`emballage :

  Votre fonction durable est emballée avec`withDurableExecution`. Ce wrapper permet une exécution durable en fournissant l'`DurableContext`objet et en gérant les opérations des points de contrôle.
+ L'`DurableContext`objet :

  Au lieu du contexte Lambda standard, votre fonction reçoit un. `DurableContext` Cet objet fournit des méthodes pour des opérations durables telles `wait()` que `step()` et qui créent des points de contrôle.
+ Étapes et points de contrôle :

  Chaque `context.step()` appel crée un point de contrôle avant et après l'exécution. Si votre fonction est interrompue, elle reprend à partir du dernier point de contrôle terminé. La fonction ne réexécute pas les étapes terminées. Il utilise plutôt leurs résultats enregistrés.
+ Opérations d'attente :

  L'`context.wait()`appel interrompt l'exécution sans consommer de ressources informatiques. Une fois l'attente terminée, Lambda appelle à nouveau votre fonction et rejoue le journal des points de contrôle, en substituant des valeurs stockées aux étapes terminées.
+ Mécanisme de rediffusion :

  Lorsque votre fonction reprend après une attente ou une interruption, Lambda exécute votre code depuis le début. Toutefois, les étapes terminées ne sont pas réexécutées. Lambda rejoue leurs résultats à partir du journal des points de contrôle. C'est pourquoi votre code doit être déterministe.

------
#### [ Python ]

**Pour modifier le code dans la console**

1. Cliquez sur l’onglet **Code**.

   Dans l'éditeur de code intégré de la console, vous devriez voir le code de fonction créé par Lambda. Si vous ne voyez pas l'onglet **lambda\$1function.py** dans l'éditeur de code, sélectionnez **lambda\$1function.py** dans l'explorateur de fichiers, comme le montre le schéma suivant.  
![\[\]](http://docs.aws.amazon.com/fr_fr/lambda/latest/dg/images/durable-python.png)

1. Collez le code suivant dans l'onglet **lambda\$1function.py**, en remplaçant le code créé par Lambda.

   ```
   from aws_durable_execution_sdk_python import (
       DurableContext,
       durable_execution,
       durable_step,
   )
   from aws_durable_execution_sdk_python.config import Duration
   
   @durable_step
   def validate_order(step_context, order_id):
       step_context.logger.info(f"Validating order {order_id}")
       return {"orderId": order_id, "status": "validated"}
   
   @durable_step
   def process_payment(step_context, order_id):
       step_context.logger.info(f"Processing payment for order {order_id}")
       return {"orderId": order_id, "status": "paid", "amount": 99.99}
   
   @durable_step
   def confirm_order(step_context, order_id):
       step_context.logger.info(f"Confirming order {order_id}")
       return {"orderId": order_id, "status": "confirmed"}
   
   @durable_execution
   def lambda_handler(event, context: DurableContext):
       order_id = event['orderId']
       
       # Step 1: Validate order
       validation_result = context.step(validate_order(order_id))
       
       # Step 2: Process payment
       payment_result = context.step(process_payment(order_id))
       
       # Wait for 10 seconds to simulate external confirmation
       context.wait(Duration.from_seconds(10))
       
       # Step 3: Confirm order
       confirmation_result = context.step(confirm_order(order_id))
           
       return {
           "orderId": order_id,
           "status": "completed",
           "steps": [validation_result, payment_result, confirmation_result]
       }
   ```

1. Dans la section **DÉPLOYER**, choisissez **Déployer** pour mettre à jour le code de votre fonction :  
![\[\]](http://docs.aws.amazon.com/fr_fr/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

**Comprendre votre code de fonction durable**  
Avant de passer à l'étape suivante, examinons le code de la fonction et comprenons les principaux concepts relatifs aux fonctions durables.
+ Le `@durable_execution` décorateur :

  Votre fonction de gestion est décorée avec`@durable_execution`. Ce décorateur permet une exécution durable en fournissant l'`DurableContext`objet et en gérant les opérations aux points de contrôle.
+ Le `@durable_step` décorateur :

  Chaque fonction de marche est décorée avec`@durable_step`. Ce décorateur définit la fonction comme une étape durable qui crée des points de contrôle.
+ L'`DurableContext`objet :

  Au lieu du contexte Lambda standard, votre fonction reçoit un. `DurableContext` Cet objet fournit des méthodes pour des opérations durables telles `wait()` que `step()` et qui créent des points de contrôle.
+ Étapes et points de contrôle :

  Chaque `context.step()` appel crée un point de contrôle avant et après l'exécution. Si votre fonction est interrompue, elle reprend à partir du dernier point de contrôle terminé. La fonction ne réexécute pas les étapes terminées. Il utilise plutôt leurs résultats enregistrés.
+ Opérations d'attente :

  L'`context.wait()`appel interrompt l'exécution sans consommer de ressources informatiques. Une fois l'attente terminée, Lambda appelle à nouveau votre fonction et rejoue le journal des points de contrôle, en substituant des valeurs stockées aux étapes terminées.
+ Le SDK Python est synchrone :

  Notez que le SDK Python n'utilise `await` pas. Toutes les opérations durables sont des appels de méthode synchrones.

------

## Appelez la fonction durable à l'aide de l'éditeur de code de la console
<a name="get-started-invoke-durable-manually"></a>

Lorsqu'aucune version explicite n'est spécifiée (ou publiée), la console invoque la fonction durable à l'aide du qualificatif de `$LATEST` version. Toutefois, pour une exécution déterministe de votre code, vous devez toujours utiliser un ARN qualifié pointant vers une version stable.

**Pour publier une version de votre fonction**

1. Choisissez l'onglet **Versions**.

1. Choisissez **Publish new version (Publier une nouvelle version)**.

1. Dans le **champ Description de la version**, entrez **Initial version** (facultatif).

1. Choisissez **Publier**.

1. Lambda crée la version 1 de votre fonction. Notez que la fonction ARN inclut désormais `:1` à la fin, ce qui indique qu'il s'agit de la version 1.

Créez maintenant un événement de test à envoyer à votre fonction. L'événement est un document au format JSON contenant un numéro de commande.

**Pour créer l'événement de test**

1. Dans la section **ÉVÉNEMENTS DE TEST** de l’éditeur de code de console, choisissez **Créer un événement de test**.  
![\[\]](http://docs.aws.amazon.com/fr_fr/lambda/latest/dg/images/getting-started-tutorial/test-event.png)

1. Dans **Event Name (Nom de l'événement)**, saisissez **myTestEvent**.

1. Dans la section **JSON d’événement**, remplacez le JSON par défaut par ce qui suit :

   ```
   {
     "orderId": "order-12345"
   }
   ```

1. Choisissez **Enregistrer**.

**Pour tester votre fonctionnalité durable et voir son exécution**

Dans la section **ÉVÉNEMENTS DE TEST** de l’éditeur de code de la console, cliquez sur l’icône d’exécution à côté de votre événement de test :

![\[\]](http://docs.aws.amazon.com/fr_fr/lambda/latest/dg/images/getting-started-tutorial/run-test-event.png)


Votre fonction durable commence à s'exécuter. Comme il inclut une attente de 10 secondes, l'appel initial se termine rapidement et la fonction reprend après la période d'attente. Vous pouvez consulter la progression de l'exécution dans l'onglet **Exécutions durables**.

**Pour visualiser l'exécution durable de vos fonctions**

1. Choisissez l'onglet **Exécutions durables**.

1. Trouvez votre exécution dans la liste. L'exécution indique l'état actuel (en cours, réussi ou échec).

1. Choisissez l'ID d'exécution pour afficher les détails, notamment :
   + Chronologie d'exécution indiquant la fin de chaque étape
   + Historique des points de contrôle
   + Périodes d'attente
   + Résultats des étapes

Vous pouvez également consulter les journaux de votre fonction dans CloudWatch Logs pour voir le résultat de chaque étape de la console.

**Pour consulter les enregistrements d'invocation de votre fonction dans Logs CloudWatch**

1. Ouvrez la page [Groupes de journaux](https://console.aws.amazon.com/cloudwatch/home#logs:) de la CloudWatch console.

1. Choisissez le groupe de journaux de votre fonction (`/aws/lambda/myDurableFunction`).

1. Faites défiler la page vers le bas et choisissez le **flux de journaux** pour les invocations de fonctions que vous souhaitez consulter.  
![\[\]](http://docs.aws.amazon.com/fr_fr/lambda/latest/dg/images/log-stream.png)

   Vous devriez voir des entrées de journal pour chaque appel de votre fonction, y compris l'exécution initiale et la rediffusion après l'attente.

**Note**  
Lorsque vous utilisez l'enregistreur depuis `DurableContext` (tel que `context.logger` ou`stepContext.logger`), les journaux apparaissent également dans les vues d'exécution durable et d'étape de la console Lambda. Le chargement de ces journaux peut prendre un certain temps.

## Nettoyage
<a name="gettingstarted-durable-cleanup"></a>

Lorsque vous avez fini d'utiliser l'exemple de fonction durable, supprimez-le. Vous pouvez également supprimer le groupe de journaux qui stocke les journaux de la fonction, et le [rôle d'exécution](lambda-intro-execution-role.md) créé par la console.

**Pour supprimer la fonction Lambda**

1. Ouvrez la [page Functions (Fonctions)](https://console.aws.amazon.com/lambda/home#/functions) de la console Lambda.

1. Sélectionnez la fonction que vous avez créée.

1. Sélectionnez **Actions**, **Supprimer**.

1. Saisissez **confirm** dans la zone de saisie de texte et choisissez **Delete** (Supprimer).

**Pour supprimer le groupe de journaux**

1. Ouvrez la [page Log groups (Groupes de journaux)](https://console.aws.amazon.com/cloudwatch/home#logs:) de la console CloudWatch.

1. Sélectionnez le groupe de journaux de la fonction (`/aws/lambda/myDurableFunction`).

1. Sélectionnez **Actions**, **Delete log group(s) (Supprimer le ou les groupes de journaux)**.

1. Dans la boîte de dialogue **Delete log group(s) (Supprimer le ou les groupes de journaux)**, sélectionnez **Delete (Supprimer)**.

**Pour supprimer le rôle d'exécution**

1. Ouvrez la [page Rôles](https://console.aws.amazon.com/iam/home?#/roles) de la console Gestion des identités et des accès AWS (IAM).

1. Sélectionnez le rôle d'exécution de la fonction (par exemple, `myDurableFunction-role-31exxmpl`).

1. Sélectionnez **Delete (Supprimer)**.

1. Dans la fenêtre de dialogue **Supprimer le rôle**, saisissez le nom du rôle, puis sélectionnez **Supprimer**.

## Ressources supplémentaires et prochaines étapes
<a name="durable-getting-started-more-resources"></a>

Maintenant que vous avez créé et testé une fonction simple et durable à l'aide de la console, procédez comme suit :
+ Découvrez les cas d'utilisation courants des fonctions durables, notamment les transactions distribuées, le traitement des commandes et les flux de travail de révision humaine. Voir les [exemples](durable-examples.md).
+ Découvrez comment surveiller les exécutions de fonctions durables à l'aide de CloudWatch métriques et d'un historique d'exécution. Consultez [la section Surveillance et débogage](durable-monitoring.md).
+ Découvrez comment invoquer des fonctions durables de manière synchrone et asynchrone, et comment gérer les exécutions de longue durée. Voir [Invocation de fonctions durables.](durable-invoking.md)
+ Suivez les meilleures pratiques en matière de rédaction de code déterministe, de gestion de la taille des points de contrôle et d'optimisation des coûts. Consultez la section [Bonnes pratiques](durable-best-practices.md).
+ Découvrez comment tester des fonctions durables localement et dans le cloud. Voir [Tester des fonctions durables](durable-testing.md).
+ Comparez les fonctions durables aux Step Functions pour savoir quand chaque approche est la plus efficace. Voir [Durable functions ou Step Functions](durable-step-functions.md).

# Déployez et invoquez des fonctions durables Lambda avec AWS CLI
<a name="durable-getting-started-cli"></a>

Utilisez le AWS CLI pour créer et déployer des fonctions Lambda durables avec des commandes impératives. Cette approche vous permet de contrôler directement chaque étape du processus de déploiement.

## Conditions préalables
<a name="durable-cli-prerequisites"></a>
+ Installez et configurez l’ AWS CLI. Pour obtenir des instructions, reportez-vous à la section [Installation du AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).
+ Créez un package de déploiement avec votre code de fonction et le SDK d'exécution durable.
+ Créez un rôle d'exécution IAM avec des autorisations de point de contrôle.

## Créer le rôle d’exécution
<a name="durable-cli-create-role"></a>

Créez un rôle IAM avec des autorisations pour l'exécution Lambda de base et les opérations de point de contrôle.

**Pour créer le rôle d'exécution**

1. Créez un document de politique de confiance qui permet à Lambda d'assumer le rôle. Enregistrez ceci sous le nom `trust-policy.json` :

   ```
   {
     "Version": "2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "lambda.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

1. Créez le rôle :

   ```
   aws iam create-role \
     --role-name durable-function-role \
     --assume-role-policy-document file://trust-policy.json
   ```

1. Joignez la politique d'exécution durable pour les opérations de point de contrôle et l'exécution de base :

   ```
   aws iam attach-role-policy \
     --role-name durable-function-role \
     --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicDurableExecutionRolePolicy
   ```

La politique `AWSLambdaBasicDurableExecutionRolePolicy` gérée inclut les autorisations requises pour les opérations de point de contrôle (`lambda:CheckpointDurableExecutions`et`lambda:GetDurableExecutionState`) et l'exécution de base de Lambda.

## Créez une fonction durable
<a name="durable-cli-create-function"></a>

Créez votre fonction durable avec le `--durable-config` paramètre.

**Pour créer une fonction durable**

1. Package de votre code de fonction avec les dépendances dans un fichier .zip :

   ```
   zip -r function.zip index.mjs node_modules/
   ```

1. Créez la fonction avec l'exécution durable activée :

   ```
   aws lambda create-function \
     --function-name myDurableFunction \
     --runtime nodejs22.x \
     --role arn:aws:iam::123456789012:role/durable-function-role \
     --handler index.handler \
     --zip-file fileb://function.zip \
     --durable-config '{"ExecutionTimeout": 3600, "RetentionPeriodInDays": 7}'
   ```

**Note**  
Vous ne pouvez activer l'exécution durable que lors de la création de la fonction. Vous ne pouvez pas l'activer sur les fonctions existantes.

**Note**  
Actuellement, les fonctions durables en Java (Preview) ne peuvent actuellement être créées que via des images de conteneur. Pour plus d'informations sur la création de fonctions durables à partir d'images de conteneurs, voir [Runtimes pris en charge pour les fonctions durables.](durable-supported-runtimes.md)

## Publier une version
<a name="durable-cli-publish-version"></a>

Bien que les fonctions durables puissent être invoquées à l'aide du qualificatif de `$LATEST` version, vous devez toujours utiliser un ARN qualifié pointant vers une version stable pour garantir une exécution déterministe de votre code.

```
aws lambda publish-version \
  --function-name myDurableFunction \
  --description "Initial version"
```

La commande renvoie l'ARN de la version. Notez le numéro de version (par exemple,`:1`) à la fin de l'ARN.

Vous pouvez éventuellement créer un alias pointant vers la version :

```
aws lambda create-alias \
  --function-name myDurableFunction \
  --name prod \
  --function-version 1
```

## Invoquez la fonction durable
<a name="durable-cli-invoke"></a>

Appelez votre fonction durable à l'aide de l'ARN qualifié (version ou alias).

**Note**  
**Invocations idempotentes :** pour éviter les doubles exécutions lors de nouvelles tentatives d'invocation infructueuses, vous pouvez fournir un nom d'exécution garantissant la sémantique d'exécution. at-most-once Voir [Idempotency](durable-execution-idempotency.md) pour plus de détails.

**Invocation synchrone**  
Pour les exécutions qui se terminent en 15 minutes, utilisez l'invocation synchrone :

```
aws lambda invoke \
  --function-name myDurableFunction:1 \
  --payload '{"orderId": "order-12345"}' \
  --cli-binary-format raw-in-base64-out \
  response.json
```

Ou en utilisant un alias :

```
aws lambda invoke \
  --function-name myDurableFunction:prod \
  --payload '{"orderId": "order-12345"}' \
  --cli-binary-format raw-in-base64-out \
  response.json
```

**invocation asynchrone**  
Pour les exécutions de longue durée, utilisez l'invocation asynchrone :

```
aws lambda invoke \
  --function-name myDurableFunction:prod \
  --invocation-type Event \
  --payload '{"orderId": "order-12345"}' \
  --cli-binary-format raw-in-base64-out \
  response.json
```

En cas d'invocation asynchrone, Lambda revient immédiatement. La fonction continue de s'exécuter en arrière-plan.

**Note**  
Vous pouvez l'utiliser `$LATEST` pour le prototypage et les tests dans la console. Pour les charges de travail de production, utilisez une version publiée ou un alias.

## Gérez des exécutions durables
<a name="durable-cli-manage-executions"></a>

Utilisez les commandes suivantes pour gérer et surveiller les exécutions de fonctions durables.

**Lister les exécutions**  
Répertoriez toutes les exécutions d'une fonction durable :

```
aws lambda list-durable-executions-by-function \
  --function-name myDurableFunction
```

**Obtenir les détails de l'exécution**  
Obtenez des informations sur une exécution spécifique :

```
aws lambda get-durable-execution \
  --durable-execution-arn arn:aws:lambda:us-east-1:123456789012:function:myDurableFunction:my-function-version/durable-execution/my-execution-name/my-execution-id
```

**Obtenir l'historique des exécutions**  
Consultez l'historique des points de contrôle d'une exécution :

```
aws lambda get-durable-execution-history \
  --durable-execution-arn arn:aws:lambda:us-east-1:123456789012:function:myDurableFunction:my-function-version/durable-execution/my-execution-name/my-execution-id
```

**Arrêter une exécution**  
Arrêtez une exécution durable en cours :

```
aws lambda stop-durable-execution \
  --durable-execution-arn arn:aws:lambda:us-east-1:123456789012:function:myDurableFunction:my-function-version/durable-execution/my-execution-name/my-execution-id
```

## Mettre à jour le code de la fonction
<a name="durable-cli-update-function"></a>

Mettez à jour votre code de fonction durable et publiez une nouvelle version :

**Pour mettre à jour et publier une nouvelle version**

1. Mettez à jour le code de fonction :

   ```
   aws lambda update-function-code \
     --function-name myDurableFunction \
     --zip-file fileb://function.zip
   ```

1. Attendez que la mise à jour soit terminée :

   ```
   aws lambda wait function-updated \
     --function-name myDurableFunction
   ```

1. Publiez une nouvelle version :

   ```
   aws lambda publish-version \
     --function-name myDurableFunction \
     --description "Updated order processing logic"
   ```

1. Mettez à jour l'alias pour qu'il pointe vers la nouvelle version :

   ```
   aws lambda update-alias \
     --function-name myDurableFunction \
     --name prod \
     --function-version 2
   ```

**Important**  
Les exécutions en cours continuent à utiliser la version avec laquelle elles ont débuté. Les nouvelles invocations utilisent la version mise à jour de l'alias.

## Affichage des journaux de fonctions
<a name="durable-cli-view-logs"></a>

Consultez les journaux de votre fonction durable dans CloudWatch Logs :

```
aws logs tail /aws/lambda/myDurableFunction --follow
```

Filtrez les journaux pour une exécution spécifique :

```
aws logs filter-log-events \
  --log-group-name /aws/lambda/myDurableFunction \
  --filter-pattern "exec-abc123"
```

## nettoyer des ressources ;
<a name="durable-cli-cleanup"></a>

Supprimez votre fonction durable et les ressources associées :

```
# Delete the function
aws lambda delete-function --function-name myDurableFunction

# Delete the IAM role policies
aws iam detach-role-policy \
  --role-name durable-function-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

aws iam detach-role-policy \
  --role-name durable-function-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicDurableExecutionRolePolicy

# Delete the role
aws iam delete-role --role-name durable-function-role
```

## Étapes suivantes
<a name="durable-cli-next-steps"></a>

Après avoir déployé votre fonction durable avec AWS CLI :
+ Surveillez les exécutions à l'aide `list-durable-executions` des `get-durable-execution` commandes et
+ Afficher les opérations des points de contrôle dans les événements de AWS CloudTrail données
+ Configurez des CloudWatch alarmes en cas d'échec d'exécution ou d'exécutions de longue durée
+ Automatisez les déploiements à l'aide de scripts shell ou CI/CD de pipelines

Pour plus d'informations sur AWS CLI les commandes pour Lambda, consultez la référence des [AWS CLI commandes](https://docs.aws.amazon.com/cli/latest/reference/lambda/index.html).

# Déployez des fonctions durables Lambda avec l'infrastructure en tant que code
<a name="durable-getting-started-iac"></a>

Vous pouvez déployer des fonctions durables Lambda à l'aide d'outils d'infrastructure en tant que code (IaC) tels que AWS CloudFormation, AWS CDK AWS Serverless Application Model, ou Terraform. Ces outils vous permettent de définir votre fonction, votre rôle d'exécution et vos autorisations dans le code, ce qui rend les déploiements reproductibles et contrôlés par version.

Les trois outils vous obligent à :
+ Permettre une exécution durable de la fonction
+ Accorder des autorisations de point de contrôle au rôle d'exécution
+ Publier une version ou créer un alias (les fonctions durables nécessitent une qualification ARNs)

## Fonctionnalités durables grâce à une fermeture éclair
<a name="durable-iac-zip"></a>

### AWS CloudFormation
<a name="durable-iac-cloudformation"></a>

 CloudFormation À utiliser pour définir votre fonction durable dans un modèle. L'exemple suivant crée une fonction durable dotée des autorisations requises.

```
AWSTemplateFormatVersion: '2010-09-09'
Description: Lambda durable function example

Resources:
  DurableFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'		 	 	 
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicDurableExecutionRolePolicy

  DurableFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: myDurableFunction
      Runtime: nodejs22.x
      Handler: index.handler
      Role: !GetAtt DurableFunctionRole.Arn
      Code:
        ZipFile: |
          // Your durable function code here
          export const handler = async (event, context) => {
            return { statusCode: 200 };
          };
      DurableConfig:
        ExecutionTimeout: 3600
        RetentionPeriodInDays: 7

  DurableFunctionVersion:
    Type: AWS::Lambda::Version
    Properties:
      FunctionName: !Ref DurableFunction
      Description: Initial version

  DurableFunctionAlias:
    Type: AWS::Lambda::Alias
    Properties:
      FunctionName: !Ref DurableFunction
      FunctionVersion: !GetAtt DurableFunctionVersion.Version
      Name: prod

Outputs:
  FunctionArn:
    Description: Durable function ARN
    Value: !GetAtt DurableFunction.Arn
  AliasArn:
    Description: Function alias ARN (use this for invocations)
    Value: !Ref DurableFunctionAlias
```

**Pour déployer le modèle**

```
aws cloudformation deploy \
  --template-file template.yaml \
  --stack-name my-durable-function-stack \
  --capabilities CAPABILITY_IAM
```

### AWS CDK
<a name="durable-iac-cdk"></a>

AWS CDK vous permet de définir l'infrastructure à l'aide de langages de programmation. Les exemples suivants montrent comment créer une fonction durable à l'aide TypeScript de Python.

------
#### [ TypeScript ]

```
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';

export class DurableFunctionStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Create the durable function
    const durableFunction = new lambda.Function(this, 'DurableFunction', {
      runtime: lambda.Runtime.NODEJS_22_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('lambda'),
      functionName: 'myDurableFunction',
      durableConfig: { executionTimeout: Duration.hours(1), retentionPeriod: Duration.days(30) },
    });

    // Create version and alias
    const version = durableFunction.currentVersion;
    const alias = new lambda.Alias(this, 'ProdAlias', {
      aliasName: 'prod',
      version: version,
    });

    // Output the alias ARN
    new cdk.CfnOutput(this, 'FunctionAliasArn', {
      value: alias.functionArn,
      description: 'Use this ARN to invoke the durable function',
    });
  }
}
```

------
#### [ Python ]

```
from aws_cdk import (
    Stack,
    aws_lambda as lambda_,
    aws_iam as iam,
    CfnOutput,
)
from constructs import Construct

class DurableFunctionStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        # Create the durable function
        durable_function = lambda_.Function(
            self, 'DurableFunction',
            runtime=lambda_.Runtime.NODEJS_22_X,
            handler='index.handler',
            code=lambda_.Code.from_asset('lambda'),
            function_name='myDurableFunction',
            durable_execution={execution_timeout: Duration.hours(1), retention_period: Duration.days(30)}
        )

        # Add durable execution managed policy for checkpoint permissions
        durable_function.role.add_managed_policy(
            iam.ManagedPolicy.from_aws_managed_policy_name('service-role/AWSLambdaBasicDurableExecutionRolePolicy')
        )

        # Create version and alias
        version = durable_function.current_version
        alias = lambda_.Alias(
            self, 'ProdAlias',
            alias_name='prod',
            version=version
        )

        # Output the alias ARN
        CfnOutput(
            self, 'FunctionAliasArn',
            value=alias.function_arn,
            description='Use this ARN to invoke the durable function'
        )
```

------

**Pour déployer la pile CDK**

```
cdk deploy
```

### AWS Serverless Application Model
<a name="durable-iac-sam"></a>

AWS SAM simplifie les CloudFormation modèles pour les applications sans serveur. Le modèle suivant crée une fonction durable avec AWS SAM.

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Lambda durable function with SAM

Resources:
  DurableFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: myDurableFunction
      Runtime: nodejs22.x
      Handler: index.handler
      CodeUri: ./src
      DurableConfig:
        ExecutionTimeout: 3600
        RetentionPeriodInDays: 7
      Policies:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicDurableExecutionRolePolicy
      AutoPublishAlias: prod

Outputs:
  FunctionArn:
    Description: Durable function ARN
    Value: !GetAtt DurableFunction.Arn
  AliasArn:
    Description: Function alias ARN (use this for invocations)
    Value: !Ref DurableFunction.Alias
```

**Pour déployer le modèle SAM**

```
sam build
sam deploy --guided
```

### Terraform
<a name="durable-iac-terraform"></a>

Terraform est un outil IaC open source populaire qui prend en charge les ressources. AWS L'exemple suivant crée une fonction durable avec Terraform à l'aide du AWS fournisseur version 6.25.0 ou ultérieure.

```
terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 6.25.0"
    }
  }
}

provider "aws" {
  region = "us-east-2"
}

# IAM Role for Lambda Function
resource "aws_iam_role" "lambda_role" {
  name = "durable-function-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "lambda.amazonaws.com"
      }
    }]
  })
}

# Attach durable execution policy for checkpoint operations
resource "aws_iam_role_policy_attachment" "lambda_durable" {
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicDurableExecutionRolePolicy"
  role       = aws_iam_role.lambda_role.name
}

# Lambda Function with Durable Execution enabled
resource "aws_lambda_function" "durable_function" {
  filename      = "function.zip"
  function_name = "myDurableFunction"
  role          = aws_iam_role.lambda_role.arn
  handler       = "index.handler"
  runtime       = "nodejs22.x"
  timeout       = 30
  memory_size   = 512

  durable_config {
    execution_timeout = 900
    retention_period  = 7
  }
}

# Publish a version
resource "aws_lambda_alias" "prod" {
  name             = "prod"
  function_name    = aws_lambda_function.durable_function.function_name
  function_version = aws_lambda_function.durable_function.version
}

output "function_arn" {
  description = "ARN of the Lambda function"
  value       = aws_lambda_function.durable_function.arn
}

output "alias_arn" {
  description = "ARN of the function alias (use this for invocations)"
  value       = aws_lambda_alias.prod.arn
}
```

**Pour déployer avec Terraform**

```
terraform init
terraform plan
terraform apply
```

**Note**  
La prise en charge par Terraform des fonctions durables Lambda nécessite la version 6.25.0 ou ultérieure du AWS fournisseur. Mettez à jour la version de votre fournisseur si vous utilisez une ancienne version.

## Fonctions durables à partir d'une image de conteneur OCI
<a name="durable-iac-oci"></a>

Vous pouvez également créer des fonctions durables à partir d'images de conteneurs. Pour obtenir des instructions sur la création d'une image de conteneur, voir [Runtimes pris en charge pour des fonctions durables.](durable-supported-runtimes.md)

### AWS CDK
<a name="durable-iac-oci-cdk"></a>

AWS CDK vous permet de définir l'infrastructure à l'aide de langages de programmation. Les exemples suivants montrent comment créer une fonction durable à TypeScript partir d'une image de conteneur.

```
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';

export class DurableFunctionStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Create the durable function
    const durableFunction = new lambda.DockerImageFunction(this, 'DurableFunction', {
      code: lambda.DockerImageCode.fromImageAsset('./lambda', {
        platform: cdk.aws_ecr_assets.Platform.LINUX_AMD64,
      }),
      functionName: 'myDurableFunction',
      memorySize: 512,
      timeout: cdk.Duration.seconds(30),
      durableConfig: { executionTimeout: cdk.Duration.hours(1), retentionPeriod: cdk.Duration.days(30) },
    });

    // Create version and alias
    const version = durableFunction.currentVersion;
    const alias = new lambda.Alias(this, 'ProdAlias', {
      aliasName: 'prod',
      version: version,
    });

    // Output the alias ARN
    new cdk.CfnOutput(this, 'FunctionAliasArn', {
      value: alias.functionArn,
      description: 'Use this ARN to invoke the durable function',
    });
  }
}
```

**Pour déployer la pile CDK**

```
cdk deploy
```

### AWS Serverless Application Model
<a name="durable-iac-oci-sam"></a>

AWS SAM simplifie les CloudFormation modèles pour les applications sans serveur. Le modèle suivant crée une fonction durable avec AWS SAM.

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Lambda durable function with SAM

Resources:
  DurableFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: myDurableFunction
      PackageType: Image
      ImageUri: ./src
      DurableConfig:
        ExecutionTimeout: 3600
        RetentionPeriodInDays: 7
      Policies:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicDurableExecutionRolePolicy
      AutoPublishAlias: prod
    Metadata:
      DockerTag: latest
      DockerContext: ./src
      Dockerfile: Dockerfile

Outputs:
  FunctionArn:
    Description: Durable function ARN
    Value: !GetAtt DurableFunction.Arn
  AliasArn:
    Description: Function alias ARN (use this for invocations)
    Value: !Ref DurableFunction.Alias
```

**Pour déployer le modèle SAM**

```
sam build
sam deploy --guided
```

## Modèles de configuration courants
<a name="durable-iac-common-patterns"></a>

Quel que soit l'outil IaC que vous utilisez, suivez les modèles suivants pour des fonctions durables :

**Permettre une exécution durable**  
Définissez la `DurableConfig` propriété de votre fonction pour permettre une exécution durable. Cette propriété n'est disponible que lors de la création de la fonction. Vous ne pouvez pas activer l'exécution durable sur des fonctions existantes.

**Accorder des autorisations aux points de contrôle**  
Associez la politique `AWSLambdaBasicDurableExecutionRolePolicy` gérée au rôle d'exécution. Cette politique inclut les `lambda:GetDurableExecutionState` autorisations `lambda:CheckpointDurableExecutions` et les autorisations requises.

**Utiliser qualifié ARNs**  
Créez une version ou un alias pour votre fonction. Les fonctions durables nécessitent une qualification ARNs (avec version ou alias) pour être invoquées. Utilisez `AutoPublishAlias` AWS SAM ou créez des versions explicites dans CloudFormation AWS CDK, et Terraform.

**Dépendances de package**  
Incluez le SDK d'exécution durable dans votre package de déploiement. Pour Node.js, installez`@aws/durable-execution-sdk-js`. Pour Python, installez`aws-durable-execution-sdk-python`.

## Étapes suivantes
<a name="durable-iac-next-steps"></a>

Après avoir déployé votre fonction durable :
+ Testez votre fonction à l'aide de l'ARN qualifié (version ou alias)
+ Surveillez la progression de l'exécution dans la console Lambda sous l'onglet Exécutions durables
+ Afficher les opérations des points de contrôle dans les événements de AWS CloudTrail données
+ Consultez CloudWatch les journaux pour connaître le comportement des fonctions, des sorties et des rediffusions

Pour plus d'informations sur le déploiement de fonctions Lambda avec les outils IaC, voir :
+ [CloudFormation AWS::Lambda::Function référence](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
+ [AWS CDK Documentation du module Lambda](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html)
+ [AWS SAM Manuel du développeur](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)

# Fonctions durables ou Step Functions
<a name="durable-step-functions"></a>

Lambda est à la fois durable et AWS Step Functions permet une orchestration fiable des flux de travail avec gestion automatique des états et reprise en cas de panne. Ils répondent aux préférences des développeurs et à des modèles architecturaux différents. Les fonctions durables sont optimisées pour le développement d'applications dans Lambda, tandis que Step Functions est conçu pour l'orchestration des flux de travail entre les services. AWS 

## Quand utiliser des fonctions durables
<a name="durable-sfn-when-durable"></a>

Utilisez des fonctions durables lorsque :
+ Votre équipe préfère les langages de programmation standard et les outils de développement familiers
+ La logique de votre application réside principalement dans les fonctions Lambda
+ Vous voulez un contrôle précis de l'état d'exécution du code
+ Vous créez des applications centrées sur Lambda avec un lien étroit entre le flux de travail et la logique métier
+ Vous souhaitez itérer rapidement sans passer du code aux concepteurs visual/JSON 

## Quand utiliser Step Functions
<a name="durable-sfn-when-step"></a>

Utilisez Step Functions lorsque :
+ Vous avez besoin d'une représentation visuelle du flux de travail pour une visibilité entre les équipes
+ Vous orchestrez plusieurs AWS services et souhaitez des intégrations natives sans code SDK personnalisé
+ Vous avez besoin d'une infrastructure ne nécessitant aucune maintenance (pas de correctifs, de mises à jour d'exécution)
+ Les parties prenantes non techniques doivent comprendre et valider la logique du flux de travail

## Cadre décisionnel
<a name="durable-sfn-decision-framework"></a>

Posez-vous les questions suivantes pour déterminer quel service correspond à votre cas d'utilisation :
+ **Quel est votre objectif principal ?** Développement d'applications dans Lambda → fonctions durables. Orchestration du flux de travail dans AWS → Step Functions.
+ **Quel est votre modèle de programmation préféré ?** Langages de programmation standard → fonctions durables. DSL ou concepteur visuel basé sur des graphiques → Step Functions.
+ **Combien de AWS services sont concernés ?** Lambda → fonctions durables principalement. AWS Services multiples → Step Functions.
+ **Quels outils de développement utilisez-vous ?** Expérience de développeur Lambda, IDE avec agent LLM, frameworks de tests unitaires spécifiques au langage de programmation,, AWS SAM AWS CDK, AWS Toolkit → fonctions durables. Générateur de flux de travail visuel, AWS CDK pour modéliser les flux de travail → Step Functions.
+ **Qui gère l'infrastructure ?** Vous recherchez de la flexibilité au sein de Lambda → des fonctions durables. Vous voulez une gestion complète, sans maintenance → Step Functions.

## Comparaison des fonctionnalités
<a name="durable-sfn-comparison"></a>

Le tableau suivant compare les principales fonctionnalités entre Step Functions et les fonctions durables Lambda :


| Fonctionnalité | AWS Step Functions | Fonctions durables Lambda | 
| --- | --- | --- | 
| Objectif principal | Orchestration du flux de travail à travers AWS | Développement d'applications dans Lambda | 
| Type de service | Service de flux de travail autonome et dédié | Fonctionne dans Lambda | 
| Modèle de programmation | Basé sur des graphiques, Amazon States Language DSL ou AWS CDK | Langages de programmation standard (JavaScript/TypeScript, Python) | 
| Outils de développement | Générateur visuel dans l'extension IDE AWS Console/Toolkit, AWS CDK | Lambda DX dans les agents IDE et LLM, les frameworks de tests unitaires, l'extension IDE du Toolkit AWS SAM AWS  | 
| Intégrations | Plus de 220 AWS services, 16 000 APIs | Extension du modèle de programmation piloté par les événements Lambda (sources d'événements) | 
| Gestion | Entièrement géré, indépendant du temps d'exécution, aucune maintenance (pas de correctifs, de mises à jour d'exécution) | Géré dans l'environnement Lambda | 
| Idéal pour | Automatisation des processus métier et informatique, traitement des données, flux de travail basés sur l'IA | Transactions distribuées, logique d'application dynamique, orchestration des fonctions, traitement des données, flux de travail basés sur l'IA | 

## Architectures hybrides
<a name="durable-sfn-hybrid"></a>

De nombreuses applications bénéficient de l'utilisation de ces deux services. Un modèle courant consiste à utiliser des fonctions durables pour la logique au niveau de l'application dans Lambda, tandis que Step Functions coordonne les flux de travail de haut niveau entre plusieurs services AWS au-delà des fonctions Lambda.

## Considérations concernant la migration
<a name="durable-sfn-migration"></a>

**Commencer par un processus simple et évolutif :** commencez par des fonctions durables pour les flux de travail centrés sur Lambda. Ajoutez Step Functions lorsque vous avez besoin d'une orchestration multiservice ou d'une conception visuelle du flux de travail.

**Utilisateurs existants de Step Functions :** conservez Step Functions pour les flux de travail interservices établis. Envisagez des fonctions durables pour la nouvelle logique d'application Lambda qui a besoin de fiabilité.

## Ressources connexes
<a name="durable-sfn-related"></a>
+ [Fonctions durables Lambda](durable-functions.md)
+ [Orchestration des fonctions Lambda avec Step Functions](with-step-functions.md)
+ [Commencer à utiliser des fonctions durables](durable-getting-started.md)

# Exemples et cas d'utilisation
<a name="durable-examples"></a>

Les fonctions durables de Lambda vous permettent de créer des applications en plusieurs étapes tolérantes aux pannes en utilisant des opérations durables telles que les étapes et les attentes. Grâce au point de contrôle automatique et à un modèle de réexécution des points de contrôle, dans lequel l'exécution redémarre depuis le début après un échec mais ignore les points de contrôle terminés, vos fonctions peuvent se rétablir après un échec et reprendre l'exécution sans perdre leur progression.

## Procédés de courte durée tolérants aux pannes
<a name="durable-examples-short-lived"></a>

Utilisez des fonctions durables pour créer des opérations fiables qui se terminent généralement en quelques minutes. Bien que ces processus soient plus courts que les flux de travail de longue durée, ils bénéficient tout de même du point de contrôle automatique et de la tolérance aux pannes dans les systèmes distribués. Des fonctions durables contribuent à garantir le succès de vos processus en plusieurs étapes, même en cas d'échec d'appels de service individuels, sans nécessiter de gestion des erreurs complexe ni de code de gestion des états.

Les scénarios courants incluent les systèmes de réservation d'hôtels, les plateformes de réservation de restaurants, les demandes de voyages en covoiturage, les achats de billets pour des événements et les mises à niveau d'abonnements SaaS. Ces scénarios présentent des caractéristiques communes : plusieurs appels de service qui doivent être exécutés en même temps, la nécessité d'une nouvelle tentative automatique en cas d'échec transitoire et la nécessité de maintenir un état cohérent sur l'ensemble des systèmes distribués.

### Transactions distribuées sur des microservices
<a name="durable-examples-distributed-transactions"></a>

Coordonnez les paiements, les stocks et les expéditions entre plusieurs services grâce à l'annulation automatique en cas de panne. Chaque opération de service est encapsulée en une étape, ce qui garantit que la transaction peut être rétablie à tout moment en cas de défaillance d'un service.

------
#### [ TypeScript ]

```
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const { orderId, amount, items } = event;
    
    // Reserve inventory across multiple warehouses
    const inventory = await context.step("reserve-inventory", async () => {
      return await inventoryService.reserve(items);
    });
    
    // Process payment
    const payment = await context.step("process-payment", async () => {
      return await paymentService.charge(amount);
    });
    
    // Create shipment
    const shipment = await context.step("create-shipment", async () => {
      return await shippingService.createShipment(orderId, inventory);
    });
    
    return { orderId, status: 'completed', shipment };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import DurableContext, durable_execution

@durable_execution
def lambda_handler(event, context: DurableContext):
    order_id = event['orderId']
    amount = event['amount']
    items = event['items']
    
    # Reserve inventory across multiple warehouses
    inventory = context.step(
        lambda _: inventory_service.reserve(items),
        name='reserve-inventory'
    )
    
    # Process payment
    payment = context.step(
        lambda _: payment_service.charge(amount),
        name='process-payment'
    )
    
    # Create shipment
    shipment = context.step(
        lambda _: shipping_service.create_shipment(order_id, inventory),
        name='create-shipment'
    )
    
    return {'orderId': order_id, 'status': 'completed', 'shipment': shipment}
```

------

Si une étape échoue, la fonction réessaie automatiquement à partir du dernier point de contrôle réussi. La réservation d'inventaire est maintenue même si le traitement du paiement échoue temporairement. Lorsque la fonction essaie à nouveau, elle ignore l'étape d'inventaire terminée et passe directement au traitement des paiements. Cela élimine les réservations dupliquées et garantit un état cohérent dans l'ensemble de votre système distribué.

### Traitement des commandes en plusieurs étapes
<a name="durable-examples-order-processing"></a>

Traitez les commandes par le biais de la validation, de l'autorisation de paiement, de l'allocation des stocks et de l'exécution avec une nouvelle tentative et une reprise automatiques. Chaque étape fait l'objet d'un point de contrôle, garantissant ainsi la progression de la commande même si les étapes individuelles échouent et que vous réessayez.

------
#### [ TypeScript ]

```
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const { orderId, customerId, items } = event;
    
    // Validate order details
    const validation = await context.step("validate-order", async () => {
      const customer = await customerService.validate(customerId);
      const itemsValid = await inventoryService.validateItems(items);
      return { customer, itemsValid };
    });
    
    if (!validation.itemsValid) {
      return { orderId, status: 'rejected', reason: 'invalid_items' };
    }
    
    // Authorize payment
    const authorization = await context.step("authorize-payment", async () => {
      return await paymentService.authorize(
        validation.customer.paymentMethod,
        calculateTotal(items)
      );
    });
    
    // Allocate inventory
    const allocation = await context.step("allocate-inventory", async () => {
      return await inventoryService.allocate(items);
    });
    
    // Fulfill order
    const fulfillment = await context.step("fulfill-order", async () => {
      return await fulfillmentService.createShipment({
        orderId,
        items: allocation.allocatedItems,
        address: validation.customer.shippingAddress
      });
    });
    
    return {
      orderId,
      status: 'completed',
      trackingNumber: fulfillment.trackingNumber
    };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import DurableContext, durable_execution

@durable_execution
def lambda_handler(event, context: DurableContext):
    order_id = event['orderId']
    customer_id = event['customerId']
    items = event['items']
    
    # Validate order details
    def validate_order(_):
        customer = customer_service.validate(customer_id)
        items_valid = inventory_service.validate_items(items)
        return {'customer': customer, 'itemsValid': items_valid}
    
    validation = context.step(validate_order, name='validate-order')
    
    if not validation['itemsValid']:
        return {'orderId': order_id, 'status': 'rejected', 'reason': 'invalid_items'}
    
    # Authorize payment
    authorization = context.step(
        lambda _: payment_service.authorize(
            validation['customer']['paymentMethod'],
            calculate_total(items)
        ),
        name='authorize-payment'
    )
    
    # Allocate inventory
    allocation = context.step(
        lambda _: inventory_service.allocate(items),
        name='allocate-inventory'
    )
    
    # Fulfill order
    fulfillment = context.step(
        lambda _: fulfillment_service.create_shipment({
            'orderId': order_id,
            'items': allocation['allocatedItems'],
            'address': validation['customer']['shippingAddress']
        }),
        name='fulfill-order'
    )
    
    return {
        'orderId': order_id,
        'status': 'completed',
        'trackingNumber': fulfillment['trackingNumber']
    }
```

------

Ce modèle garantit que les commandes ne restent jamais bloquées dans des états intermédiaires. Si la validation échoue, la commande est rejetée avant l'autorisation de paiement. Si l'autorisation de paiement échoue, le stock n'est pas alloué. Chaque étape s'appuie sur la précédente avec une nouvelle tentative et une restauration automatiques.

**Remarque**  
La vérification conditionnelle `if (!validation.itemsValid)` se situe en dehors d'une étape et sera réexécutée pendant la rediffusion. C'est sûr car c'est déterministe : cela produit toujours le même résultat pour le même objet de validation.

## Procédés de longue durée
<a name="durable-examples-long-running"></a>

Utilisez des fonctions durables pour les processus qui s'étendent sur des heures, des jours ou des semaines. Les opérations d'attente suspendent l'exécution sans frais de calcul, ce qui permet de rentabiliser les processus de longue durée. Pendant les périodes d'attente, votre fonction cesse de fonctionner et Lambda recycle l'environnement d'exécution. Au moment de reprendre, Lambda invoque à nouveau votre fonction et la rejoue depuis le dernier point de contrôle.

Ce modèle d'exécution rend les fonctions durables idéales pour les processus qui doivent être interrompus pendant de longues périodes, qu'il s'agisse d'attendre des décisions humaines, des réponses du système externe, des fenêtres de traitement planifiées ou des retards temporels. Vous ne payez que pour le temps de calcul actif, et non pour le temps d'attente.

Les scénarios courants incluent les processus d'approbation des documents, le traitement par lots planifié, les processus d'intégration sur plusieurs jours, les processus d'essai d'abonnement et les systèmes de notification différée. Ces scénarios présentent des caractéristiques communes : des délais d'attente prolongés mesurés en heures ou en jours, la nécessité de maintenir l'état d'exécution pendant ces temps d'attente et des exigences liées aux coûts dans lesquelles le paiement pour le temps de calcul inactif est prohibitif.

### Human-in-the-loop approbations
<a name="durable-examples-human-in-loop"></a>

Suspendez l'exécution pour les révisions de documents, les approbations ou les décisions tout en maintenant l'état d'exécution. La fonction attend les rappels externes sans consommer de ressources et reprend automatiquement lorsque l'approbation est reçue.

Ce modèle est essentiel pour les processus qui nécessitent un jugement humain ou une validation externe. La fonction est suspendue au point de rappel, sans frais de calcul pendant l'attente. Lorsque quelqu'un soumet sa décision via l'API, Lambda invoque à nouveau votre fonction et rejoue depuis le point de contrôle, en continuant avec le résultat de l'approbation.

------
#### [ TypeScript ]

```
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const { documentId, reviewers } = event;
    
    // Step 1: Prepare document for review
    const prepared = await context.step("prepare-document", async () => {
      return await documentService.prepare(documentId);
    });
    
    // Step 2: Request approval with callback
    const approval = await context.waitForCallback(
      "approval-callback",
      async (callbackId) => {
        await notificationService.sendApprovalRequest({
          documentId,
          reviewers,
          callbackId,
          expiresIn: 86400
        });
      },
      {
        timeout: { seconds: 86400 }
      }
    );
    
    // Function resumes here when approval is received
    if (approval?.approved) {
      const finalized = await context.step("finalize-document", async () => {
        return await documentService.finalize(documentId, approval.comments);
      });
      
      return {
        status: 'approved',
        documentId,
        finalizedAt: finalized.timestamp
      };
    }
    
    // Handle rejection
    await context.step("archive-rejected", async () => {
      await documentService.archive(documentId, approval?.reason);
    });
    
    return {
      status: 'rejected',
      documentId,
      reason: approval?.reason
    };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import DurableContext, durable_execution, WaitConfig

@durable_execution
def lambda_handler(event, context: DurableContext):
    document_id = event['documentId']
    reviewers = event['reviewers']
    
    # Step 1: Prepare document for review
    prepared = context.step(
        lambda _: document_service.prepare(document_id),
        name='prepare-document'
    )
    
    # Step 2: Request approval with callback
    def send_approval_request(callback_id):
        notification_service.send_approval_request({
            'documentId': document_id,
            'reviewers': reviewers,
            'callbackId': callback_id,
            'expiresIn': 86400
        })
    
    approval = context.wait_for_callback(
        send_approval_request,
        name='approval-callback',
        config=WaitConfig(timeout=86400)
    )
    
    # Function resumes here when approval is received
    if approval and approval.get('approved'):
        finalized = context.step(
            lambda _: document_service.finalize(document_id, approval.get('comments')),
            name='finalize-document'
        )
        
        return {
            'status': 'approved',
            'documentId': document_id,
            'finalizedAt': finalized['timestamp']
        }
    
    # Handle rejection
    context.step(
        lambda _: document_service.archive(document_id, approval.get('reason') if approval else None),
        name='archive-rejected'
    )
    
    return {
        'status': 'rejected',
        'documentId': document_id,
        'reason': approval.get('reason') if approval else None
    }
```

------

Lorsque le rappel est reçu et que votre fonction reprend, elle est rejouée depuis le début. L'étape de préparation du document renvoie instantanément le résultat du point de contrôle. L' waitForCallback opération renvoie également instantanément le résultat d'approbation enregistré au lieu d'attendre à nouveau. L'exécution se poursuit ensuite jusqu'aux étapes de finalisation ou d'archivage.

### Pipelines de données en plusieurs étapes
<a name="durable-examples-data-pipelines"></a>

Traitez de grands ensembles de données par le biais de phases d'extraction, de transformation et de chargement avec des points de contrôle entre les étapes. Chaque étape peut prendre des heures, et les points de contrôle permettent au pipeline de reprendre à partir de n'importe quelle étape en cas d'interruption.

Ce modèle est idéal pour les flux de travail ETL, les migrations de données ou les tâches de traitement par lots où vous devez traiter les données par étapes, avec des points de récupération entre eux. Si une étape échoue, le pipeline reprend à partir de la dernière étape terminée plutôt que de recommencer depuis le début. Vous pouvez également utiliser les opérations d'attente pour faire une pause entre les étapes, en respectant les limites de débit, en attendant que les systèmes en aval soient prêts ou en planifiant le traitement en dehors des heures de pointe.

------
#### [ TypeScript ]

```
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const { datasetId, batchSize } = event;
    
    // Stage 1: Extract data from source
    const extracted = await context.step("extract-data", async () => {
      const records = await sourceDatabase.extractRecords(datasetId);
      return { recordCount: records.length, records };
    });
    
    // Wait 5 minutes to respect source system rate limits
    await context.wait({ seconds: 300 });
    
    // Stage 2: Transform data in batches
    const transformed = await context.step("transform-data", async () => {
      const batches = chunkArray(extracted.records, batchSize);
      const results = [];
      
      for (const batch of batches) {
        const transformed = await transformService.processBatch(batch);
        results.push(transformed);
      }
      
      return { batchCount: batches.length, results };
    });
    
    // Wait until off-peak hours (e.g., 2 AM)
    const now = new Date();
    const targetHour = 2;
    const msUntilTarget = calculateMsUntilHour(now, targetHour);
    await context.wait({ seconds: Math.floor(msUntilTarget / 1000) });
    
    // Stage 3: Load data to destination
    const loaded = await context.step("load-data", async () => {
      let loadedCount = 0;
      
      for (const result of transformed.results) {
        await destinationDatabase.loadBatch(result);
        loadedCount += result.length;
      }
      
      return { loadedCount };
    });
    
    // Stage 4: Verify and finalize
    const verified = await context.step("verify-pipeline", async () => {
      const verification = await destinationDatabase.verifyRecords(datasetId);
      await pipelineService.markComplete(datasetId, verification);
      return verification;
    });
    
    return {
      datasetId,
      recordsProcessed: extracted.recordCount,
      batchesProcessed: transformed.batchCount,
      recordsLoaded: loaded.loadedCount,
      verified: verified.success
    };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import DurableContext, durable_execution
from datetime import datetime

@durable_execution
def lambda_handler(event, context: DurableContext):
    dataset_id = event['datasetId']
    batch_size = event['batchSize']
    
    # Stage 1: Extract data from source
    def extract_data(_):
        records = source_database.extract_records(dataset_id)
        return {'recordCount': len(records), 'records': records}
    
    extracted = context.step(extract_data, name='extract-data')
    
    # Wait 5 minutes to respect source system rate limits
    context.wait(300)
    
    # Stage 2: Transform data in batches
    def transform_data(_):
        batches = chunk_array(extracted['records'], batch_size)
        results = []
        
        for batch in batches:
            transformed = transform_service.process_batch(batch)
            results.append(transformed)
        
        return {'batchCount': len(batches), 'results': results}
    
    transformed = context.step(transform_data, name='transform-data')
    
    # Wait until off-peak hours (e.g., 2 AM)
    now = datetime.now()
    target_hour = 2
    ms_until_target = calculate_ms_until_hour(now, target_hour)
    context.wait(ms_until_target // 1000)
    
    # Stage 3: Load data to destination
    def load_data(_):
        loaded_count = 0
        
        for result in transformed['results']:
            destination_database.load_batch(result)
            loaded_count += len(result)
        
        return {'loadedCount': loaded_count}
    
    loaded = context.step(load_data, name='load-data')
    
    # Stage 4: Verify and finalize
    def verify_pipeline(_):
        verification = destination_database.verify_records(dataset_id)
        pipeline_service.mark_complete(dataset_id, verification)
        return verification
    
    verified = context.step(verify_pipeline, name='verify-pipeline')
    
    return {
        'datasetId': dataset_id,
        'recordsProcessed': extracted['recordCount'],
        'batchesProcessed': transformed['batchCount'],
        'recordsLoaded': loaded['loadedCount'],
        'verified': verified['success']
    }
```

------

Chaque étape est encapsulée dans une étape, ce qui crée un point de contrôle qui permet au pipeline de reprendre à partir de n'importe quelle étape en cas d'interruption. L'attente de 5 minutes entre l'extraction et la transformation respecte les limites de débit du système source sans consommer de ressources informatiques, tandis que l'attente jusqu'à 2 heures du matin permet de planifier l'opération de chargement coûteuse pendant les heures creuses.

**Remarque**  
L'`new Date()`appel et la `calculateMsUntilHour()` fonction sont des étapes extérieures et seront réexécutés pendant la rediffusion. Pour les opérations basées sur le temps qui doivent être cohérentes entre les rediffusions, calculez l'horodatage d'une étape ou utilisez-le uniquement pour les durées d'attente (qui sont des points de contrôle).

## Modèles avancés
<a name="durable-examples-advanced"></a>

Utilisez des fonctions durables pour créer des applications complexes en plusieurs étapes qui combinent plusieurs opérations durables, l'exécution parallèle, le traitement de tableaux, la logique conditionnelle et les interrogations. Ces modèles vous permettent de créer des applications sophistiquées qui coordonnent de nombreuses tâches tout en maintenant la tolérance aux pannes et la restauration automatique.

Les modèles avancés vont au-delà de simples étapes séquentielles. Vous pouvez exécuter des opérations simultanément`parallel()`, traiter des tableaux avec ces primitives`map()`, attendre des conditions extérieures et combiner ces primitives pour créer des applications fiables. `waitForCondition()` Chaque opération durable crée ses propres points de contrôle, afin que votre application puisse se rétablir à tout moment en cas d'interruption.

### Processus d'intégration des utilisateurs
<a name="durable-examples-user-onboarding"></a>

Guidez les utilisateurs lors de l'enregistrement, de la vérification des e-mails, de la configuration du profil et de la configuration initiale avec gestion des nouvelles tentatives. Cet exemple combine des étapes séquentielles, des rappels et une logique conditionnelle pour créer un processus d'intégration complet.

------
#### [ TypeScript ]

```
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const { userId, email } = event;
    
    // Step 1: Create user account
    const user = await context.step("create-account", async () => {
      return await userService.createAccount(userId, email);
    });
    
    // Step 2: Send verification email
    await context.step("send-verification", async () => {
      return await emailService.sendVerification(email);
    });
    
    // Step 3: Wait for email verification (up to 48 hours)
    const verified = await context.waitForCallback(
      "email-verification",
      async (callbackId) => {
        await notificationService.sendVerificationLink({
          email,
          callbackId,
          expiresIn: 172800
        });
      },
      {
        timeout: { seconds: 172800 }
      }
    );
    
    if (!verified) {
      await context.step("send-reminder", async () => {
        await emailService.sendReminder(email);
      });
      
      return {
        status: "verification_timeout",
        userId,
        message: "Email verification not completed within 48 hours"
      };
    }
    
    // Step 4: Initialize user profile in parallel
    const setupResults = await context.parallel("profile-setup", [
      async (ctx: DurableContext) => {
        return await ctx.step("create-preferences", async () => {
          return await preferencesService.createDefaults(userId);
        });
      },
      
      async (ctx: DurableContext) => {
        return await ctx.step("setup-notifications", async () => {
          return await notificationService.setupDefaults(userId);
        });
      },
      
      async (ctx: DurableContext) => {
        return await ctx.step("create-welcome-content", async () => {
          return await contentService.createWelcome(userId);
        });
      }
    ]);
    
    // Step 5: Send welcome email
    await context.step("send-welcome", async () => {
      const [preferences, notifications, content] = setupResults.getResults();
      return await emailService.sendWelcome({
        email,
        preferences,
        notifications,
        content
      });
    });
    
    return {
      status: "onboarding_complete",
      userId,
      completedAt: new Date().toISOString()
    };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import DurableContext, durable_execution, WaitConfig
from datetime import datetime

@durable_execution
def lambda_handler(event, context: DurableContext):
    user_id = event['userId']
    email = event['email']
    
    # Step 1: Create user account
    user = context.step(
        lambda _: user_service.create_account(user_id, email),
        name='create-account'
    )
    
    # Step 2: Send verification email
    context.step(
        lambda _: email_service.send_verification(email),
        name='send-verification'
    )
    
    # Step 3: Wait for email verification (up to 48 hours)
    def send_verification_link(callback_id):
        notification_service.send_verification_link({
            'email': email,
            'callbackId': callback_id,
            'expiresIn': 172800
        })
    
    verified = context.wait_for_callback(
        send_verification_link,
        name='email-verification',
        config=WaitConfig(timeout=172800)
    )
    
    if not verified:
        context.step(
            lambda _: email_service.send_reminder(email),
            name='send-reminder'
        )
        
        return {
            'status': 'verification_timeout',
            'userId': user_id,
            'message': 'Email verification not completed within 48 hours'
        }
    
    # Step 4: Initialize user profile in parallel
    def create_preferences(ctx: DurableContext):
        return ctx.step(
            lambda _: preferences_service.create_defaults(user_id),
            name='create-preferences'
        )
    
    def setup_notifications(ctx: DurableContext):
        return ctx.step(
            lambda _: notification_service.setup_defaults(user_id),
            name='setup-notifications'
        )
    
    def create_welcome_content(ctx: DurableContext):
        return ctx.step(
            lambda _: content_service.create_welcome(user_id),
            name='create-welcome-content'
        )
    
    setup_results = context.parallel(
        [create_preferences, setup_notifications, create_welcome_content],
        name='profile-setup'
    )
    
    # Step 5: Send welcome email
    def send_welcome(_):
        results = setup_results.get_results()
        preferences, notifications, content = results[0], results[1], results[2]
        return email_service.send_welcome({
            'email': email,
            'preferences': preferences,
            'notifications': notifications,
            'content': content
        })
    
    context.step(send_welcome, name='send-welcome')
    
    return {
        'status': 'onboarding_complete',
        'userId': user_id,
        'completedAt': datetime.now().isoformat()
    }
```

------

Le processus combine des étapes séquentielles avec des points de contrôle pour la création de comptes et l'envoi d'e-mails, puis s'interrompt pendant 48 heures en attendant la vérification des e-mails sans consommer de ressources. La logique conditionnelle gère différents chemins selon que la vérification est terminée ou expirée. Les tâches de configuration du profil s'exécutent simultanément à l'aide d'opérations parallèles afin de réduire le temps d'exécution total, et chaque étape réessaie automatiquement en cas d'échec transitoire afin de garantir la fiabilité de l'intégration.

### Invocations enchaînées entre les fonctions
<a name="durable-examples-chained-invocations"></a>

Invoquez d'autres fonctions Lambda depuis une fonction durable en utilisant. `context.invoke()` La fonction appelante est suspendue en attendant que la fonction invoquée soit terminée, créant ainsi un point de contrôle qui préserve le résultat. Si la fonction appelante est interrompue une fois la fonction invoquée terminée, elle reprend avec le résultat enregistré sans avoir à réinvoquer la fonction.

Utilisez ce modèle lorsque vous avez des fonctions spécialisées qui gèrent des domaines spécifiques (validation des clients, traitement des paiements, gestion des stocks) et que vous devez les coordonner dans un flux de travail. Chaque fonction conserve sa propre logique et peut être invoquée par plusieurs fonctions d'orchestrateur, évitant ainsi la duplication de code.

------
#### [ TypeScript ]

```
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

// Main orchestrator function
export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const { orderId, customerId } = event;
    
    // Step 1: Validate customer by invoking customer service function
    const customer = await context.invoke(
      "validate-customer",
      "arn:aws:lambda:us-east-1:123456789012:function:customer-service:1",
      { customerId }
    );
    
    if (!customer.isValid) {
      return { orderId, status: "rejected", reason: "invalid_customer" };
    }
    
    // Step 2: Check inventory by invoking inventory service function
    const inventory = await context.invoke(
      "check-inventory",
      "arn:aws:lambda:us-east-1:123456789012:function:inventory-service:1",
      { orderId, items: event.items }
    );
    
    if (!inventory.available) {
      return { orderId, status: "rejected", reason: "insufficient_inventory" };
    }
    
    // Step 3: Process payment by invoking payment service function
    const payment = await context.invoke(
      "process-payment",
      "arn:aws:lambda:us-east-1:123456789012:function:payment-service:1",
      {
        customerId,
        amount: inventory.totalAmount,
        paymentMethod: customer.paymentMethod
      }
    );
    
    // Step 4: Create shipment by invoking fulfillment service function
    const shipment = await context.invoke(
      "create-shipment",
      "arn:aws:lambda:us-east-1:123456789012:function:fulfillment-service:1",
      {
        orderId,
        items: inventory.allocatedItems,
        address: customer.shippingAddress
      }
    );
    
    return {
      orderId,
      status: "completed",
      trackingNumber: shipment.trackingNumber,
      estimatedDelivery: shipment.estimatedDelivery
    };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import DurableContext, durable_execution

# Main orchestrator function
@durable_execution
def lambda_handler(event, context: DurableContext):
    order_id = event['orderId']
    customer_id = event['customerId']
    
    # Step 1: Validate customer by invoking customer service function
    customer = context.invoke(
        'arn:aws:lambda:us-east-1:123456789012:function:customer-service:1',
        {'customerId': customer_id},
        name='validate-customer'
    )
    
    if not customer['isValid']:
        return {'orderId': order_id, 'status': 'rejected', 'reason': 'invalid_customer'}
    
    # Step 2: Check inventory by invoking inventory service function
    inventory = context.invoke(
        'arn:aws:lambda:us-east-1:123456789012:function:inventory-service:1',
        {'orderId': order_id, 'items': event['items']},
        name='check-inventory'
    )
    
    if not inventory['available']:
        return {'orderId': order_id, 'status': 'rejected', 'reason': 'insufficient_inventory'}
    
    # Step 3: Process payment by invoking payment service function
    payment = context.invoke(
        'arn:aws:lambda:us-east-1:123456789012:function:payment-service:1',
        {
            'customerId': customer_id,
            'amount': inventory['totalAmount'],
            'paymentMethod': customer['paymentMethod']
        },
        name='process-payment'
    )
    
    # Step 4: Create shipment by invoking fulfillment service function
    shipment = context.invoke(
        'arn:aws:lambda:us-east-1:123456789012:function:fulfillment-service:1',
        {
            'orderId': order_id,
            'items': inventory['allocatedItems'],
            'address': customer['shippingAddress']
        },
        name='create-shipment'
    )
    
    return {
        'orderId': order_id,
        'status': 'completed',
        'trackingNumber': shipment['trackingNumber'],
        'estimatedDelivery': shipment['estimatedDelivery']
    }
```

------

Chaque invocation crée un point de contrôle dans la fonction d'orchestrateur. Si l'orchestrateur est interrompu une fois la validation du client terminée, il reprend à partir de ce point de contrôle avec les données client stockées, en ignorant l'appel de validation. Cela permet d'éviter les appels dupliqués vers les services en aval et de garantir une exécution cohérente malgré les interruptions.

Les fonctions invoquées peuvent être des fonctions Lambda durables ou standard. Si vous invoquez une fonction durable, elle peut avoir son propre flux de travail en plusieurs étapes avec des temps d'attente et des points de contrôle. L'orchestrateur attend simplement la fin de l'exécution durable complète pour obtenir le résultat final.

**Note**  
Les appels entre comptes ne sont pas pris en charge. Toutes les fonctions invoquées doivent être dans le même AWS compte que la fonction appelante.

### Traitement par lots avec points de contrôle
<a name="durable-examples-batch-processing"></a>

Traitez des millions d'enregistrements grâce à la restauration automatique depuis le dernier point de contrôle réussi après un échec. Cet exemple montre comment les fonctions durables combinent les `map()` opérations avec le découpage et la limitation de débit pour gérer le traitement de données à grande échelle.

------
#### [ TypeScript ]

```
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

interface Batch {
  batchIndex: number;
  recordIds: string[];
}

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    const { datasetId, batchSize = 1000 } = event;
    
    // Step 1: Get all record IDs to process
    const recordIds = await context.step("fetch-record-ids", async () => {
      return await dataService.getRecordIds(datasetId);
    });
    
    // Step 2: Split into batches
    const batches: Batch[] = [];
    for (let i = 0; i < recordIds.length; i += batchSize) {
      batches.push({
        batchIndex: Math.floor(i / batchSize),
        recordIds: recordIds.slice(i, i + batchSize)
      });
    }
    
    // Step 3: Process batches with controlled concurrency
    const batchResults = await context.map(
      "process-batches",
      batches,
      async (ctx: DurableContext, batch: Batch, index: number) => {
        const processed = await ctx.step(`batch-${batch.batchIndex}`, async () => {
          const results = [];
          for (const recordId of batch.recordIds) {
            const result = await recordService.process(recordId);
            results.push(result);
          }
          return results;
        });
        
        const validated = await ctx.step(`validate-${batch.batchIndex}`, async () => {
          return await validationService.validateBatch(processed);
        });
        
        return {
          batchIndex: batch.batchIndex,
          recordCount: batch.recordIds.length,
          successCount: validated.successCount,
          failureCount: validated.failureCount
        };
      },
      {
        maxConcurrency: 5
      }
    );
    
    // Step 4: Aggregate results
    const summary = await context.step("aggregate-results", async () => {
      const results = batchResults.getResults();
      const totalSuccess = results.reduce((sum, r) => sum + r.successCount, 0);
      const totalFailure = results.reduce((sum, r) => sum + r.failureCount, 0);
      
      return {
        datasetId,
        totalRecords: recordIds.length,
        batchesProcessed: batches.length,
        successCount: totalSuccess,
        failureCount: totalFailure,
        completedAt: new Date().toISOString()
      };
    });
    
    return summary;
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import DurableContext, durable_execution, MapConfig
from datetime import datetime
from typing import List, Dict

@durable_execution
def lambda_handler(event, context: DurableContext):
    dataset_id = event['datasetId']
    batch_size = event.get('batchSize', 1000)
    
    # Step 1: Get all record IDs to process
    record_ids = context.step(
        lambda _: data_service.get_record_ids(dataset_id),
        name='fetch-record-ids'
    )
    
    # Step 2: Split into batches
    batches = []
    for i in range(0, len(record_ids), batch_size):
        batches.append({
            'batchIndex': i // batch_size,
            'recordIds': record_ids[i:i + batch_size]
        })
    
    # Step 3: Process batches with controlled concurrency
    def process_batch(ctx: DurableContext, batch: Dict, index: int):
        batch_index = batch['batchIndex']
        
        def process_records(_):
            results = []
            for record_id in batch['recordIds']:
                result = record_service.process(record_id)
                results.append(result)
            return results
        
        processed = ctx.step(process_records, name=f'batch-{batch_index}')
        
        validated = ctx.step(
            lambda _: validation_service.validate_batch(processed),
            name=f'validate-{batch_index}'
        )
        
        return {
            'batchIndex': batch_index,
            'recordCount': len(batch['recordIds']),
            'successCount': validated['successCount'],
            'failureCount': validated['failureCount']
        }
    
    batch_results = context.map(
        process_batch,
        batches,
        name='process-batches',
        config=MapConfig(max_concurrency=5)
    )
    
    # Step 4: Aggregate results
    def aggregate_results(_):
        results = batch_results.get_results()
        total_success = sum(r['successCount'] for r in results)
        total_failure = sum(r['failureCount'] for r in results)
        
        return {
            'datasetId': dataset_id,
            'totalRecords': len(record_ids),
            'batchesProcessed': len(batches),
            'successCount': total_success,
            'failureCount': total_failure,
            'completedAt': datetime.now().isoformat()
        }
    
    summary = context.step(aggregate_results, name='aggregate-results')
    
    return summary
```

------

Les enregistrements sont divisés en lots gérables pour éviter de surcharger la mémoire ou les services en aval, puis plusieurs lots sont traités simultanément avec `maxConcurrency` le contrôle du parallélisme. Chaque lot possède son propre point de contrôle, de sorte que les échecs ne font que réessayer le lot défaillant au lieu de retraiter tous les enregistrements. Ce modèle est idéal pour les tâches ETL, les migrations de données ou les opérations en masse dont le traitement peut prendre des heures.

## Étapes suivantes
<a name="durable-examples-next-steps"></a>
+ Explorez les [concepts de base](durable-basic-concepts.md) pour comprendre DurableContext, les étapes et les attentes
+ Passez en revue [les meilleures pratiques](durable-best-practices.md) en matière d'écriture de code déterministe et d'optimisation des performances
+ Découvrez comment [tester des fonctions durables](durable-testing.md) en local et dans le cloud
+ Comparez les fonctions durables aux Step Functions pour savoir quand chaque approche est la plus efficace. Voir [Durable functions ou Step Functions](durable-step-functions.md).

# Sécurité et autorisations pour les fonctions durables de Lambda
<a name="durable-security"></a>

Les fonctions durables de Lambda nécessitent des autorisations IAM spécifiques pour gérer les opérations des points de contrôle. Respectez le principe du moindre privilège en n'accordant que les autorisations dont votre fonction a besoin.

## Autorisations du rôle d’exécution
<a name="durable-execution-role"></a>

Le rôle d'exécution de votre fonction durable nécessite des autorisations pour créer des points de contrôle et récupérer l'état d'exécution. La politique suivante indique les autorisations minimales requises :

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:CheckpointDurableExecution",
                "lambda:GetDurableExecutionState"
            ],
            "Resource": "arn:aws:lambda:region:account-id:function:function-name:*"
        }
    ]
}
```

Lorsque vous créez une fonction durable à l'aide de la console, Lambda ajoute automatiquement ces autorisations au rôle d'exécution. Si vous créez la fonction à l'aide du AWS CLI ou AWS CloudFormation, ajoutez ces autorisations à votre rôle d'exécution.

**Principe du moindre privilège**  
Délimitez l'`Resource`élément à une fonction spécifique ARNs au lieu d'utiliser des caractères génériques. Cela limite le rôle d'exécution aux opérations de point de contrôle uniquement pour les fonctions qui en ont besoin.

**Exemple : autorisations étendues pour plusieurs fonctions**

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:CheckpointDurableExecution",
                "lambda:GetDurableExecutionState"
            ],
            "Resource": [
                "arn:aws:lambda:us-east-1:123456789012:function:orderProcessor:*",
                "arn:aws:lambda:us-east-1:123456789012:function:paymentHandler:*"
            ]
        }
    ]
}
```

Vous pouvez également utiliser la politique AWS gérée `AWSLambdaBasicDurableExecutionRolePolicy` qui inclut les autorisations d'exécution durables requises ainsi que les autorisations d'exécution Lambda de base pour Amazon CloudWatch Logs.

## Chiffrement d'état
<a name="durable-state-encryption"></a>

Les fonctions Lambda Durable activent automatiquement le chiffrement au repos à l'aide de clés AWS détenues gratuitement. Chaque exécution de fonction conserve un état isolé auquel les autres exécutions ne peuvent pas accéder. Les clés gérées par le client (CMK) ne sont pas prises en charge.

Les données des points de contrôle incluent :
+ Résultats des étapes et valeurs renvoyées
+ Progrès et calendrier de l'exécution
+ Informations sur l'état d'attente

Toutes les données sont cryptées en transit à l'aide du protocole TLS lorsque Lambda lit ou écrit des données de point de contrôle.

### Chiffrement personnalisé avec sérialiseurs et désérialiseurs personnalisés
<a name="durable-custom-encryption"></a>

Pour les exigences de sécurité critiques, vous pouvez implémenter votre propre mécanisme de chiffrement et de déchiffrement à l'aide de sérialiseurs et de désérialiseurs personnalisés () à l'aide d'un SDK durable. SerDer Cette approche vous donne un contrôle total sur les clés de chiffrement et les algorithmes utilisés pour protéger les données des points de contrôle.

**Important**  
Lorsque vous utilisez un chiffrement personnalisé, vous perdez la visibilité des résultats des opérations dans la console Lambda et les réponses de l'API. Les données des points de contrôle apparaissent cryptées dans l'historique des exécutions et ne peuvent pas être inspectées sans déchiffrement.

Le rôle d'exécution de votre fonction `kms:Decrypt` nécessite `kms:Encrypt` et autorise la AWS KMS clé utilisée dans l' SerDer implémentation personnalisée.

## CloudTrail journalisation
<a name="durable-cloudtrail-logging"></a>

Lambda enregistre les opérations des points de contrôle sous forme d'événements de données dans. AWS CloudTrail Vous pouvez l'utiliser CloudTrail pour auditer le moment où les points de contrôle sont créés, suivre les changements d'état d'exécution et surveiller l'accès aux données d'exécution durables.

Les opérations de point de contrôle apparaissent dans CloudTrail les journaux sous les noms d'événements suivants :
+ `CheckpointDurableExecution`- Enregistré lorsqu'une étape se termine et crée un point de contrôle
+ `GetDurableExecutionState`- Enregistré lorsque Lambda récupère l'état d'exécution pendant la rediffusion

Pour activer la journalisation des événements de données pour des fonctions durables, configurez un journal CloudTrail pour enregistrer les événements de données Lambda. Pour plus d'informations, consultez la section [Journalisation des événements liés aux données](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html) dans le Guide de CloudTrail l'utilisateur.

**Exemple : entrée de CloudTrail journal pour le fonctionnement du point de contrôle**

```
{
    "eventVersion": "1.08",
    "eventTime": "2024-11-16T10:30:45Z",
    "eventName": "CheckpointDurableExecution",
    "eventSource": "lambda.amazonaws.com",
    "requestParameters": {
        "functionName": "myDurableFunction",
        "executionId": "exec-abc123",
        "stepId": "step-1"
    },
    "responseElements": null,
    "eventType": "AwsApiCall"
}
```

## Considérations relatives à l’accès intercompte
<a name="durable-cross-account-access"></a>

Si vous invoquez des fonctions durables sur plusieurs AWS comptes, le compte appelant a besoin d'une `lambda:InvokeFunction` autorisation, mais les opérations de point de contrôle utilisent toujours le rôle d'exécution dans le compte de la fonction. Le compte appelant ne peut pas accéder directement aux données du point de contrôle ou à l'état d'exécution.

Cette isolation garantit que les données des points de contrôle restent sécurisées dans le compte de la fonction, même lorsqu'elles sont invoquées depuis des comptes externes.

## Fonctionnalités de sécurité Lambda héritées
<a name="durable-inherited-security"></a>

Les fonctions durables héritent de toutes les fonctionnalités de sécurité, de gouvernance et de conformité de Lambda, notamment la connectivité VPC, le chiffrement des variables d'environnement, les files d'attente lettre morte, la simultanéité réservée, les URLs fonctions, la signature de code et les certifications de conformité (SOC, PCI DSS, HIPAA, etc.).

Pour des informations détaillées sur les fonctionnalités de sécurité Lambda, consultez la section [Sécurité AWS Lambda dans le guide](https://docs.aws.amazon.com/lambda/latest/dg/lambda-security.html) du développeur Lambda. Les seules considérations de sécurité supplémentaires pour les fonctions durables sont les autorisations de point de contrôle décrites dans ce guide.

# SDK d'exécution durable
<a name="durable-execution-sdk"></a>

Le SDK d'exécution durable est la base de la création de fonctions durables. Il fournit les primitives dont vous avez besoin pour contrôler la progression, gérer les nouvelles tentatives et gérer le flux d'exécution. Le SDK élimine la complexité de la gestion et de la rediffusion des points de contrôle, en vous permettant d'écrire du code séquentiel qui devient automatiquement tolérant aux pannes.

Le SDK est disponible pour JavaScript Python et Java (version préliminaire). TypeScript Pour obtenir une documentation complète sur les API et des exemples, consultez le [TypeScript SDKJavaScript/](https://github.com/aws/aws-durable-execution-sdk-js), le [SDK Python](https://github.com/aws/aws-durable-execution-sdk-python) et le [SDK Java](https://github.com/aws/aws-durable-execution-sdk-java) sur. GitHub

## DurableContext
<a name="durable-sdk-context"></a>

Le SDK fournit à votre fonction un `DurableContext` objet qui expose toutes les opérations durables. Ce contexte remplace le contexte Lambda standard et fournit des méthodes pour créer des points de contrôle, gérer le flux d'exécution et coordonner avec des systèmes externes.

Pour utiliser le SDK, enveloppez votre gestionnaire Lambda avec le wrapper d'exécution durable :

------
#### [ TypeScript ]

```
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js';

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // Your function receives DurableContext instead of Lambda context
    // Use context.step(), context.wait(), etc.
    return result;
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import durable_execution, DurableContext

@durable_execution
def handler(event: dict, context: DurableContext):
    # Your function receives DurableContext
    # Use context.step(), context.wait(), etc.
    return result
```

------
#### [ Java (Preview) ]

```
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.DurableHandler;

public class Handler extends DurableHandler<Object, String> {
    @Override
    public String handleRequest(Object input, DurableContext context) {
        // Your function receives DurableContext
        // Use context.step(), context.wait(), etc.
        return result;
    }
}
```

------

Le wrapper intercepte l'invocation de votre fonction, charge tout journal de points de contrôle existant et fournit le journal `DurableContext` qui gère la rediffusion et le point de contrôle.

## Ce que fait le SDK
<a name="durable-sdk-what-it-does"></a>

Le SDK assume trois responsabilités essentielles qui permettent une exécution durable :

**Gestion des points de contrôle :** le SDK crée automatiquement des points de contrôle lorsque votre fonction exécute des opérations durables. Chaque point de contrôle enregistre le type d'opération, les entrées et les résultats. Lorsque votre fonction termine une étape, le SDK maintient le point de contrôle avant de continuer. Cela garantit que votre fonction peut reprendre après toute opération terminée en cas d'interruption.

**Coordination des rediffusions :** lorsque votre fonction reprend après une pause ou une interruption, le SDK effectue une rediffusion. Il exécute votre code depuis le début mais ignore les opérations terminées, en utilisant les résultats des points de contrôle stockés au lieu de les réexécuter. Le SDK garantit que la rediffusion est déterministe : avec les mêmes entrées et le même journal de points de contrôle, votre fonction produit les mêmes résultats.

**Isolation des états :** le SDK conserve l'état d'exécution séparément de votre logique métier. Chaque exécution durable possède son propre journal de points de contrôle auquel les autres exécutions ne peuvent pas accéder. Le SDK chiffre les données des points de contrôle au repos et garantit la cohérence de l'état entre les rediffusions.

## Comment fonctionne le point de contrôle
<a name="durable-sdk-how-checkpointing-works"></a>

Lorsque vous appelez une opération durable, le SDK suit cette séquence :

1. **Vérifier l'existence d'un point de contrôle :** le SDK vérifie si cette opération a déjà été effectuée lors d'un appel précédent. S'il existe un point de contrôle, le SDK renvoie le résultat enregistré sans réexécuter l'opération.

1. **Exécuter l'opération :** s'il n'existe aucun point de contrôle, le SDK exécute votre code d'opération. Pour les étapes, cela signifie appeler votre fonction. Pour les temps d'attente, cela signifie planifier la reprise.

1. **Créer un point de contrôle :** une fois l'opération terminée, le SDK sérialise le résultat et crée un point de contrôle. Le point de contrôle inclut le type d'opération, le nom, les entrées, le résultat et l'horodatage.

1. **Point de contrôle persistant :** le SDK appelle l'API du point de contrôle Lambda pour conserver le point de contrôle. Cela garantit la durabilité du point de contrôle avant de poursuivre l'exécution.

1. **Renvoyer le résultat :** le SDK renvoie le résultat de l'opération à votre code, qui passe à l'opération suivante.

Cette séquence garantit qu'une fois l'opération terminée, son résultat est stocké en toute sécurité. Si votre fonction est interrompue à tout moment, le SDK peut être rejoué jusqu'au dernier point de contrôle terminé.

## Comportement de rediffusion
<a name="durable-sdk-replay-behavior"></a>

Lorsque votre fonction reprend après une pause ou une interruption, le SDK effectue une rediffusion :

1. **Charger le journal des points de contrôle :** le SDK récupère le journal des points de contrôle pour cette exécution à partir de Lambda.

1. **Exécuter depuis le début :** le SDK appelle votre fonction de gestionnaire dès le début, et non depuis l'endroit où elle s'est interrompue.

1. **Ignorer les opérations durables terminées :** lorsque votre code appelle des opérations durables, le SDK compare chacune d'entre elles au journal des points de contrôle. Pour les opérations durables terminées, le SDK renvoie le résultat stocké sans exécuter le code d'opération.
**Note**  
Si le résultat d'un contexte enfant est supérieur à la taille maximale du point de contrôle (256 Ko), le code du contexte est à nouveau exécuté pendant la rediffusion. Cela vous permet de générer des résultats volumineux à partir des opérations durables exécutées dans le contexte, qui seront consultés dans le journal des points de contrôle. Il est donc impératif de n'exécuter le code déterministe que dans le contexte lui-même. Lorsque vous utilisez des contextes enfants avec des résultats importants, il est recommandé d'effectuer un travail de longue durée ou non déterministe à l'intérieur des étapes et de n'effectuer que des tâches de courte durée qui combinent les résultats dans le contexte lui-même.

1. **Reprise au point d'interruption :** lorsque le SDK atteint une opération sans point de contrôle, il s'exécute normalement et crée de nouveaux points de contrôle au fur et à mesure que les opérations durables sont terminées.

Ce mécanisme de rediffusion nécessite que votre code soit déterministe. Avec les mêmes entrées et le même journal de points de contrôle, votre fonction doit effectuer la même séquence d'appels d'opérations durables. Le SDK applique cela en validant que les noms et types d'opérations correspondent au journal des points de contrôle lors de la rediffusion.

## Opérations durables disponibles
<a name="durable-sdk-operations"></a>

`DurableContext`Il fournit des opérations pour différents modèles de coordination. Chaque opération durable crée automatiquement des points de contrôle, garantissant ainsi que votre fonction peut reprendre à tout moment.

### Étapes
<a name="durable-sdk-op-step"></a>

Exécute la logique métier avec pointage automatique des points de contrôle et réessais. Utilisez des étapes pour les opérations qui appellent des services externes, effectuent des calculs ou exécutent toute logique devant être vérifiée. Le SDK crée un point de contrôle avant et après l'étape, stockant le résultat pour le rejouer.

------
#### [ TypeScript ]

```
const result = await context.step('process-payment', async () => {
  return await paymentService.charge(amount);
});
```

------
#### [ Python ]

```
result = context.step(
    lambda _: payment_service.charge(amount),
    name='process-payment'
)
```

------
#### [ Java (Preview) ]

```
var result = context.step("process-payment", Payment.class, 
    () -> paymentService.charge(amount)
);
```

------

Les étapes prennent en charge les stratégies de nouvelle tentative configurables, la sémantique d'exécution (at-most-once ou at-least-once) et la sérialisation personnalisée.

### Éléments d’attente
<a name="durable-sdk-op-wait"></a>

Suspend l'exécution pendant une durée spécifiée sans consommer de ressources informatiques. Le SDK crée un point de contrôle, met fin à l'invocation de la fonction et planifie la reprise. Lorsque l'attente est terminée, Lambda invoque à nouveau votre fonction et le SDK rejoue jusqu'au point d'attente avant de continuer.

------
#### [ TypeScript ]

```
// Wait 1 hour without charges
await context.wait({ seconds: 3600 });
```

------
#### [ Python ]

```
# Wait 1 hour without charges
context.wait(3600)
```

------
#### [ Java (Preview) ]

```
// Wait 1 hour without charges
context.wait(Duration.ofHours(1));
```

------

### Rappels
<a name="durable-sdk-op-callback"></a>

Les rappels permettent à votre fonction de faire une pause et d'attendre que des systèmes externes fournissent une entrée. Lorsque vous créez un rappel, le SDK génère un identifiant de rappel unique et crée un point de contrôle. Votre fonction est ensuite suspendue (met fin à l'invocation) sans frais de calcul. Les systèmes externes soumettent les résultats de rappel à l'aide du `SendDurableExecutionCallbackSuccess` ou `SendDurableExecutionCallbackFailure` Lambda APIs. Lorsqu'un rappel est soumis, Lambda appelle à nouveau votre fonction, le SDK rejoue jusqu'au point de rappel et votre fonction continue avec le résultat du rappel.

Le SDK propose deux méthodes pour utiliser les rappels :

**CreateCallback :** crée un rappel et renvoie à la fois une promesse et un identifiant de rappel. Vous envoyez l'ID de rappel à un système externe, qui soumet le résultat à l'aide de l'API Lambda.

------
#### [ TypeScript ]

```
const [promise, callbackId] = await context.createCallback('approval', {
  timeout: { hours: 24 }
});

await sendApprovalRequest(callbackId, requestData);
const approval = await promise;
```

------
#### [ Python ]

```
callback = context.create_callback(
    name='approval',
    config=CallbackConfig(timeout_seconds=86400)
)

context.step(
    lambda _: send_approval_request(callback.callback_id),
    name='send_request'
)

approval = callback.result()
```

------
#### [ Java (Preview) ]

```
var config = CallbackConfig.builder(Duration.ofHours(24)).timeout()

var callback = context.createCallback("approval", String.class, config);

context.step("send-request", String.class, () -> {
    notificationService.sendApprovalRequest(callback.callbackId(), requestData);
    return "request-sent";
});

// Blocks until the callback finishes or times out
String approval = callback.get();
```

------

**waitForCallback:** simplifie la gestion des rappels en combinant la création et la soumission des rappels en une seule opération. Le SDK crée le rappel, exécute votre fonction de soumission avec l'ID de rappel et attend le résultat.

------
#### [ TypeScript ]

```
const result = await context.waitForCallback(
  'external-api',
  async (callbackId, ctx) => {
    await submitToExternalAPI(callbackId, requestData);
  },
  { timeout: { minutes: 30 } }
);
```

------
#### [ Python ]

```
result = context.wait_for_callback(
    lambda callback_id: submit_to_external_api(callback_id, request_data),
    name='external-api',
    config=WaitForCallbackConfig(timeout_seconds=1800)
)
```

------
#### [ Java (Preview) ]

waitForCallback est toujours en développement pour Java.

------

Configurez les délais d'attente pour empêcher les fonctions d'attendre indéfiniment. Si un rappel expire, le SDK renvoie un `CallbackError` et votre fonction peut gérer le cas de délai d'expiration. Utilisez les délais d'expiration du rythme cardiaque pour les rappels de longue durée afin de détecter les cas où les systèmes externes cessent de répondre.

Utilisez des rappels pour les human-in-the-loop flux de travail, l'intégration de systèmes externes, les réponses Webhook ou tout autre scénario dans lequel l'exécution doit être interrompue pour une entrée externe.

### Exécution en parallèle
<a name="durable-sdk-op-parallel"></a>

Exécute plusieurs opérations simultanément avec un contrôle de simultanéité optionnel. Le SDK gère l'exécution parallèle, crée des points de contrôle pour chaque opération et gère les défaillances conformément à votre politique d'achèvement.

------
#### [ TypeScript ]

```
const results = await context.parallel([
  async (ctx) => ctx.step('task1', async () => processTask1()),
  async (ctx) => ctx.step('task2', async () => processTask2()),
  async (ctx) => ctx.step('task3', async () => processTask3())
]);
```

------
#### [ Python ]

```
results = context.parallel(
    lambda ctx: ctx.step(lambda _: process_task1(), name='task1'),
    lambda ctx: ctx.step(lambda _: process_task2(), name='task2'),
    lambda ctx: ctx.step(lambda _: process_task3(), name='task3')
)
```

------
#### [ Java (Preview) ]

Parallel est toujours en développement pour Java.

------

`parallel`À utiliser pour exécuter simultanément des opérations indépendantes.

### Map
<a name="durable-sdk-op-map"></a>

Exécutez simultanément une opération sur chaque élément d'un tableau avec un contrôle de simultanéité optionnel. Le SDK gère les exécutions simultanées, crée des points de contrôle pour chaque opération et gère les défaillances conformément à votre politique d'achèvement.

------
#### [ TypeScript ]

```
const results = await context.map(itemArray, async (ctx, item, index) =>
  ctx.step('task', async () => processItem(item, index))
);
```

------
#### [ Python ]

```
results = context.map(
    item_array,
    lambda ctx, item, index: ctx.step(
        lambda _: process_item(item, index),
        name='task'
    )
)
```

------
#### [ Java (Preview) ]

La carte est toujours en cours de développement pour Java.

------

`map`À utiliser pour traiter des tableaux avec contrôle de simultanéité.

### Contextes relatifs aux enfants
<a name="durable-sdk-op-child-context"></a>

Crée un contexte d'exécution isolé pour les opérations de regroupement. Les contextes enfants possèdent leur propre journal des points de contrôle et peuvent contenir plusieurs étapes, temps d'attente et autres opérations. Le SDK traite l'ensemble du contexte de l'enfant comme une unité unique pour les nouvelles tentatives et la restauration.

Utilisez des contextes enfants pour organiser des flux de travail complexes, implémenter des sous-flux de travail ou isoler les opérations qui doivent être réessayées ensemble.

------
#### [ TypeScript ]

```
const result = await context.runInChildContext(
  'batch-processing',
  async (childCtx) => {
    return await processBatch(childCtx, items);
  }
);
```

------
#### [ Python ]

```
result = context.run_in_child_context(
    lambda child_ctx: process_batch(child_ctx, items),
    name='batch-processing'
)
```

------
#### [ Java (Preview) ]

```
var result = context.runInChildContext(
    "batch-processing", 
    String.class, 
    childCtx -> process_batch(childCtx, items)
);
```

------

Le mécanisme de rediffusion exige que les opérations durables soient effectuées dans un ordre déterministe. En utilisant plusieurs contextes enfants, plusieurs flux de travail peuvent être exécutés simultanément, et le déterminisme s'applique séparément dans chaque contexte. Cela vous permet de créer des fonctions hautes performances qui utilisent efficacement plusieurs cœurs de processeur.

Par exemple, imaginons que nous démarrions deux contextes enfants, A et B. Lors de l'invocation initiale, les étapes des contextes étaient exécutées dans cet ordre, les étapes « A » s'exécutant simultanément avec les étapes « B » : A1, B1, B2, A2, A3. Lors de la rediffusion, le chronométrage est beaucoup plus rapide car les résultats sont extraits du journal des points de contrôle et les étapes sont parcourues dans un ordre différent : B1, A1, A2, B2, A3. Comme les étapes « A » ont été rencontrées dans le bon ordre (A1, A2, A3) et que les étapes « B » ont été rencontrées dans le bon ordre (B1, B2), le besoin de déterminisme a été correctement satisfait.

### Attentes conditionnelles
<a name="durable-sdk-op-wait-condition"></a>

Recherche une condition avec pointage automatique entre les tentatives. Le SDK exécute votre fonction de vérification, crée un point de contrôle avec le résultat, attend selon votre stratégie et répète jusqu'à ce que la condition soit remplie.

------
#### [ TypeScript ]

```
const result = await context.waitForCondition(
  async (state, ctx) => {
    const status = await checkJobStatus(state.jobId);
    return { ...state, status };
  },
  {
    initialState: { jobId: 'job-123', status: 'pending' },
    waitStrategy: (state) => 
      state.status === 'completed' 
        ? { shouldContinue: false }
        : { shouldContinue: true, delay: { seconds: 30 } }
  }
);
```

------
#### [ Python ]

```
result = context.wait_for_condition(
    lambda state, ctx: check_job_status(state['jobId']),
    config=WaitForConditionConfig(
        initial_state={'jobId': 'job-123', 'status': 'pending'},
        wait_strategy=lambda state, attempt: 
            {'should_continue': False} if state['status'] == 'completed'
            else {'should_continue': True, 'delay': 30}
    )
)
```

------
#### [ Java (Preview) ]

waitForCondition est toujours en développement pour Java.

------

`waitForCondition`À utiliser pour interroger des systèmes externes, attendre que les ressources soient prêtes ou implémenter une nouvelle tentative avec interruption.

### Invocation de fonctions
<a name="durable-sdk-op-invoke"></a>

Invoque une autre fonction Lambda et attend son résultat. Le SDK crée un point de contrôle, invoque la fonction cible et reprend votre fonction une fois l'invocation terminée. Cela permet la composition des fonctions et la décomposition du flux de travail.

------
#### [ TypeScript ]

```
const result = await context.invoke(
  'invoke-processor',
  'arn:aws:lambda:us-east-1:123456789012:function:processor:1',
  { data: inputData }
);
```

------
#### [ Python ]

```
result = context.invoke(
    'arn:aws:lambda:us-east-1:123456789012:function:processor:1',
    {'data': input_data},
    name='invoke-processor'
)
```

------
#### [ Java (Preview) ]

```
var result = context.invoke(
    "invoke-processor", 
    "arn:aws:lambda:us-east-1:123456789012:function:processor:1",
    inputData,
    Result.class, 
    InvokeConfig.builder().build()
);
```

------

## Comment mesure-t-on la durabilité des opérations
<a name="durable-operations-checkpoint-consumption"></a>

Chaque opération durable que vous effectuez `DurableContext` crée des points de contrôle pour suivre la progression de l'exécution et stocker les données d'état. Ces opérations sont facturées en fonction de leur utilisation, et les points de contrôle peuvent contenir des données qui contribuent à vos coûts d'écriture et de conservation des données. Les données stockées incluent les données relatives aux événements d'invocation, les charges utiles renvoyées par les étapes et les données transmises lors de l'exécution des rappels. Comprendre comment la durabilité des opérations est mesurée vous permet d'estimer les coûts d'exécution et d'optimiser vos flux de travail. Pour plus de détails sur la tarification, consultez la page de [tarification de Lambda](https://aws.amazon.com/lambda/pricing/).

La taille de la charge utile fait référence à la taille des données sérialisées qu'une opération durable persiste. Les données sont mesurées en octets et leur taille peut varier en fonction du sérialiseur utilisé par l'opération. La charge utile d'une opération peut être le résultat lui-même en cas d'achèvement réussi, ou l'objet d'erreur sérialisé en cas d'échec de l'opération.

### Opérations de base
<a name="durable-operations-basic"></a>

Les opérations de base sont les éléments fondamentaux des fonctions durables :


| Opération | Chronométrage des points de contrôle | Nombre d'opérations | Les données ont persisté | 
| --- | --- | --- | --- | 
| Exécution | Démarré(e) | 1 | Taille de la charge utile d'entrée | 
| Exécution | Terminé (Succeeded/Failed/Stopped) | 0 | Taille de la charge utile de sortie | 
| Step (Étape) | Retry/Succeeded/Failed | 10 \$1 Aucune nouvelle tentative | Taille de la charge utile renvoyée à chaque tentative | 
| Attente | Démarré(e) | 1 | N/A | 
| WaitForCondition | Chaque tentative de sondage | \$1 1 x N sondages | Taille de la charge utile renvoyée à chaque tentative de sondage | 
| Nouvelle tentative au niveau de l'invocation | Démarré(e) | 1 | Charge utile pour l'objet d'erreur | 

### Opérations de rappel
<a name="durable-operations-callbacks"></a>

Les opérations de rappel permettent à votre fonction de faire une pause et d'attendre que des systèmes externes fournissent une entrée. Ces opérations créent des points de contrôle lorsque le rappel est créé et lorsqu'il est terminé :


| Opération | Chronométrage des points de contrôle | Nombre d'opérations | Les données ont persisté | 
| --- | --- | --- | --- | 
| CreateCallback | Démarré(e) | 1 | N/A | 
| Exécution du rappel via un appel d'API | Terminé | 0 | Charge utile de rappel | 
| WaitForCallback | Démarré(e) | 3 \$1 N tentatives (contexte \$1 rappel \$1 étape) | Charges utiles renvoyées par les tentatives d'étape de l'expéditeur, plus deux copies de la charge utile de rappel | 

### Opérations composées
<a name="durable-operations-compound"></a>

Les opérations composées combinent plusieurs opérations durables pour gérer des modèles de coordination complexes tels que l'exécution parallèle, le traitement de tableaux et les contextes imbriqués :


| Opération | Chronométrage des points de contrôle | Nombre d'opérations | Les données ont persisté | 
| --- | --- | --- | --- | 
| Parallèle | Démarré(e) | 1 \$1 N branches (1 contexte parent \$1 N contextes enfants) | Jusqu'à deux copies de la taille de charge utile renvoyée par chaque branche, plus les statuts de chaque branche | 
| Map | Démarré(e) | 1 \$1 N branches (1 contexte parent \$1 N contextes enfants) | Jusqu'à deux copies de la taille de charge utile renvoyée par itération, plus les statuts de chaque itération | 
| Des aides à la promesse | Terminé | 1 | Taille de la charge utile renvoyée par la promesse | 
| RunInChildContext | Succès/Echec | 1 | Taille de la charge utile renvoyée par le contexte enfant | 

Pour les contextes, tels que ceux issus `runInChildContext` ou utilisés en interne par des opérations composées, les résultats inférieurs à 256 Ko sont directement contrôlés. Les résultats les plus importants ne sont pas stockés ; ils sont reconstruits lors de la rediffusion en retraitant les opérations du contexte.

# Runtimes pris en charge pour des fonctions durables
<a name="durable-supported-runtimes"></a>

Des fonctions durables sont disponibles pour certains environnements d'exécution gérés et pour les images de conteneur OCI pour une flexibilité accrue des versions d'exécution. Vous pouvez créer des fonctions durables pour Node.js et Python à l'aide d'environnements d'exécution gérés directement dans la console ou par programmation. infrastructure-as-code Les fonctions durables de Java (version préliminaire) ne peuvent actuellement être déployées que via des images de conteneur.

## Runtimes gérés par Lambda
<a name="durable-managed-runtimes"></a>

Les environnements d'exécution gérés suivants prennent en charge les fonctions durables lorsque vous créez des fonctions dans la console Lambda ou que vous utilisez AWS CLI le paramètre with `--durable-config '{"ExecutionTimeout": 3600, "RetentionPeriodInDays": 7}'` the. [Pour des informations complètes sur les environnements d'exécution Lambda, consultez la section Runtimes Lambda.](lambda-runtimes.md)


| Language | Environnement d’exécution | 
| --- | --- | 
| Node.js | nodejs22.x | 
| Node.js | nodejs24.x | 
| Python | python3.13 | 
| Python | python3,14 | 

**Note**  
Les environnements d'exécution Lambda incluent le SDK d'exécution durable pour les tests et le développement. Toutefois, nous vous recommandons d'inclure le SDK dans votre package de déploiement pour la production. Cela garantit la cohérence des versions et évite les mises à jour d'exécution potentielles susceptibles d'affecter le comportement de votre fonction.

### Node.js
<a name="durable-runtime-nodejs"></a>

Installez le SDK dans votre projet Node.js :

```
npm install @aws/durable-execution-sdk-js
```

Le SDK prend en charge JavaScript et. TypeScript Pour les TypeScript projets, le SDK inclut des définitions de type.

### Python
<a name="durable-runtime-python"></a>

Installez le SDK dans votre projet Python :

```
pip install aws-durable-execution-sdk-python
```

Le SDK Python utilise des méthodes synchrones et n'en nécessite pas. `async/await`

### Java (version préliminaire)
<a name="durable-runtime-java"></a>

Ajoutez une dépendance à `pom.xml` :

```
<dependency>
    <groupId>software.amazon.lambda.durable</groupId>
    <artifactId>aws-durable-execution-sdk-java</artifactId>
    <version>VERSION</version>
</dependency>
```

Installez le SDK dans votre projet Java :

```
mvn install
```

Une version préliminaire du SDK Java est disponible. Les opérations waitForCondition waitForCallback, parallel et map sont toujours en cours de développement.

## Images de conteneurs
<a name="durable-container-images"></a>

Vous pouvez utiliser des fonctions durables avec des images de conteneur pour prendre en charge des versions d'exécution supplémentaires ou des configurations d'exécution personnalisées. Les images de conteneur vous permettent d'utiliser des versions d'exécution non disponibles en tant que moteurs d'exécution gérés ou de personnaliser votre environnement d'exécution.

Pour créer une fonction durable à l'aide d'une image de conteneur :

1. Création d'un Dockerfile basé sur une image de base Lambda

1. Installez le SDK d'exécution durable dans votre conteneur

1. Créez et transférez l'image du conteneur vers Amazon Elastic Container Registry

1. Créez la fonction Lambda à partir de l'image du conteneur avec l'exécution durable activée

### Exemple de conteneur
<a name="durable-container-python"></a>

Créez un Dockerfile :

------
#### [ Python ]

Créez un Dockerfile pour Python 3.11 :

```
FROM public.ecr.aws/lambda/python:3.11

# Copy requirements file
COPY requirements.txt ${LAMBDA_TASK_ROOT}/

# Install dependencies including durable SDK
RUN pip install -r requirements.txt

# Copy function code
COPY lambda_function.py ${LAMBDA_TASK_ROOT}/

# Set the handler
CMD [ "lambda_function.handler" ]
```

Créez un `requirements.txt` fichier :

```
aws-durable-execution-sdk-python
```

------
#### [ Java (Preview) ]

Créez un Dockerfile pour Java 25 :

```
FROM --platform=linux/amd64 public.ecr.aws/lambda/java:25

# Install Maven
RUN dnf install -y maven

WORKDIR /var/task

# Copy Maven configuration and source code
COPY pom.xml .
COPY src ./src

# Build
RUN mvn clean package -DskipTests

# Move JAR to lib directory
RUN mv target/*.jar lib/

# Set the handler
CMD ["src.path.to.lambdaFunction::handler"]
```

------

Créez et publiez l'image :

```
# Build the image
docker build -t my-durable-function .

# Tag for ECR
docker tag my-durable-function:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-durable-function:latest

# Push to ECR
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-durable-function:latest
```

Créez la fonction avec l'exécution durable activée :

```
aws lambda create-function \
  --function-name myDurableFunction \
  --package-type Image \
  --code ImageUri=123456789012.dkr.ecr.us-east-1.amazonaws.com/my-durable-function:latest \
  --role arn:aws:iam::123456789012:role/lambda-execution-role \
  --durable-config '{"ExecutionTimeout": 3600, "RetentionPeriodInDays": 7}'
```

Pour plus d'informations sur l'utilisation d'images de conteneur avec Lambda, consultez la section Création d'images de [conteneur Lambda dans le guide du développeur](https://docs.aws.amazon.com/lambda/latest/dg/images-create.html) Lambda.

## Considérations relatives à l’exécution
<a name="durable-runtime-considerations"></a>

**Gestion des versions du SDK :** incluez le SDK d'exécution durable dans votre package de déploiement ou votre image de conteneur. Cela garantit que votre fonction utilise une version spécifique du SDK et n'est pas affectée par les mises à jour d'exécution. Épinglez les versions du SDK dans votre `package.json` ou `requirements.txt` pour contrôler lors de la mise à niveau.

**Mises à jour d'exécution :** AWS met à jour les environnements d'exécution gérés pour inclure des correctifs de sécurité et des corrections de bogues. Ces mises à jour peuvent inclure de nouvelles versions du SDK. Pour éviter tout comportement inattendu, incluez le SDK dans votre package de déploiement et testez-le de manière approfondie avant de le déployer en production.

**Taille de l'image du conteneur :** les images du conteneur ont une taille non compressée maximale de 10 Go. Le SDK d'exécution durable ajoute une taille minimale à votre image. Optimisez votre conteneur en utilisant des builds en plusieurs étapes et en supprimant les dépendances inutiles.

**Performances de démarrage à froid :** les images de conteneur peuvent avoir des temps de démarrage à froid plus longs que les temps d'exécution gérés. Le SDK d'exécution durable a un impact minimal sur les performances de démarrage à froid. Utilisez la simultanéité provisionnée si la latence de démarrage à froid est essentielle pour votre application.

# Invoquer des fonctions Lambda durables
<a name="durable-invoking"></a>

Les fonctions Lambda durables prennent en charge les mêmes méthodes d'appel que les fonctions Lambda standard. Vous pouvez appeler des fonctions durables de manière synchrone, asynchrone ou via des mappages de sources d'événements. Le processus d'invocation est identique aux fonctions standard, mais les fonctions durables offrent des fonctionnalités supplémentaires pour les exécutions de longue durée et la gestion automatique des états.

## Méthodes d'invocation
<a name="durable-invoking-methods"></a>

**Invocation synchrone :** invoquez une fonction durable et attendez la réponse. Les appels synchrones sont limités par le Lambda à 15 minutes (ou moins, selon la fonction configurée et le délai d'exécution). Utilisez l'invocation synchrone lorsque vous avez besoin de résultats immédiats ou lorsque vous intégrez APIs des services qui attendent une réponse. Vous pouvez utiliser les opérations d'attente pour un calcul efficace sans perturber l'appelant : l'invocation attend la fin de l'exécution durable complète. [Pour les démarrages d'exécution idempotents, utilisez le paramètre de nom d'exécution tel que décrit dans Idempotentie.](durable-execution-idempotency.md)

```
aws lambda invoke \
  --function-name my-durable-function:1 \
  --cli-binary-format raw-in-base64-out \
  --payload '{"orderId": "12345"}' \
  response.json
```

**Invocation asynchrone :** mettez en file d'attente un événement pour qu'il soit traité sans attendre de réponse. Lambda place l'événement dans une file d'attente et y retourne immédiatement. Les invocations asynchrones prennent en charge des durées d'exécution allant jusqu'à 1 an. Utilisez l'invocation asynchrone pour les fire-and-forget scénarios ou lorsque le traitement peut avoir lieu en arrière-plan. [Pour les démarrages d'exécution idempotents, utilisez le paramètre de nom d'exécution tel que décrit dans Idempotentie.](durable-execution-idempotency.md)

```
aws lambda invoke \
  --function-name my-durable-function:1 \
  --invocation-type Event \
  --cli-binary-format raw-in-base64-out \
  --payload '{"orderId": "12345"}' \
  response.json
```

**Mappages de sources d'événements :** configurez Lambda pour appeler automatiquement votre fonction durable lorsque des enregistrements sont disponibles à partir de services basés sur des flux ou des files d'attente tels qu'Amazon SQS, Kinesis ou DynamoDB. Les mappages de sources d'événements interrogent la source d'événements et invoquent votre fonction avec des lots d'enregistrements. Pour plus de détails sur l'utilisation des mappages de sources d'événements avec des fonctions durables, y compris les limites de durée d'exécution, voir [Mappages de sources d'événements avec des fonctions durables.](durable-invoking-esm.md)

[Pour obtenir des informations complètes sur chaque méthode d'appel, consultez les sections Invocation [synchrone et Invocation asynchrone](invocation-sync.md).](invocation-async.md)

**Note**  
Les fonctions durables prennent en charge les files d'attente en lettres mortes (DLQs) pour la gestion des erreurs, mais ne prennent pas en charge les destinations Lambda. Configurez un DLQ pour capturer les enregistrements des appels ayant échoué.

## ARNs Exigence qualifiée
<a name="durable-invoking-qualified-arns"></a>

Les fonctions durables nécessitent des identifiants qualifiés pour l'invocation. Vous devez invoquer des fonctions durables à l'aide d'un numéro de version, d'un alias ou`$LATEST`. Vous pouvez utiliser un ARN qualifié complet ou un nom de fonction avec version/alias suffixe. Vous ne pouvez pas utiliser un identifiant non qualifié (sans version ni suffixe d'alias).

**Invocations valides :**

```
# Using full ARN with version number
arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:1

# Using full ARN with alias
arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:prod

# Using full ARN with $LATEST
arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:$LATEST

# Using function name with version number
my-durable-function:1

# Using function name with alias
my-durable-function:prod
```

**Invocations non valides :**

```
# Unqualified ARN (not allowed)
arn:aws:lambda:us-east-1:123456789012:function:my-durable-function

# Unqualified function name (not allowed)
my-durable-function
```

Cette exigence garantit que les exécutions durables restent cohérentes tout au long de leur cycle de vie. Lorsqu'une exécution durable démarre, elle est associée à la version de fonction spécifique. Si votre fonction s'arrête et reprend des heures ou des jours plus tard, Lambda invoque la même version qui a démarré l'exécution, garantissant ainsi la cohérence du code dans l'ensemble du flux de travail.

**Bonne pratique**  
Utilisez plutôt `$LATEST` des versions numérotées ou des alias pour produire des fonctions durables. Les versions numérotées sont immuables et permettent une rediffusion déterministe. Les alias fournissent éventuellement une référence stable que vous pouvez mettre à jour pour pointer vers de nouvelles versions sans modifier le code d'appel. Lorsque vous mettez à jour un alias, les nouvelles exécutions utilisent la nouvelle version, tandis que les exécutions en cours reprennent leur version d'origine. Vous pouvez l'utiliser `$LATEST` pour le prototypage ou pour raccourcir les délais de déploiement pendant le développement, en sachant que les exécutions risquent de ne pas se reproduire correctement (voire d'échouer) si le code sous-jacent change pendant les exécutions.

## Comprendre le cycle de vie d'exécution
<a name="durable-invoking-execution-lifecycle"></a>

Lorsque vous appelez une fonction durable, Lambda crée une exécution durable qui peut couvrir plusieurs invocations de fonction :

1. **Invocation initiale :** votre demande d'invocation crée une nouvelle exécution durable. Lambda attribue un ID d'exécution unique et lance le traitement.

1. **Exécution et pointage : lorsque** votre fonction exécute des opérations durables, le SDK crée des points de contrôle qui permettent de suivre la progression.

1. **Suspension (si nécessaire) :** si votre fonction utilise des temps d'attente prolongés, tels que `wait` des tentatives ou des tentatives automatiques`waitForCallback`, Lambda suspend l'exécution et arrête de facturer le temps de calcul.

1. **Reprise :** au moment de reprendre (y compris après de nouvelles tentatives), Lambda invoque à nouveau votre fonction. Le SDK rejoue le journal des points de contrôle et continue à partir de l'endroit où l'exécution a été interrompue.

1. **Achèvement :** lorsque votre fonction renvoie un résultat final ou renvoie une erreur non gérée, l'exécution durable est terminée.

Pour les invocations synchrones, l'appelant attend la fin complète de l'exécution durable, y compris les opérations d'attente. Si l'exécution dépasse le délai d'invocation (15 minutes ou moins), l'invocation expire. Pour les appels asynchrones, Lambda revient immédiatement et l'exécution se poursuit indépendamment. Utilisez l'exécution durable APIs pour suivre l'état d'exécution et obtenir les résultats finaux.

## Invocation depuis le code de l'application
<a name="durable-invoking-with-sdk"></a>

Utilisez le AWS SDKs pour invoquer des fonctions durables à partir du code de votre application. Le processus d'invocation est identique aux fonctions standard :

------
#### [ TypeScript ]

```
import { LambdaClient, InvokeCommand } from '@aws-sdk/client-lambda';

const client = new LambdaClient({});

// Synchronous invocation
const response = await client.send(new InvokeCommand({
  FunctionName: 'arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:1',
  Payload: JSON.stringify({ orderId: '12345' })
}));

const result = JSON.parse(Buffer.from(response.Payload!).toString());

// Asynchronous invocation
await client.send(new InvokeCommand({
  FunctionName: 'arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:1',
  InvocationType: 'Event',
  Payload: JSON.stringify({ orderId: '12345' })
}));
```

------
#### [ Python ]

```
import boto3
import json

client = boto3.client('lambda')

# Synchronous invocation
response = client.invoke(
    FunctionName='arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:1',
    Payload=json.dumps({'orderId': '12345'})
)

result = json.loads(response['Payload'].read())

# Asynchronous invocation
client.invoke(
    FunctionName='arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:1',
    InvocationType='Event',
    Payload=json.dumps({'orderId': '12345'})
)
```

------

## Invocations enchaînées
<a name="durable-invoking-chained"></a>

Les fonctions durables peuvent invoquer d'autres fonctions durables et non durables à l'aide de l'`invoke`opération de`DurableContext`. Cela crée un appel enchaîné dans lequel la fonction appelante attend (suspend) la fin de la fonction invoquée :

------
#### [ TypeScript ]

```
export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // Invoke another durable function and wait for result
    const result = await context.invoke(
      'process-order',
      'arn:aws:lambda:us-east-1:123456789012:function:order-processor:1',
      { orderId: event.orderId }
    );
    
    return { statusCode: 200, body: JSON.stringify(result) };
  }
);
```

------
#### [ Python ]

```
@durable_execution
def handler(event, context: DurableContext):
    # Invoke another durable function and wait for result
    result = context.invoke(
        'arn:aws:lambda:us-east-1:123456789012:function:order-processor:1',
        {'orderId': event['orderId']},
        name='process-order'
    )
    
    return {'statusCode': 200, 'body': json.dumps(result)}
```

------

Les invocations enchaînées créent un point de contrôle dans la fonction d'appel. Si la fonction appelante est interrompue, elle repart du point de contrôle avec le résultat de la fonction invoquée, sans la réinvoquer.

**Note**  
Les invocations chaînées entre comptes ne sont pas prises en charge. La fonction invoquée doit se trouver dans le même AWS compte que la fonction appelante.

# Mappages de sources d'événements dotés de fonctions durables
<a name="durable-invoking-esm"></a>

Les fonctions durables fonctionnent avec tous les mappages de sources d'événements Lambda. Configurez les mappages de sources d'événements pour les fonctions durables de la même manière que vous les configurez pour les fonctions standard. Les mappages de sources d'événements interrogent automatiquement des sources d'événements telles qu'Amazon SQS, Kinesis et DynamoDB Streams, et invoquent votre fonction à l'aide de lots d'enregistrements.

Les mappages de sources d'événements sont utiles pour les fonctions durables qui traitent des flux ou des files d'attente avec des flux de travail complexes en plusieurs étapes. Par exemple, vous pouvez créer une fonction durable qui traite les messages Amazon SQS avec de nouvelles tentatives, des appels d'API externes et des approbations humaines.

## Comment les mappages de sources d'événements invoquent des fonctions durables
<a name="durable-esm-invocation-behavior"></a>

Les mappages de sources d'événements invoquent des fonctions durables de manière synchrone, en attendant la fin de l'exécution durable complète avant de traiter le lot suivant ou de marquer les enregistrements comme traités. Si le temps d'exécution durable total dépasse 15 minutes, l'exécution expire et échoue. Le mappage de la source d'événements reçoit une exception de délai d'attente et la gère en fonction de sa configuration de nouvelle tentative.

## Limite d'exécution de 15 minutes
<a name="durable-esm-duration-limit"></a>

Lorsque des fonctions durables sont invoquées par des mappages de sources d'événements, la durée totale d'exécution durable ne peut pas dépasser 15 minutes. Cette limite s'applique à l'ensemble de l'exécution durable, du début à la fin, et pas uniquement aux invocations de fonctions individuelles.

Cette limite de 15 minutes est distincte du délai d'expiration de la fonction Lambda (également 15 minutes maximum). La fonction timeout contrôle la durée d'exécution de chaque invocation individuelle, tandis que le délai d'exécution durable contrôle le temps total écoulé entre le début et la fin de l'exécution.

**Exemples de scénarios :**
+ **Valable :** une fonction durable traite un message Amazon SQS en trois étapes, chacune prenant 2 minutes, puis attend 5 minutes avant de terminer une dernière étape. Durée totale d'exécution : 11 minutes. Cela fonctionne car le total est inférieur à 15 minutes.
+ **Non valide :** une fonction durable traite un message Amazon SQS, effectue le traitement initial en 2 minutes, puis attend un rappel externe pendant 20 minutes avant de terminer. Durée totale d'exécution : 22 minutes. Cela dépasse la limite de 15 minutes et échouera.
+ **Non valide :** une fonction durable traite un enregistrement Kinesis avec plusieurs opérations d'attente d'une durée totale de 30 minutes entre les étapes. Même si chaque invocation individuelle se termine rapidement, le temps d'exécution total dépasse 15 minutes.

**Important**  
Configurez votre délai d'exécution durable à 15 minutes ou moins lorsque vous utilisez des mappages de sources d'événements, sinon la création du mappage des sources d'événements échouera. Si votre flux de travail nécessite des temps d'exécution plus longs, utilisez le modèle de fonction intermédiaire décrit ci-dessous.

## Configuration des mappages de sources d'événements
<a name="durable-esm-configuration"></a>

Configurez les mappages de sources d'événements pour des fonctions durables à l'aide de la console Lambda AWS CLI, ou. AWS SDKs Toutes les propriétés standard de mappage des sources d'événements s'appliquent aux fonctions durables :

```
aws lambda create-event-source-mapping \
  --function-name arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:1 \
  --event-source-arn arn:aws:sqs:us-east-1:123456789012:my-queue \
  --batch-size 10 \
  --maximum-batching-window-in-seconds 5
```

N'oubliez pas d'utiliser un ARN qualifié (avec numéro de version ou alias) lors de la configuration des mappages de sources d'événements pour des fonctions durables.

## Gestion des erreurs avec les mappages de sources d'événements
<a name="durable-esm-error-handling"></a>

Les mappages de sources d'événements fournissent une gestion des erreurs intégrée qui fonctionne avec des fonctions durables :
+ **Comportement de nouvelle tentative :** si l'appel initial échoue, le mappage de la source d'événements réessaie conformément à sa configuration de nouvelle tentative. Configurez le nombre maximal de tentatives et les intervalles entre les tentatives en fonction de vos besoins.
+ Files d'attente de **lettres mortes : configurez une file d'attente** de lettres mortes pour capturer les enregistrements qui échouent après chaque nouvelle tentative. Cela empêche la perte de messages et permet une inspection manuelle des enregistrements défaillants.
+ **Défaillances partielles par lots :** pour Amazon SQS et Kinesis, utilisez le rapport d'échec partiel des lots pour traiter les enregistrements individuellement et réessayez uniquement les enregistrements ayant échoué.
+ **Couper en deux en cas d'erreur :** pour Kinesis et DynamoDB Streams, activez la division en deux en cas d'erreur pour diviser les lots ayant échoué et isoler les enregistrements problématiques.

**Note**  
Les fonctions durables prennent en charge les files d'attente en lettres mortes (DLQs) pour la gestion des erreurs, mais ne prennent pas en charge les destinations Lambda. Configurez un DLQ pour capturer les enregistrements des appels ayant échoué.

Pour des informations complètes sur la gestion des erreurs de mappage des sources d'événements, consultez la section [Mappages des sources d'événements](invocation-eventsourcemapping.md).

## Utilisation d'une fonction intermédiaire pour les flux de travail de longue durée
<a name="durable-esm-intermediary-function"></a>

Si votre flux de travail nécessite plus de 15 minutes, utilisez une fonction Lambda standard intermédiaire entre le mappage de la source d'événements et votre fonction durable. La fonction intermédiaire reçoit les événements du mappage de la source d'événements et invoque la fonction durable de manière asynchrone, supprimant ainsi la limite d'exécution de 15 minutes.

Ce modèle dissocie le modèle d'appel synchrone du mappage des sources d'événements du modèle d'exécution à long terme de la fonction durable. Le mappage de la source d'événements invoque la fonction intermédiaire, qui revient rapidement après le démarrage de l'exécution durable. La fonction durable fonctionne ensuite indépendamment aussi longtemps que nécessaire (jusqu'à 1 an).

### Architecture
<a name="durable-esm-intermediary-architecture"></a>

Le modèle de fonction intermédiaire utilise trois composants :

1. **Cartographie de la source d'événements :** interroge la source de l'événement (Amazon SQS, Kinesis, DynamoDB Streams) et invoque la fonction intermédiaire de manière synchrone avec des lots d'enregistrements.

1. **Fonction intermédiaire : fonction** Lambda standard qui reçoit les événements du mappage des sources d'événements, valide et transforme les données si nécessaire, et invoque la fonction durable de manière asynchrone. Cette fonction s'exécute rapidement (généralement en moins d'une seconde) et redonne le contrôle au mappage des sources d'événements.

1. **Fonction durable :** traite l'événement selon une logique complexe en plusieurs étapes qui peut s'exécuter pendant de longues périodes. Invoqué de manière asynchrone, il n'est donc pas limité par la limite de 15 minutes.

### Mise en œuvre
<a name="durable-esm-intermediary-implementation"></a>

La fonction intermédiaire reçoit l'intégralité de l'événement à partir du mappage de la source d'événements et invoque la fonction durable de manière asynchrone. Utilisez le paramètre du nom d'exécution pour vous assurer que l'exécution idempotente démarre, empêchant ainsi le traitement dupliqué si le mappage de la source d'événements tente à nouveau :

------
#### [ TypeScript ]

```
import { LambdaClient, InvokeCommand } from '@aws-sdk/client-lambda';
import { SQSEvent } from 'aws-lambda';
import { createHash } from 'crypto';

const lambda = new LambdaClient({});

export const handler = async (event: SQSEvent) => {
  // Invoke durable function asynchronously with execution name
  await lambda.send(new InvokeCommand({
    FunctionName: 'arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:1',
    InvocationType: 'Event',
    Payload: JSON.stringify({
      executionName: event.Name,
      event: event
    })
  }));
  
  return { statusCode: 200 };
};
```

------
#### [ Python ]

```
import boto3
import json
import hashlib

lambda_client = boto3.client('lambda')

def handler(event, context):  
    # Invoke durable function asynchronously with execution name
    lambda_client.invoke(
        FunctionName='arn:aws:lambda:us-east-1:123456789012:function:my-durable-function:1',
        InvocationType='Event',
        Payload=json.dumps({
            'executionName': execution_name,
            'event': event["name"]
        })
    )
    
    return {'statusCode': 200}
```

------

Pour garantir l'idempuissance de la fonction intermédiaire elle-même, utilisez [Powertools for AWS Lambda](https://docs.aws.amazon.com//powertools/) afin d'éviter les appels dupliqués de la fonction durable si le mappage de la source d'événements tente à nouveau la fonction intermédiaire.

La fonction durable reçoit la charge utile avec le nom de l'exécution et traite tous les enregistrements selon une logique de longue durée :

------
#### [ TypeScript ]

```
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js';

export const handler = withDurableExecution(
  async (payload: any, context: DurableContext) => {
    const sqsEvent = payload.event;
    
    // Process each record with complex, multi-step logic
    const results = await context.map(
      sqsEvent.Records,
      async (ctx, record) => {
        const validated = await ctx.step('validate', async () => {
          return validateOrder(JSON.parse(record.body));
        });
        
        // Wait for external approval (could take hours or days)
        const approval = await ctx.waitForCallback(
          'approval',
          async (callbackId) => {
            await requestApproval(callbackId, validated);
          },
          { timeout: { hours: 48 } }
        );
        
        // Complete processing
        return await ctx.step('complete', async () => {
          return completeOrder(validated, approval);
        });
      }
    );
    
    return { statusCode: 200, processed: results.getResults().length };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import durable_execution, DurableContext
from aws_durable_execution_sdk_python.config import Duration, WaitForCallbackConfig
from collections.abc import Sequence
import json

def validate_order(order_data: dict) -> dict:
    """Validate order data - always passes."""
    return order_data

def request_approval(callback_id: str, validated_order: dict) -> None:
    """Request approval for the order - always passes."""
    pass

def complete_order(validated_order: dict, approval_result: str) -> dict:
    """Complete the order processing - always passes."""
    return validated_order

@durable_execution
def lambda_handler(payload, context: DurableContext):
    sqs_event = payload['event']

    def process_record(
        ctx: DurableContext, 
        record: dict, 
        index: int, 
        items: Sequence[dict]
    ) -> dict:
        validated = ctx.step(
            lambda _: validate_order(json.loads(record['body'])),
            name=f'validate-{index}'
        )

        approval = ctx.wait_for_callback(
            submitter=lambda callback_id, wait_ctx: request_approval(callback_id, validated),
            name=f'approval-{index}',
            config=WaitForCallbackConfig(timeout=Duration.from_seconds(172800))
        )

        return ctx.step(
            lambda _: complete_order(validated, approval),
            name=f'complete-{index}'
        )

    results = context.map(
        inputs=sqs_event['Records'],
        func=process_record,
        name='process-records'
    )

    return {
        'statusCode': 200, 
        'started': results.started_count,
        'completed': results.success_count,
        'failed': results.failure_count,
        'total': results.total_count
    }
```

------

### Considérations clés
<a name="durable-esm-intermediary-tradeoffs"></a>

Ce modèle supprime la limite d'exécution de 15 minutes en dissociant le mappage de la source d'événements de l'exécution durable. La fonction intermédiaire revient immédiatement après le début de l'exécution durable, ce qui permet au mappage de la source d'événements de poursuivre le traitement. La fonction durable fonctionne ensuite indépendamment aussi longtemps que nécessaire.

La fonction intermédiaire réussit lorsqu'elle invoque la fonction durable, et non lorsque l'exécution durable est terminée. Si l'exécution durable échoue ultérieurement, le mappage de la source d'événements ne réessaiera pas car le lot a déjà été traité avec succès. Implémentez la gestion des erreurs dans la fonction durable et configurez des files d'attente contenant des lettres mortes en cas d'échec d'exécution.

Utilisez le paramètre du nom d'exécution pour vous assurer que l'exécution idempotente démarre. Si le mappage de la source d'événements tente à nouveau la fonction intermédiaire, la fonction durable ne démarrera pas une double exécution car le nom de l'exécution existe déjà.

## Sources d'événements prises en charge
<a name="durable-esm-supported-sources"></a>

Les fonctions durables prennent en charge toutes les sources d'événements Lambda qui utilisent des mappages de sources d'événements :
+ Files d'attente Amazon SQS (standard et FIFO)
+ Flux Kinesis
+ DynamoDB Streams
+ Amazon Managed Streaming for Apache Kafka (Amazon MSK)
+ Self-managed Apache Kafka
+ Amazon MQ (ActiveMQ et RabbitMQ)
+ Flux de modifications Amazon DocumentDB

Tous les types de sources d'événements sont soumis à la limite d'exécution durable de 15 minutes lors de l'invocation de fonctions durables.

# Réessais pour les fonctions durables de Lambda
<a name="durable-execution-sdk-retries"></a>

Les fonctions durables offrent des fonctionnalités de relance automatique qui permettent à vos applications de résister aux défaillances transitoires. Le SDK gère les nouvelles tentatives à deux niveaux : les tentatives par étapes en cas d'échec de la logique métier et les tentatives du backend en cas de défaillance de l'infrastructure.

## Étape 2 : Réessaie
<a name="durable-step-retries"></a>

Lorsqu'une exception non détectée se produit au cours d'une étape, le SDK réessaie automatiquement l'étape en fonction de la stratégie de nouvelle tentative configurée. Les tentatives d'étape sont des opérations ponctuelles qui permettent au SDK de suspendre l'exécution et de la reprendre ultérieurement sans perdre la progression.

### Étape 1 : comportement en cas de nouvelle tentative
<a name="durable-step-retry-behavior"></a>

Le tableau suivant décrit comment le SDK gère les exceptions par étapes :


| Scénario | Que se passe-t-il | Impact du mesurage | 
| --- | --- | --- | 
| Exception en cours avec les tentatives de nouvelle tentative restantes | Le SDK crée un point de contrôle pour la nouvelle tentative et suspend la fonction. Lors de l'appel suivant, l'étape réessaie avec le délai d'attente configuré. | 1 opération\$1erreur sur la taille de la charge utile | 
| Exception en cours, aucune nouvelle tentative n'ayant été tentée | L'étape échoue et génère une exception. Si le code de votre gestionnaire ne détecte pas cette exception, l'exécution complète échoue. | 1 opération\$1erreur sur la taille de la charge utile | 

Lorsqu'une étape doit être réessayée, le SDK vérifie l'état de nouvelle tentative et quitte l'appel Lambda si aucune autre tâche n'est en cours d'exécution. Cela permet au SDK d'implémenter des délais de temporisation sans consommer de ressources informatiques. La fonction reprend automatiquement après la période d'attente.

### Configuration des stratégies de nouvelle tentative
<a name="durable-step-retry-configuration"></a>

Configurez des stratégies de nouvelle tentative pour contrôler la manière dont les étapes gèrent les échecs. Vous pouvez spécifier le nombre maximum de tentatives, les intervalles d'attente et les conditions de réessai.

**Retard exponentiel avec un maximum de tentatives :**

------
#### [ TypeScript ]

```
const result = await context.step('call-api', async () => {
  const response = await fetch('https://api.example.com/data');
  if (!response.ok) throw new Error(`API error: ${response.status}`);
  return await response.json();
}, {
  retryStrategy: (error, attemptCount) => {
    if (attemptCount >= 5) {
      return { shouldRetry: false };
    }
    // Exponential backoff: 2s, 4s, 8s, 16s, 32s (capped at 300s)
    const delay = Math.min(2 * Math.pow(2, attemptCount - 1), 300);
    return { shouldRetry: true, delay: { seconds: delay } };
  }
});
```

------
#### [ Python ]

```
def retry_strategy(error, attempt_count):
    if attempt_count >= 5:
        return {'should_retry': False}
    # Exponential backoff: 2s, 4s, 8s, 16s, 32s (capped at 300s)
    delay = min(2 * (2 ** (attempt_count - 1)), 300)
    return {'should_retry': True, 'delay': delay}

result = context.step(
    lambda _: call_external_api(),
    name='call-api',
    config=StepConfig(retry_strategy=retry_strategy)
)
```

------

**Annulation à intervalle fixe :**

------
#### [ TypeScript ]

```
const orders = await context.step('query-orders', async () => {
  return await queryDatabase(event.userId);
}, {
  retryStrategy: (error, attemptCount) => {
    if (attemptCount >= 3) {
      return { shouldRetry: false };
    }
    return { shouldRetry: true, delay: { seconds: 5 } };
  }
});
```

------
#### [ Python ]

```
def retry_strategy(error, attempt_count):
    if attempt_count >= 3:
        return {'should_retry': False}
    return {'should_retry': True, 'delay': 5}

orders = context.step(
    lambda _: query_database(event['userId']),
    name='query-orders',
    config=StepConfig(retry_strategy=retry_strategy)
)
```

------

**Nouvelle tentative conditionnelle (réessayez uniquement en cas d'erreurs spécifiques) :**

------
#### [ TypeScript ]

```
const result = await context.step('call-rate-limited-api', async () => {
  const response = await fetch('https://api.example.com/data');
  
  if (response.status === 429) throw new Error('RATE_LIMIT');
  if (response.status === 504) throw new Error('TIMEOUT');
  if (!response.ok) throw new Error(`API_ERROR_${response.status}`);
  
  return await response.json();
}, {
  retryStrategy: (error, attemptCount) => {
    // Only retry rate limits and timeouts
    const isRetryable = error.message === 'RATE_LIMIT' || error.message === 'TIMEOUT';
    
    if (!isRetryable || attemptCount >= 3) {
      return { shouldRetry: false };
    }
    
    // Exponential backoff: 1s, 2s, 4s (capped at 30s)
    const delay = Math.min(Math.pow(2, attemptCount - 1), 30);
    return { shouldRetry: true, delay: { seconds: delay } };
  }
});
```

------
#### [ Python ]

```
def retry_strategy(error, attempt_count):
    # Only retry rate limits and timeouts
    is_retryable = str(error) in ['RATE_LIMIT', 'TIMEOUT']
    
    if not is_retryable or attempt_count >= 3:
        return {'should_retry': False}
    
    # Exponential backoff: 1s, 2s, 4s (capped at 30s)
    delay = min(2 ** (attempt_count - 1), 30)
    return {'should_retry': True, 'delay': delay}

result = context.step(
    lambda _: call_rate_limited_api(),
    name='call-rate-limited-api',
    config=StepConfig(retry_strategy=retry_strategy)
)
```

------

**Désactiver les nouvelles tentatives :**

------
#### [ TypeScript ]

```
const isDuplicate = await context.step('check-duplicate', async () => {
  return await checkIfOrderExists(event.orderId);
}, {
  retryStrategy: () => ({ shouldRetry: false })
});
```

------
#### [ Python ]

```
is_duplicate = context.step(
    lambda _: check_if_order_exists(event['orderId']),
    name='check-duplicate',
    config=StepConfig(
        retry_strategy=lambda error, attempt: {'should_retry': False}
    )
)
```

------

Lorsque la stratégie de nouvelle tentative revient`shouldRetry: false`, l'étape échoue immédiatement sans nouvelle tentative. Utilisez-le pour les opérations qui ne doivent pas être renouvelées, telles que les contrôles d'idempuissance ou les opérations présentant des effets secondaires qui ne peuvent pas être répétés en toute sécurité.

## Exceptions en dehors des étapes
<a name="durable-handler-exceptions"></a>

Lorsqu'une exception non détectée se produit dans le code de votre gestionnaire mais en dehors de toute étape, le SDK marque l'exécution comme ayant échoué. Cela garantit que les erreurs dans la logique de votre application sont correctement capturées et signalées.


| Scénario | Que se passe-t-il | Impact du mesurage | 
| --- | --- | --- | 
| Exception dans le code du gestionnaire en dehors de toute étape | Le SDK marque l'exécution comme ayant échoué et renvoie l'erreur. L'exception n'est pas automatiquement réessayée. | Erreur concernant la taille de la charge utile | 

Pour activer la nouvelle tentative automatique pour le code sujet aux erreurs, associez-le à une étape avec une stratégie de nouvelle tentative. Les étapes fournissent une nouvelle tentative automatique avec une interruption configurable, tandis que le code en dehors des étapes échoue immédiatement.

## Rétentatives du backend
<a name="durable-backend-retries"></a>

Les nouvelles tentatives du backend ont lieu lorsque Lambda rencontre des défaillances d'infrastructure, des erreurs d'exécution ou lorsque le SDK ne peut pas communiquer avec le service d'exécution durable. Lambda réessaie automatiquement ces défaillances pour aider vos fonctions durables à se remettre de problèmes d'infrastructure transitoires.

### Scénarios de nouvelle tentative du backend
<a name="durable-backend-retry-scenarios"></a>

Lambda réessaie automatiquement votre fonction lorsqu'elle rencontre les scénarios suivants :
+ **Erreurs de service internes** : lorsque Lambda ou le service d'exécution durable renvoie une erreur 5xx, indiquant un problème de service temporaire.
+ **Limitation : lorsque** votre fonction est limitée en raison de limites de simultanéité ou de quotas de service.
+ **Délais d'expiration** : lorsque le SDK ne parvient pas à atteindre le service d'exécution durable dans le délai imparti.
+ Échec de l'**initialisation du sandbox : lorsque** Lambda ne parvient pas à initialiser l'environnement d'exécution.
+ **Erreurs d'exécution** : lorsque le moteur d'exécution Lambda rencontre des erreurs extérieures au code de votre fonction, telles que out-of-memory des erreurs ou des pannes de processus.
+ **Erreurs de jeton de point de contrôle non valides** : lorsque le jeton de point de contrôle n'est plus valide, généralement en raison de changements d'état côté service.

Le tableau suivant décrit comment le SDK gère ces scénarios :


| Scénario | Que se passe-t-il | Impact du mesurage | 
| --- | --- | --- | 
| Erreur d'exécution en dehors du gestionnaire durable (OOM, délai d'attente, crash) | Lambda réessaie automatiquement l'invocation. Le SDK se rejoue depuis le dernier point de contrôle, en sautant les étapes terminées. | Taille de la charge utile d'erreur \$1 1 opération par nouvelle tentative | 
| Erreur de service (5xx) ou délai d'expiration lors de l'appel/CheckpointDurableExecutionGetDurableExecutionState APIs | Lambda réessaie automatiquement l'invocation. Le SDK se rejoue depuis le dernier point de contrôle. | Taille de la charge utile d'erreur \$1 1 opération par nouvelle tentative | 
| Throttling (429) ou jeton de point de contrôle non valide lors de l'appel/CheckpointDurableExecutionGetDurableExecutionState APIs | Lambda réessaie automatiquement l'invocation avec un retard exponentiel. Le SDK se rejoue depuis le dernier point de contrôle. | Taille de la charge utile d'erreur \$1 1 opération par nouvelle tentative | 
| Erreur client (4xx, sauf 429 et jeton non valide) lorsque/CheckpointDurableExecutionGetDurableExecutionState APIs | Le SDK marque l'exécution comme ayant échoué. Aucune nouvelle tentative automatique ne se produit car l'erreur indique un problème permanent. | Erreur concernant la taille de la charge utile | 

Les nouvelles tentatives du backend utilisent un retard exponentiel et se poursuivent jusqu'à ce que la fonction réussisse ou que le délai d'exécution soit atteint. Pendant la rediffusion, le SDK ignore les points de contrôle terminés et poursuit l'exécution depuis la dernière opération réussie, garantissant ainsi que votre fonction ne réexécute pas le travail terminé.

## Réessayez les meilleures pratiques
<a name="durable-retry-best-practices"></a>

Suivez les meilleures pratiques suivantes lors de la configuration des stratégies de nouvelle tentative :
+ **Configurez des stratégies de relance explicites** : ne vous fiez pas au comportement de nouvelle tentative par défaut en production. Configurez des stratégies de nouvelles tentatives explicites avec un nombre maximum de tentatives et des intervalles d'attente adaptés à votre cas d'utilisation.
+ **Utiliser des tentatives conditionnelles** : implémentez une `shouldRetry` logique permettant de réessayer uniquement les erreurs transitoires (limites de débit, délais d'attente) et d'échouer rapidement en cas d'erreur permanente (échec de validation, introuvable).
+ **Définissez le nombre maximum de tentatives approprié** : équilibre entre résilience et temps d'exécution. Un trop grand nombre de tentatives peut retarder la détection des échecs, tandis qu'un nombre insuffisant peut entraîner des échecs inutiles.
+ **Utilisez le ralentissement exponentiel : le** ralentissement exponentiel réduit la charge sur les services en aval et augmente les chances de reprise après des défaillances transitoires.
+ **Enveloppez le code sujet aux erreurs par étapes : le code en** dehors des étapes ne peut pas être réessayé automatiquement. Intégrez les appels d'API externes, les requêtes de base de données et les autres opérations susceptibles d'entraîner des erreurs par étapes grâce à des stratégies de nouvelle tentative.
+ **Surveillez les statistiques relatives aux nouvelles tentatives** : suivez les opérations de nouvelle tentative par étapes et les échecs d'exécution sur Amazon CloudWatch afin d'identifier les modèles et d'optimiser les stratégies de nouvelles tentatives.

# Idempotence
<a name="durable-execution-idempotency"></a>

Les fonctions durables fournissent une idempuissance intégrée pour les démarrages d'exécution grâce aux noms d'exécution. Lorsque vous fournissez un nom d'exécution, Lambda l'utilise pour empêcher les doubles exécutions et permettre de nouvelles tentatives d'appel en toute sécurité. Les étapes ont une sémantique at-least-once d'exécution par défaut : lors de la réexécution, le SDK renvoie des résultats précis sans réexécuter les étapes terminées, mais votre logique métier doit être idempotente pour gérer d'éventuelles nouvelles tentatives avant la fin.

**Note**  
Les mappages de sources d'événements Lambda (ESM) ne prennent pas en charge l'idempotencie au lancement. Par conséquent, chaque invocation (y compris les nouvelles tentatives) lance une nouvelle exécution durable. Pour garantir une exécution idempotente avec des mappages de sources d'événements, implémentez la logique d'idempotentie dans votre code de fonction, par exemple avec [Powertools for, ou AWS Lambda](https://docs.aws.amazon.com//powertools/) utilisez une fonction Lambda normale comme proxy (répartiteur) pour appeler une fonction durable avec une clé d'idempotentie (paramètre du nom d'exécution).

## Noms d'exécution
<a name="durable-idempotency-execution-names"></a>

Vous pouvez fournir un nom d'exécution lorsque vous invoquez une fonction durable. Le nom d'exécution agit comme une clé d'impuissance, vous permettant de réessayer les demandes d'invocation en toute sécurité sans créer de doublons d'exécutions. Si vous ne fournissez pas de nom, Lambda génère automatiquement un identifiant d'exécution unique.

Les noms d'exécution doivent être uniques au sein de votre compte et de votre région. Lorsque vous invoquez une fonction dont le nom d'exécution existe déjà, le comportement de Lambda dépend de l'état de l'exécution existante et de la correspondance de la charge utile.

## Comportement d'impuissance
<a name="durable-idempotency-behavior"></a>

Le tableau suivant décrit comment Lambda gère les demandes d'invocation selon que vous fournissez un nom d'exécution, l'état d'exécution existant et si la charge utile correspond :


| Scénario | Nom fourni ? | État d'exécution existant | Charge utile identique ? | Comportement | 
| --- | --- | --- | --- | --- | 
| 1 | Non | N/A | N/A | Nouvelle exécution démarrée : Lambda génère un ID d'exécution unique et lance une nouvelle exécution | 
| 2 | Oui | N'a jamais existé ou la rétention a expiré | N/A | Nouvelle exécution démarrée : Lambda lance une nouvelle exécution avec le nom fourni | 
| 3 | Oui | En cours d’exécution | Oui | Démarrage idempotent : Lambda renvoie les informations d'exécution existantes sans créer de doublon. Pour les invocations synchrones, cela agit comme un rattachement à l'exécution en cours | 
| 4 | Oui | En cours d’exécution | Non | Erreur : Lambda renvoie une DurableExecutionAlreadyExists erreur car une exécution portant ce nom est déjà en cours d'exécution avec une charge utile différente | 
| 5 | Oui | Fermé (réussite, échec, arrêt ou expiration du délai imparti) | Oui | Démarrage idempotent : Lambda renvoie les informations d'exécution existantes sans démarrer une nouvelle exécution. Le résultat de l'exécution fermée est renvoyé | 
| 6 | Oui | Fermé (réussite, échec, arrêt ou expiration du délai imparti) | Non | Erreur : Lambda renvoie une DurableExecutionAlreadyExists erreur car une exécution portant ce nom est déjà terminée avec une charge utile différente | 

**Remarque**  
Les scénarios 3 et 5 illustrent un comportement idempotent dans lequel Lambda gère en toute sécurité les demandes d'invocation dupliquées en renvoyant les informations d'exécution existantes au lieu de créer des doublons.

## Étape 1 : Idempuissance
<a name="durable-idempotency-steps"></a>

Les étapes ont une sémantique at-least-once d'exécution par défaut. Lorsque votre fonction est rejouée après une attente, un rappel ou un échec, le SDK compare chaque étape au journal des points de contrôle. Pour les étapes déjà terminées, le SDK renvoie le résultat du point de contrôle sans réexécuter la logique des étapes. Toutefois, si une étape échoue ou si la fonction est interrompue avant la fin de l'étape, l'étape peut être exécutée plusieurs fois.

Votre logique métier articulée en étapes doit être idempotente pour gérer d'éventuelles nouvelles tentatives. Utilisez des clés d'idempuissance pour garantir que les opérations telles que les paiements ou les écritures de base de données ne s'exécutent qu'une seule fois, même si l'étape est réessayée.

**Exemple : utilisation des clés d'idempuissance par étapes**

------
#### [ TypeScript ]

```
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js';
import { randomUUID } from 'crypto';

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // Generate idempotency key once
    const idempotencyKey = await context.step('generate-key', async () => {
      return randomUUID();
    });
    
    // Use idempotency key in payment API to prevent duplicate charges
    const payment = await context.step('process-payment', async () => {
      return paymentAPI.charge({
        amount: event.amount,
        idempotencyKey: idempotencyKey
      });
    });
    
    return { statusCode: 200, payment };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import durable_execution, DurableContext
import uuid

@durable_execution
def handler(event, context: DurableContext):
    # Generate idempotency key once
    idempotency_key = context.step(
        lambda _: str(uuid.uuid4()),
        name='generate-key'
    )
    
    # Use idempotency key in payment API to prevent duplicate charges
    payment = context.step(
        lambda _: payment_api.charge(
            amount=event['amount'],
            idempotency_key=idempotency_key
        ),
        name='process-payment'
    )
    
    return {'statusCode': 200, 'payment': payment}
```

------

Vous pouvez configurer les étapes pour utiliser la sémantique at-most-once d'exécution en définissant le mode d'exécution sur. `AT_MOST_ONCE_PER_RETRY` Cela garantit que l'étape s'exécute au maximum une fois par nouvelle tentative, mais peut ne pas s'exécuter du tout si la fonction est interrompue avant la fin de l'étape.

Le SDK applique la rediffusion déterministe en vérifiant que les noms et l'ordre des étapes correspondent au journal des points de contrôle lors de la rediffusion. Si votre code tente d'exécuter des étapes dans un ordre différent ou avec des noms différents, le SDK lance un`NonDeterministicExecutionError`.

**Comment fonctionne le replay une fois les étapes terminées :**

1. Premier appel : la fonction exécute l'étape A, crée un point de contrôle, puis attend

1. Deuxième appel (après attente) : la fonction est rejouée depuis le début, l'étape A renvoie instantanément le résultat vérifié sans la réexécuter, puis passe à l'étape B

1. Troisième appel (après une nouvelle attente) : les fonctions sont rejouées depuis le début, les étapes A et B renvoient instantanément les résultats vérifiés, puis passent à l'étape C

Ce mécanisme de réexécution garantit que les étapes terminées ne sont pas réexécutées, mais votre logique métier doit toujours être idempotente pour gérer les nouvelles tentatives avant leur fin.

# Tester les fonctions durables de Lambda
<a name="durable-testing"></a>

AWS fournit des tests dédiés SDKs pour les fonctions durables qui vous permettent d'exécuter et d'inspecter les exécutions à la fois localement et dans le cloud. Installez le SDK de test pour votre langue :

------
#### [ TypeScript ]

```
npm install --save-dev @aws/aws-durable-execution-sdk-js-testing
```

Pour obtenir une documentation complète et des exemples, consultez le [SDK de TypeScript test](https://github.com/aws/aws-durable-execution-sdk-js/tree/development/packages/aws-durable-execution-sdk-js-testing) sur GitHub.

------
#### [ Python ]

```
pip install aws-durable-execution-sdk-python-testing
```

Pour une documentation complète et des exemples, consultez le [SDK de test Python](https://github.com/aws/aws-durable-execution-sdk-python-testing) sur GitHub.

------

Le SDK de test propose deux modes de test : les tests locaux pour les tests unitaires rapides et les tests dans le cloud pour les tests d'intégration sur les fonctions déployées.

## Tests locaux
<a name="durable-local-testing"></a>

Les tests locaux exécutent vos fonctions durables dans votre environnement de développement sans nécessiter de ressources déployées. Le lanceur de tests exécute directement votre code de fonction et capture toutes les opérations à des fins d'inspection.

Utilisez les tests locaux pour les tests unitaires, le développement piloté par les tests et CI/CD les pipelines. Les tests sont exécutés localement sans latence réseau ni coûts supplémentaires.

**Exemple de test :**

------
#### [ TypeScript ]

```
import { withDurableExecution } from '@aws/aws-durable-execution-sdk-js';
import { DurableFunctionTestRunner } from '@aws/aws-durable-execution-sdk-js-testing';

const handler = withDurableExecution(async (event, context) => {
  const result = await context.step('calculate', async () => {
    return event.a + event.b;
  });
  return result;
});

test('addition works correctly', async () => {
  const runner = new DurableFunctionTestRunner({ handler });
  const result = await runner.run({ a: 5, b: 3 });
  
  expect(result.status).toBe('SUCCEEDED');
  expect(result.result).toBe(8);
  
  const step = result.getStep('calculate');
  expect(step.result).toBe(8);
});
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import durable_execution, DurableContext
from aws_durable_execution_sdk_python_testing import DurableFunctionTestRunner
from aws_durable_execution_sdk_python.execution import InvocationStatus

@durable_execution
def handler(event: dict, context: DurableContext) -> int:
    result = context.step(lambda _: event["a"] + event["b"], name="calculate")
    return result

def test_addition():
    runner = DurableFunctionTestRunner(handler=handler)
    with runner:
        result = runner.run(input={"a": 5, "b": 3}, timeout=10)
    
    assert result.status is InvocationStatus.SUCCEEDED
    assert result.result == 8
    
    step = result.get_step("calculate")
    assert step.result == 8
```

------

Le lanceur de tests capture l'état d'exécution, y compris le résultat final, les résultats des étapes individuelles, les opérations d'attente, les rappels et les éventuelles erreurs. Vous pouvez inspecter les opérations par leur nom ou répéter toutes les opérations pour vérifier le comportement d'exécution.

### Magasins d'exécution
<a name="durable-execution-stores"></a>

Le SDK de test utilise des magasins d'exécution pour conserver les données d'exécution des tests. Par défaut, les tests utilisent un magasin en mémoire qui est rapide et ne nécessite aucun nettoyage. Pour le débogage ou l'analyse de l'historique des exécutions, vous pouvez utiliser un magasin de système de fichiers qui enregistre les exécutions sous forme de fichiers JSON.

**Stockage en mémoire (par défaut) :**

Le stockage en mémoire conserve les données d'exécution en mémoire pendant les tests. Les données sont perdues à la fin des tests, ce qui les rend idéales pour les tests unitaires standard et les CI/CD pipelines où vous n'avez pas besoin d'inspecter les exécutions une fois les tests terminés.

**Stockage du système de fichiers :**

Le magasin du système de fichiers conserve les données d'exécution sur le disque sous forme de fichiers JSON. Chaque exécution est enregistrée dans un fichier distinct, ce qui permet de consulter facilement l'historique des exécutions une fois les tests terminés. Utilisez le magasin du système de fichiers pour corriger les échecs de tests complexes ou pour analyser les modèles d'exécution au fil du temps.

Configurez le magasin à l'aide de variables d'environnement :

```
# Use filesystem store
export AWS_DEX_STORE_TYPE=filesystem
export AWS_DEX_STORE_PATH=./test-executions

# Run tests
pytest tests/
```

Les fichiers d'exécution sont stockés avec des noms nettoyés et contiennent l'état d'exécution complet, y compris les opérations, les points de contrôle et les résultats. Le magasin du système de fichiers crée automatiquement le répertoire de stockage s'il n'existe pas.

## Test cloud
<a name="durable-cloud-testing"></a>

Les tests dans le cloud invoquent les fonctions durables déployées AWS et récupèrent leur historique d'exécution à l'aide de l'API Lambda. Utilisez les tests dans le cloud pour vérifier le comportement dans des environnements de production dotés de AWS services et de configurations réels.

Les tests dans le cloud nécessitent une fonction déployée et des AWS informations d'identification avec les autorisations nécessaires pour appeler des fonctions et lire l'historique d'exécution :

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction",
                "lambda:GetDurableExecution",
                "lambda:GetDurableExecutionHistory"
            ],
            "Resource": "arn:aws:lambda:region:account-id:function:function-name"
        }
    ]
}
```

**Exemple de test dans le cloud :**

------
#### [ TypeScript ]

```
import { DurableFunctionCloudTestRunner } from '@aws/aws-durable-execution-sdk-js-testing';

test('deployed function processes orders', async () => {
  const runner = new DurableFunctionCloudTestRunner({
    functionName: 'order-processor',
    region: 'us-east-1'
  });
  
  const result = await runner.run({ orderId: 'order-123' });
  
  expect(result.status).toBe('SUCCEEDED');
  expect(result.result.status).toBe('completed');
});
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python_testing import (
    DurableFunctionCloudTestRunner,
    DurableFunctionCloudTestRunnerConfig
)

def test_deployed_function():
    config = DurableFunctionCloudTestRunnerConfig(
        function_name="order-processor",
        region="us-east-1"
    )
    runner = DurableFunctionCloudTestRunner(config=config)
    
    result = runner.run(input={"orderId": "order-123"})
    
    assert result.status is InvocationStatus.SUCCEEDED
    assert result.result["status"] == "completed"
```

------

Les tests dans le cloud invoquent la fonction réellement déployée et en extraient l'historique d'exécution AWS. Cela vous permet de vérifier l'intégration avec d'autres AWS services, de valider les caractéristiques de performance et de tester avec des données et des configurations similaires à celles de la production.

## Que faut-il tester ?
<a name="durable-testing-patterns"></a>

Testez les fonctions durables en vérifiant les résultats d'exécution, le comportement des opérations et la gestion des erreurs. Concentrez-vous sur l'exactitude de la logique métier plutôt que sur les détails de mise en œuvre.

**Vérifiez les résultats de l'exécution :** vérifiez que les fonctions renvoient les valeurs attendues pour des entrées données. Testez à la fois les exécutions réussies et les cas d'erreur pour vous assurer que les fonctions gèrent correctement les entrées non valides.

**Inspectez l'exécution des opérations :** vérifiez que les étapes, les attentes et les rappels s'exécutent comme prévu. Vérifiez les résultats des étapes pour vous assurer que les opérations intermédiaires produisent des valeurs correctes. Vérifiez que les opérations d'attente sont configurées avec des délais d'expiration appropriés et que les rappels sont créés avec les paramètres appropriés.

**Gestion des erreurs de test :** vérifiez que les fonctions échouent correctement avec des messages d'erreur descriptifs en cas d'entrée non valide. Testez le comportement des nouvelles tentatives en simulant des défaillances transitoires et en vérifiant que les opérations recommencent correctement. Vérifiez que les échecs permanents ne déclenchent pas de nouvelles tentatives inutiles.

**Valider les flux de travail :** pour les flux de travail en plusieurs étapes, vérifiez que les opérations s'exécutent dans le bon ordre. Testez le branchement conditionnel pour vous assurer que les différents chemins d'exécution fonctionnent correctement. Validez les opérations parallèles exécutées simultanément et produisez les résultats attendus.

Les référentiels de documentation du SDK contiennent de nombreux exemples de modèles de test, notamment des flux de travail en plusieurs étapes, des scénarios d'erreur, la gestion des délais d'attente et des modèles de sondage.

## Stratégie de test
<a name="durable-testing-strategy"></a>

Utilisez des tests locaux pour les tests unitaires pendant le développement et dans les CI/CD pipelines. Les tests locaux s'exécutent rapidement, ne nécessitent pas AWS d'informations d'identification et fournissent des informations immédiates sur les modifications du code. Rédigez des tests locaux pour vérifier la logique métier, la gestion des erreurs et le comportement des opérations.

Utilisez les tests dans le cloud pour les tests d'intégration avant le déploiement en production. Les tests dans le cloud vérifient le comportement à l'aide de AWS services et de configurations réels, valident les caractéristiques de performance et testent end-to-end les flux de travail. Exécutez des tests cloud dans des environnements de test afin de détecter les problèmes d'intégration avant qu'ils ne soient mis en production.

Simulez les dépendances externes dans les tests locaux pour isoler la logique des fonctions et accélérer les tests. Utilisez des tests dans le cloud pour vérifier l'intégration réelle avec des services externes tels que des bases de données et d'autres AWS services. APIs

Rédigez des tests ciblés qui vérifient un comportement spécifique. Utilisez des noms de test descriptifs qui expliquent ce qui est testé. Regroupez les tests connexes et utilisez des appareils de test pour un code de configuration commun. Simplifiez les tests et évitez les logiques de test complexes difficiles à comprendre.

## Défaillances de débogage
<a name="durable-testing-debugging"></a>

Lorsque les tests échouent, inspectez le résultat de l'exécution pour comprendre ce qui s'est mal passé. Vérifiez l'état d'exécution pour voir si la fonction a réussi, a échoué ou a expiré. Lisez les messages d'erreur pour comprendre la cause de l'échec.

Inspectez les résultats de chaque opération pour trouver les domaines dans lesquels le comportement ne correspondait pas aux attentes. Vérifiez les résultats des étapes pour voir quelles valeurs ont été produites. Vérifiez l'ordre des opérations pour confirmer que les opérations sont exécutées dans l'ordre attendu. Comptez les opérations pour vous assurer que le bon nombre d'étapes, d'attentes et de rappels a été créé.

Les problèmes courants incluent le code non déterministe qui produit des résultats différents lors de la réexécution, l'état partagé par le biais de variables globales qui s'interrompent pendant la rediffusion et les opérations manquantes en raison d'erreurs de logique conditionnelle. Utilisez les débogueurs et la journalisation standard pour parcourir le code de fonction et suivre le flux d'exécution.

Pour les tests dans le cloud, consultez l'historique des exécutions dans CloudWatch les journaux pour consulter les journaux d'opérations détaillés. Utilisez le suivi pour suivre le flux d'exécution entre les services et identifier les goulots d'étranglement.

# Surveillance des fonctions durables
<a name="durable-monitoring"></a>

Vous pouvez surveiller vos fonctions durables à l'aide de CloudWatch métriques, de CloudWatch journaux et de traçage. Les fonctions durables pouvant s'exécuter pendant de longues périodes et couvrir plusieurs invocations de fonctions, leur surveillance nécessite de comprendre leurs modèles d'exécution uniques, notamment les points de contrôle, les transitions d'état et le comportement de rediffusion.

## CloudWatch métriques
<a name="durable-monitoring-metrics"></a>

Lambda publie automatiquement les métriques sans CloudWatch frais supplémentaires. Les fonctions durables fournissent des mesures supplémentaires au-delà des métriques Lambda standard pour vous aider à surveiller les flux de travail de longue durée, la gestion des états et l'utilisation des ressources.

### Mesures d'exécution durables
<a name="durable-monitoring-execution-metrics"></a>

Lambda émet les métriques suivantes pour des exécutions durables :


| Métrique | Description | 
| --- | --- | 
| ApproximateRunningDurableExecutions | Nombre d'exécutions durables à l'état RUNNING | 
| ApproximateRunningDurableExecutionsUtilization | Pourcentage du quota maximal d'exécutions durables de votre compte actuellement utilisé | 
| DurableExecutionDuration | Temps écoulé, en millisecondes, pendant lequel une exécution durable est restée à l'état RUNNING | 
| DurableExecutionStarted | Nombre d'exécutions durables qui ont débuté | 
| DurableExecutionStopped | Nombre d'exécutions durables interrompues à l'aide de l' StopDurableExecution API | 
| DurableExecutionSucceeded | Nombre d'exécutions durables achevées avec succès | 
| DurableExecutionFailed | Nombre d'exécutions durables qui se sont soldées par un échec | 
| DurableExecutionTimedOut | Nombre d'exécutions durables ayant dépassé le délai d'exécution configuré | 
| DurableExecutionOperations | Nombre cumulé d'opérations effectuées dans le cadre d'une exécution durable (maximum : 3 000) | 
| DurableExecutionStorageWrittenBytes | Quantité cumulée de données en octets persistée par une exécution durable (max. : 100 Mo) | 

### CloudWatch métriques
<a name="durable-monitoring-standard-metrics"></a>

Lambda émet des métriques d'invocation, de performance et de simultanéité standard pour des fonctions durables. Étant donné qu'une exécution durable peut s'étendre sur plusieurs invocations de fonctions au fur et à mesure qu'elle progresse entre les points de contrôle et les rediffusions, ces métriques se comportent différemment de celles des fonctions standard :
+ **Invocations :** compte chaque appel de fonction, y compris les rediffusions. Une seule exécution durable peut générer plusieurs points de données d'invocation.
+ **Durée :** mesure chaque invocation de fonction séparément. `DurableExecutionDuration`À utiliser pour le temps total nécessaire à une seule exécution durable.
+ **Erreurs :** suit les échecs d'invocation des fonctions. À utiliser `DurableExecutionFailed` pour les échecs au niveau de l'exécution.

Pour une liste complète des métriques Lambda standard, voir [Types de métriques pour les fonctions Lambda](https://docs.aws.amazon.com//lambda/latest/dg/monitoring-metrics-types.html).

### Création d' CloudWatch alarmes
<a name="durable-monitoring-alarms"></a>

Créez des CloudWatch alarmes pour vous avertir lorsque les mesures dépassent les seuils. Les alarmes les plus courantes incluent :
+ `ApproximateRunningDurableExecutionsUtilization`dépasse 80 % de votre quota
+ `DurableExecutionFailed`augmentations supérieures à un seuil
+ `DurableExecutionTimedOut`indique que le délai d'exécution est expiré
+ `DurableExecutionStorageWrittenBytes`approche les limites de stockage

Pour plus d'informations, [consultez la section Utilisation des CloudWatch alarmes.](https://docs.aws.amazon.com//AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html) .

## EventBridge événements
<a name="durable-monitoring-eventbridge"></a>

Lambda publie les événements de modification du statut d'exécution durable sur. EventBridge Vous pouvez utiliser ces événements pour déclencher des flux de travail, envoyer des notifications ou suivre les modifications du cycle de vie d'exécution de vos fonctions durables.

### Événements de changement de statut d'exécution durables
<a name="durable-eventbridge-status-changes"></a>

Lambda émet un événement EventBridge chaque fois qu'une exécution durable change de statut. Ces événements présentent les caractéristiques suivantes :
+ **Source :** `aws.lambda`
+ **Type de détail :** `Durable Execution Status Change`

Les événements de changement de statut sont publiés pour les états d'exécution suivants :
+ `RUNNING`- L'exécution a commencé
+ `SUCCEEDED`- Exécution terminée avec succès
+ `STOPPED`- L'exécution s'est arrêtée à l'aide de l' StopDurableExecution API
+ `FAILED`- L'exécution a échoué avec une erreur
+ `TIMED_OUT`- L'exécution a dépassé le délai d'expiration configuré

L'exemple suivant montre un événement de changement de statut d'exécution durable :

```
{
  "version": "0",
  "id": "d019b03c-a8a3-9d58-85de-241e96206538",
  "detail-type": "Durable Execution Status Change",
  "source": "aws.lambda",
  "account": "123456789012",
  "time": "2025-11-20T13:08:22Z",
  "region": "us-east-1",
  "resources": [],
  "detail": {
    "durableExecutionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function:$LATEST/durable-execution/090c4189-b18b-4296-9d0c-cfd01dc3a122/9f7d84c9-ea3d-3ffc-b3e5-5ec51c34ffc9",
    "durableExecutionName": "order-123",
    "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function:2",
    "status": "RUNNING",
    "startTimestamp": "2025-11-20T13:08:22.345Z"
  }
}
```

Pour les états du terminal (`SUCCEEDED``STOPPED`,`FAILED`,,`TIMED_OUT`), l'événement inclut un `endTimestamp` champ indiquant quand l'exécution est terminée.

### Création de EventBridge règles
<a name="durable-eventbridge-rules"></a>

Créez des règles pour acheminer les événements de changement de statut d'exécution durables vers des cibles telles qu'Amazon Simple Notification Service, Amazon Simple Queue Service ou d'autres fonctions Lambda.

L'exemple suivant crée une règle qui correspond à toutes les modifications du statut d'exécution durable :

```
{
  "source": ["aws.lambda"],
  "detail-type": ["Durable Execution Status Change"]
}
```

L'exemple suivant crée une règle qui ne correspond qu'aux exécutions ayant échoué :

```
{
  "source": ["aws.lambda"],
  "detail-type": ["Durable Execution Status Change"],
  "detail": {
    "status": ["FAILED"]
  }
}
```

L'exemple suivant crée une règle qui correspond aux changements de statut pour une fonction spécifique :

```
{
  "source": ["aws.lambda"],
  "detail-type": ["Durable Execution Status Change"],
  "detail": {
    "functionArn": [{
      "prefix": "arn:aws:lambda:us-east-1:123456789012:function:my-function"
    }]
  }
}
```

Pour plus d'informations sur la création de règles, consultez les [ EventBridge didacticiels Amazon](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-tutorial.html) dans le guide de EventBridge l'utilisateur.

## AWS X-Ray traçage
<a name="durable-monitoring-xray"></a>

Vous pouvez activer le traçage X-Ray sur vos fonctions durables. Lambda transmet l'en-tête de trace X-Ray à l'exécution durable, ce qui vous permet de suivre les demandes dans l'ensemble de votre flux de travail.

Pour activer le traçage X-Ray à l'aide de la console Lambda, choisissez votre fonction, puis choisissez Configuration, Monitoring and Operations tools, puis activez Active Tracing sous X-Ray.

Pour activer le traçage X-Ray à l'aide de AWS CLI :

```
aws lambda update-function-configuration \
    --function-name my-durable-function \
    --tracing-config Mode=Active
```

Pour activer le AWS X-Ray suivi à l'aide de AWS SAM :

```
Resources:
  MyDurableFunction:
    Type: AWS::Serverless::Function
    Properties:
      Tracing: Active
      DurableConfig:
        ExecutionTimeout: 3600
```

Pour plus d'informations sur X-Ray, [consultez le manuel du AWS X-Ray développeur.](https://docs.aws.amazon.com//xray/latest/devguide/aws-xray.html)

# Meilleures pratiques pour les fonctions durables de Lambda
<a name="durable-best-practices"></a>

Les fonctions durables utilisent un modèle d'exécution basé sur le replay qui nécessite des modèles différents de ceux des fonctions Lambda traditionnelles. Suivez ces meilleures pratiques pour créer des flux de travail fiables et rentables.

## Écrire du code déterministe
<a name="durable-determinism"></a>

Pendant la réexécution, votre fonction s'exécute depuis le début et doit suivre le même chemin d'exécution que l'exécution initiale. Le code en dehors des opérations durables doit être déterministe et produire les mêmes résultats avec les mêmes entrées.

**Répartissez les opérations non déterministes par étapes :**
+ Génération de nombres aléatoires et UUIDs
+ Heure actuelle ou horodatage
+ Appels d'API externes et requêtes de base de données
+ Opérations du système de fichiers

------
#### [ TypeScript ]

```
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js';
import { randomUUID } from 'crypto';

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // Generate transaction ID inside a step
    const transactionId = await context.step('generate-transaction-id', async () => {
      return randomUUID();
    });
    
    // Use the same ID throughout execution, even during replay
    const payment = await context.step('process-payment', async () => {
      return processPayment(event.amount, transactionId);
    });
    
    return { statusCode: 200, transactionId, payment };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import durable_execution, DurableContext
import uuid

@durable_execution
def handler(event, context: DurableContext):
    # Generate transaction ID inside a step
    transaction_id = context.step(
        lambda _: str(uuid.uuid4()),
        name='generate-transaction-id'
    )
    
    # Use the same ID throughout execution, even during replay
    payment = context.step(
        lambda _: process_payment(event['amount'], transaction_id),
        name='process-payment'
    )
    
    return {'statusCode': 200, 'transactionId': transaction_id, 'payment': payment}
```

------

**Important**  
N'utilisez pas de variables globales ou de fermetures pour partager l'état entre les étapes. Transmettez les données via les valeurs de retour. L'état global se brise pendant la rediffusion car les étapes renvoient les résultats mis en cache mais les variables globales sont réinitialisées.

**Évitez les mutations de fermeture :** les variables capturées lors des fermetures peuvent perdre des mutations pendant la rediffusion. Les étapes renvoient les résultats mis en cache, mais les mises à jour des variables en dehors de l'étape ne sont pas reproduites.

------
#### [ TypeScript ]

```
// ❌ WRONG: Mutations lost on replay
export const handler = withDurableExecution(async (event, context) => {
  let total = 0;
  
  for (const item of items) {
    await context.step(async () => {
      total += item.price; // ⚠️ Mutation lost on replay!
      return saveItem(item);
    });
  }
  
  return { total }; // Inconsistent value!
});

// ✅ CORRECT: Accumulate with return values
export const handler = withDurableExecution(async (event, context) => {
  let total = 0;
  
  for (const item of items) {
    total = await context.step(async () => {
      const newTotal = total + item.price;
      await saveItem(item);
      return newTotal; // Return updated value
    });
  }
  
  return { total }; // Consistent!
});

// ✅ EVEN BETTER: Use map for parallel processing
export const handler = withDurableExecution(async (event, context) => {
  const results = await context.map(
    items,
    async (ctx, item) => {
      await ctx.step(async () => saveItem(item));
      return item.price;
    }
  );
  
  const total = results.getResults().reduce((sum, price) => sum + price, 0);
  return { total };
});
```

------
#### [ Python ]

```
# ❌ WRONG: Mutations lost on replay
@durable_execution
def handler(event, context: DurableContext):
    total = 0
    
    for item in items:
        context.step(
            lambda _: save_item_and_mutate(item, total),  # ⚠️ Mutation lost on replay!
            name=f'save-item-{item["id"]}'
        )
    
    return {'total': total}  # Inconsistent value!

# ✅ CORRECT: Accumulate with return values
@durable_execution
def handler(event, context: DurableContext):
    total = 0
    
    for item in items:
        total = context.step(
            lambda _: save_item_and_return_total(item, total),
            name=f'save-item-{item["id"]}'
        )
    
    return {'total': total}  # Consistent!

# ✅ EVEN BETTER: Use map for parallel processing
@durable_execution
def handler(event, context: DurableContext):
    def process_item(ctx, item):
        ctx.step(lambda _: save_item(item))
        return item['price']
    
    results = context.map(items, process_item)
    total = sum(results.get_results())
    
    return {'total': total}
```

------

## Conception axée sur l'idempuissance
<a name="durable-idempotency"></a>

Les opérations peuvent être exécutées plusieurs fois en raison de nouvelles tentatives ou de rediffusions. Les opérations non idempotentes entraînent des effets secondaires dupliqués, comme le fait de facturer deux fois les clients ou d'envoyer plusieurs e-mails.

**Utilisez des jetons d'idempuissance :** générez des jetons en quelques étapes et incluez-les dans les appels d'API externes pour éviter les opérations dupliquées.

------
#### [ TypeScript ]

```
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js';

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // Generate idempotency token once
    const idempotencyToken = await context.step('generate-idempotency-token', async () => {
      return crypto.randomUUID();
    });
    
    // Use token to prevent duplicate charges
    const charge = await context.step('charge-payment', async () => {
      return paymentService.charge({
        amount: event.amount,
        cardToken: event.cardToken,
        idempotencyKey: idempotencyToken
      });
    });
    
    return { statusCode: 200, charge };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import durable_execution, DurableContext
import uuid

@durable_execution
def handler(event, context: DurableContext):
    # Generate idempotency token once
    idempotency_token = context.step(
        lambda _: str(uuid.uuid4()),
        name='generate-idempotency-token'
    )
    
    # Use token to prevent duplicate charges
    def charge_payment(_):
        return payment_service.charge(
            amount=event['amount'],
            card_token=event['cardToken'],
            idempotency_key=idempotency_token
        )
    
    charge = context.step(charge_payment, name='charge-payment')
    
    return {'statusCode': 200, 'charge': charge}
```

------

**Utilisez la at-most-once sémantique :** pour les opérations critiques qui ne doivent jamais être dupliquées (transactions financières, déductions d'inventaire), configurez at-most-once le mode d'exécution.

------
#### [ TypeScript ]

```
// Critical operation that must not duplicate
await context.step('deduct-inventory', async () => {
  return inventoryService.deduct(event.productId, event.quantity);
}, {
  executionMode: 'AT_MOST_ONCE_PER_RETRY'
});
```

------
#### [ Python ]

```
# Critical operation that must not duplicate
context.step(
    lambda _: inventory_service.deduct(event['productId'], event['quantity']),
    name='deduct-inventory',
    config=StepConfig(execution_mode='AT_MOST_ONCE_PER_RETRY')
)
```

------

**Identité de la base de données :** utilisez check-before-write des modèles, des mises à jour conditionnelles ou des opérations de modification pour éviter les doublons d'enregistrements.

## Gérez efficacement l'état
<a name="durable-state-management"></a>

Chaque point de contrôle enregistre l'état dans un stockage permanent. Les objets d'état volumineux augmentent les coûts, ralentissent le pointage des points de contrôle et ont un impact sur les performances. Stockez uniquement les données essentielles de coordination du flux de travail.

**Maintenez l'état au minimum :**
+ Magasin IDs et références, pas des objets complets
+ Récupérez des données détaillées en quelques étapes, selon les besoins
+ Utilisez Amazon S3 ou DynamoDB pour les données volumineuses, transmettez les références dans l'état
+ Évitez de transmettre de grosses charges utiles entre les étapes

------
#### [ TypeScript ]

```
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js';

export const handler = withDurableExecution(
  async (event: any, context: DurableContext) => {
    // Store only the order ID, not the full order object
    const orderId = event.orderId;
    
    // Fetch data within each step as needed
    await context.step('validate-order', async () => {
      const order = await orderService.getOrder(orderId);
      return validateOrder(order);
    });
    
    await context.step('process-payment', async () => {
      const order = await orderService.getOrder(orderId);
      return processPayment(order);
    });
    
    return { statusCode: 200, orderId };
  }
);
```

------
#### [ Python ]

```
from aws_durable_execution_sdk_python import durable_execution, DurableContext

@durable_execution
def handler(event, context: DurableContext):
    # Store only the order ID, not the full order object
    order_id = event['orderId']
    
    # Fetch data within each step as needed
    context.step(
        lambda _: validate_order(order_service.get_order(order_id)),
        name='validate-order'
    )
    
    context.step(
        lambda _: process_payment(order_service.get_order(order_id)),
        name='process-payment'
    )
    
    return {'statusCode': 200, 'orderId': order_id}
```

------

## Concevez des étapes efficaces
<a name="durable-step-design"></a>

Les étapes sont l'unité de travail fondamentale des fonctions durables. Des étapes bien conçues facilitent la compréhension, le débogage et la maintenance des flux de travail.

**Principes de conception des étapes :**
+ **Utilisez des noms descriptifs** : les noms tels que `validate-order` « `step1` instead » facilitent la compréhension des journaux et des erreurs
+ **Conservez les noms statiques** : n'utilisez pas de noms dynamiques avec des horodatages ou des valeurs aléatoires. Les noms des étapes doivent être déterministes pour la rediffusion
+ **Équilibrez la granularité** : divisez les opérations complexes en étapes ciblées, mais évitez les petites étapes excessives qui augmentent la charge des points de contrôle
+ **Opérations liées au groupe** - Les opérations qui devraient réussir ou échouer ensemble appartiennent à la même étape

## Utilisez efficacement les opérations d'attente
<a name="durable-wait-operations"></a>

Les opérations d'attente suspendent l'exécution sans consommer de ressources ni entraîner de coûts. Utilisez-les au lieu de faire fonctionner Lambda.

**Attentes basées sur le temps :** à utiliser `context.wait()` pour les retards au lieu de `setTimeout` ou. `sleep`

**Rappels externes :** à utiliser `context.waitForCallback()` lorsque vous attendez des systèmes externes. Définissez toujours des délais d'attente pour éviter les temps d'attente indéfinis.

**Sondage :** `context.waitForCondition()` à utiliser avec un recul exponentiel pour interroger les services externes sans les surcharger.

------
#### [ TypeScript ]

```
// Wait 24 hours without cost
await context.wait({ seconds: 86400 });

// Wait for external callback with timeout
const result = await context.waitForCallback(
  'external-job',
  async (callbackId) => {
    await externalService.submitJob({
      data: event.data,
      webhookUrl: `https://api.example.com/callbacks/${callbackId}`
    });
  },
  { timeout: { seconds: 3600 } }
);
```

------
#### [ Python ]

```
# Wait 24 hours without cost
context.wait(86400)

# Wait for external callback with timeout
result = context.wait_for_callback(
    lambda callback_id: external_service.submit_job(
        data=event['data'],
        webhook_url=f'https://api.example.com/callbacks/{callback_id}'
    ),
    name='external-job',
    config=WaitForCallbackConfig(timeout_seconds=3600)
)
```

------

## Considérations supplémentaires
<a name="durable-additional-considerations"></a>

**Gestion des erreurs :** réessayez les échecs transitoires tels que les délais d'expiration du réseau et les limites de débit. Ne réessayez pas en cas d'échec permanent, comme une saisie non valide ou une erreur d'authentification. Configurez des stratégies de nouvelles tentatives avec des taux de tentatives et d'interruption maximaux appropriés. Pour des exemples détaillés, voir [Gestion des erreurs et nouvelles tentatives](durable-execution-sdk-retries.md).

**Performances :** minimisez la taille des points de contrôle en stockant des références plutôt que des charges utiles complètes. Utilisez `context.parallel()` et `context.map()` pour exécuter simultanément des opérations indépendantes. Opérations liées au batch pour réduire la surcharge des points de contrôle.

**Gestion des versions :** invoquez des fonctions avec des numéros de version ou des alias pour attribuer les exécutions à des versions de code spécifiques. Assurez-vous que les nouvelles versions du code peuvent gérer l'état des anciennes versions. Ne renommez pas les étapes et ne modifiez pas leur comportement de manière à interrompre la rediffusion.

**Sérialisation :** utilisez des types compatibles JSON pour les entrées et les résultats des opérations. Convertissez les dates en chaînes ISO et les objets personnalisés en objets simples avant de les transmettre à des opérations durables.

**Surveillance :** activez la journalisation structurée avec les noms d'exécution IDs et d'étape. Configurez CloudWatch des alarmes pour les taux d'erreur et la durée d'exécution. Utilisez le traçage pour identifier les goulots d'étranglement. Pour obtenir des instructions détaillées, consultez la section [Surveillance et débogage](durable-monitoring.md).

**Tests :** testez le chemin heureux, la gestion des erreurs et le comportement des rediffusions. Testez des scénarios de temporisation pour les rappels et les temps d'attente. Utilisez des tests locaux pour réduire le temps d'itération. Pour obtenir des instructions détaillées, voir [Tester des fonctions durables](durable-testing.md).

**Erreurs courantes à éviter :** n'imbriquez pas les `context.step()` appels, utilisez plutôt des contextes enfantins. Enveloppez les opérations non déterministes par étapes. Définissez toujours des délais d'expiration pour les rappels. Équilibrez la granularité des étapes avec la surcharge des points de contrôle. Stockez les références plutôt que les objets volumineux dans l'état.

## Ressources supplémentaires
<a name="durable-additional-resources"></a>
+ [Documentation du SDK Python](https://github.com/aws/aws-durable-execution-sdk-python/tree/main/docs) - Référence complète des API, modèles de test et exemples avancés
+ [TypeScript Documentation du SDK](https://github.com/aws/aws-durable-execution-sdk-js/tree/main/docs) : référence complète des API, modèles de test et exemples avancés