

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Richiamo di funzioni Lambda durevoli
<a name="durable-invoking"></a>

Le funzioni Lambda durevoli supportano gli stessi metodi di invocazione delle funzioni Lambda standard. È possibile richiamare funzioni durevoli in modo sincrono, asincrono o tramite mappature delle sorgenti degli eventi. Il processo di invocazione è identico alle funzioni standard, ma le funzioni durevoli forniscono funzionalità aggiuntive per le esecuzioni di lunga durata e la gestione automatica dello stato.

## Metodi di invocazione
<a name="durable-invoking-methods"></a>

**Invocazione sincrona: richiama** una funzione durevole e attendi la risposta. Le chiamate sincrone sono limitate dalla Lambda a 15 minuti (o meno, a seconda della funzione configurata e del timeout di esecuzione). Utilizza la chiamata sincrona quando hai bisogno di risultati immediati o quando esegui l'integrazione con servizi che prevedono una risposta. APIs È possibile utilizzare le operazioni di attesa per un calcolo efficiente senza interrompere il chiamante: la chiamata attende il completamento dell'intera esecuzione durevole. [Per avvii di esecuzione idempotenti, utilizzate il parametro del nome dell'esecuzione come descritto in Idempotency.](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
```

**Richiamata asincrona: mette in coda un evento per l'elaborazione senza attendere una risposta**. Lambda mette l'evento in coda e ritorna immediatamente. Le chiamate asincrone supportano durate di esecuzione fino a 1 anno. Utilizza la chiamata asincrona per scenari o quando l'elaborazione può avvenire in background. fire-and-forget [Per avvii di esecuzione idempotenti, utilizzate il parametro del nome dell'esecuzione come descritto in Idempotenza.](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
```

**Mappature delle sorgenti degli eventi: configura** Lambda per richiamare automaticamente la tua funzione duratura quando i record sono disponibili da servizi basati su stream o code come Amazon SQS, Kinesis o DynamoDB. Le mappature delle sorgenti degli eventi analizzano l'origine dell'evento e richiamano la funzione con batch di record. [Per i dettagli sull'utilizzo delle mappature delle sorgenti degli eventi con funzioni durevoli, inclusi i limiti di durata dell'esecuzione, consulta Mappature delle sorgenti degli eventi con funzioni durevoli.](durable-invoking-esm.md)

[[Per dettagli completi su ciascun metodo di invocazione, vedere invocazione sincrona e chiamata asincrona.](invocation-async.md)](invocation-sync.md)

**Nota**  
Le funzioni durevoli supportano dead-letter queues (DLQs) per la gestione degli errori, ma non supportano le destinazioni Lambda. Configura un DLQ per acquisire i record delle chiamate non riuscite.

## ARNs Requisito qualificato
<a name="durable-invoking-qualified-arns"></a>

Le funzioni durevoli richiedono identificatori qualificati per la chiamata. È necessario richiamare funzioni durevoli utilizzando un numero di versione, un alias o. `$LATEST` È possibile utilizzare un ARN completo o un nome di funzione con version/alias suffisso. Non è possibile utilizzare un identificatore non qualificato (senza una versione o un suffisso di alias).

**Invocazioni valide:**

```
# 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
```

**Invocazioni non valide:**

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

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

Questo requisito garantisce che le esecuzioni durevoli rimangano coerenti per tutto il loro ciclo di vita. Quando inizia un'esecuzione durevole, viene associata alla versione della funzione specifica. Se la funzione viene messa in pausa e riprende ore o giorni dopo, Lambda richiama la stessa versione che ha avviato l'esecuzione, garantendo la coerenza del codice nell'intero flusso di lavoro.

**Best practice**  
Utilizza versioni numerate o alias per funzioni durevoli di produzione anziché. `$LATEST` Le versioni numerate sono immutabili e supportano la riproduzione deterministica. Facoltativamente, gli alias forniscono un riferimento stabile che è possibile aggiornare per indirizzare a nuove versioni senza modificare il codice di invocazione. Quando si aggiorna un alias, le nuove esecuzioni utilizzano la nuova versione, mentre le esecuzioni in corso continuano con la versione originale. È possibile utilizzarla `$LATEST` per la prototipazione o per abbreviare i tempi di implementazione durante lo sviluppo, tenendo presente che le esecuzioni potrebbero non essere riprodotte correttamente (o addirittura fallire) se il codice sottostante cambia durante l'esecuzione.

## Comprendere il ciclo di vita dell'esecuzione
<a name="durable-invoking-execution-lifecycle"></a>

Quando richiami una funzione duratura, Lambda crea un'esecuzione durevole che può includere più chiamate di funzioni:

1. **Richiamata iniziale: la richiesta di invocazione crea una nuova** esecuzione durevole. Lambda assegna un ID di esecuzione univoco e avvia l'elaborazione.

1. **Esecuzione e checkpoint: man mano che** la funzione esegue operazioni durature, l'SDK crea checkpoint che tengono traccia dei progressi.

1. **Sospensione (se necessaria):** se la funzione utilizza attese durature, ad esempio or, `wait` o ripetizioni automatiche dei passaggi`waitForCallback`, Lambda sospende l'esecuzione e interrompe l'addebito del tempo di elaborazione.

1. **Ripresa:** quando è il momento di riprendere (anche dopo nuovi tentativi), Lambda richiama nuovamente la funzione. L'SDK riproduce il registro del checkpoint e continua dal punto in cui l'esecuzione si è interrotta.

1. **Completamento:** quando la funzione restituisce un risultato finale o genera un errore non gestito, l'esecuzione durevole viene completata.

Per le chiamate sincrone, il chiamante attende il completamento dell'intera esecuzione durevole, comprese le eventuali operazioni di attesa. Se l'esecuzione supera il timeout di chiamata (15 minuti o meno), la chiamata scade. Per le chiamate asincrone, Lambda ritorna immediatamente e l'esecuzione continua indipendentemente. Usa l'esecuzione durevole APIs per tenere traccia dello stato di esecuzione e recuperare i risultati finali.

## Richiamo dal codice dell'applicazione
<a name="durable-invoking-with-sdk"></a>

Utilizzate il AWS SDKs per richiamare funzioni durevoli dal codice dell'applicazione. Il processo di invocazione è identico alle funzioni 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'})
)
```

------

## Invocazioni concatenate
<a name="durable-invoking-chained"></a>

Le funzioni durevoli possono richiamare altre funzioni durevoli e non durevoli utilizzando l'operazione da. `invoke` `DurableContext` Questo crea una chiamata concatenata in cui la funzione chiamante attende (sospende) il completamento della funzione invocata:

------
#### [ 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)}
```

------

Le invocazioni concatenate creano un checkpoint nella funzione chiamante. Se la funzione chiamante viene interrotta, riprende dal checkpoint con il risultato della funzione richiamata, senza richiamare nuovamente la funzione.

**Nota**  
Le chiamate concatenate tra più account non sono supportate. La funzione richiamata deve trovarsi nello stesso AWS account della funzione chiamante.

# Mappature delle sorgenti degli eventi con funzioni durevoli
<a name="durable-invoking-esm"></a>

Le funzioni durevoli funzionano con tutte le mappature delle sorgenti degli eventi Lambda. Configura le mappature delle sorgenti degli eventi per funzioni durevoli nello stesso modo in cui le configuri per le funzioni standard. Le mappature delle sorgenti degli eventi analizzano automaticamente sorgenti di eventi come Amazon SQS, Kinesis e DynamoDB Streams e richiamano la tua funzione con batch di record.

Le mappature delle sorgenti degli eventi sono utili per funzioni durevoli che elaborano flussi o code con flussi di lavoro complessi e in più fasi. Ad esempio, puoi creare una funzione durevole che elabora i messaggi Amazon SQS con nuovi tentativi, chiamate API esterne e approvazioni umane.

## In che modo le mappature delle sorgenti degli eventi richiamano funzioni durevoli
<a name="durable-esm-invocation-behavior"></a>

Le mappature delle sorgenti degli eventi richiamano funzioni durevoli in modo sincrono, in attesa del completamento dell'esecuzione duratura completa prima di elaborare il batch successivo o di contrassegnare i record come elaborati. Se il tempo di esecuzione duraturo totale supera i 15 minuti, l'esecuzione scade e fallisce. La mappatura dell'origine degli eventi riceve un'eccezione di timeout e la gestisce in base alla configurazione dei nuovi tentativi.

## Limite di esecuzione di 15 minuti
<a name="durable-esm-duration-limit"></a>

Quando le funzioni durevoli vengono richiamate dalle mappature delle sorgenti degli eventi, la durata totale dell'esecuzione durevole non può superare i 15 minuti. Questo limite si applica all'intera esecuzione durevole dall'inizio al completamento, non solo alle chiamate di singole funzioni.

Questo limite di 15 minuti è separato dal timeout della funzione Lambda (anch'esso massimo 15 minuti). Il timeout della funzione controlla per quanto tempo può essere eseguita ogni singola chiamata, mentre il timeout di esecuzione duraturo controlla il tempo totale trascorso dall'inizio dell'esecuzione al completamento.

**Scenari di esempio:**
+ **Valido:** una funzione durevole elabora un messaggio Amazon SQS in tre passaggi, ciascuno dei quali richiede 2 minuti, quindi attende 5 minuti prima di completare un passaggio finale. Tempo di esecuzione totale: 11 minuti. Funziona perché il totale è inferiore a 15 minuti.
+ **Non valido:** una funzione durevole elabora un messaggio Amazon SQS, completa l'elaborazione iniziale in 2 minuti, quindi attende 20 minuti per una richiamata esterna prima del completamento. Tempo di esecuzione totale: 22 minuti. Questa operazione supera il limite di 15 minuti e avrà esito negativo.
+ Non **valido:** una funzione durevole elabora un record Kinesis con più operazioni di attesa per un totale di 30 minuti tra i passaggi. Anche se ogni singola chiamata viene completata rapidamente, il tempo di esecuzione totale supera i 15 minuti.

**Importante**  
Configura il timeout di esecuzione duraturo su 15 minuti o meno quando utilizzi le mappature delle sorgenti degli eventi, altrimenti la creazione della mappatura delle sorgenti degli eventi avrà esito negativo. Se il flusso di lavoro richiede tempi di esecuzione più lunghi, utilizza lo schema di funzioni intermedie descritto di seguito.

## Configurazione delle mappature delle sorgenti degli eventi
<a name="durable-esm-configuration"></a>

Configura le mappature delle sorgenti degli eventi per funzioni durevoli utilizzando la console Lambda, oppure. AWS CLI AWS SDKs Tutte le proprietà standard di mappatura delle sorgenti degli eventi si applicano alle funzioni durevoli:

```
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
```

Ricordarsi di utilizzare un ARN qualificato (con numero di versione o alias) quando si configurano le mappature delle sorgenti degli eventi per funzioni durevoli.

## Gestione degli errori con le mappature delle sorgenti degli eventi
<a name="durable-esm-error-handling"></a>

Le mappature delle sorgenti degli eventi forniscono una gestione degli errori integrata che funziona con funzioni durevoli:
+ **Comportamento dei nuovi tentativi:** se la chiamata iniziale fallisce, la mappatura delle sorgenti degli eventi riprova in base alla configurazione dei nuovi tentativi. Configura il numero massimo di tentativi e gli intervalli di nuovi tentativi in base alle tue esigenze.
+ Code di **lettere scadenti: configura una coda** di lettere scadenti per acquisire i record che hanno esito negativo dopo tutti i nuovi tentativi. Ciò impedisce la perdita di messaggi e consente l'ispezione manuale dei record non riusciti.
+ **Errori parziali dei batch:** per Amazon SQS e Kinesis, utilizza la segnalazione parziale degli errori dei batch per elaborare i record singolarmente e riprovare solo i record non riusciti.
+ **Bisect in caso di errore:** per Kinesis e DynamoDB Streams, abilita bisect on error per dividere i batch non riusciti e isolare i record problematici.

**Nota**  
Le funzioni durevoli supportano dead-letter queues (DLQs) per la gestione degli errori, ma non supportano le destinazioni Lambda. Configura un DLQ per acquisire i record delle chiamate non riuscite.

[Per informazioni complete sulla gestione degli errori di mappatura delle sorgenti degli eventi, consulta la sezione Mappature delle sorgenti degli eventi.](invocation-eventsourcemapping.md)

## Utilizzo di una funzione intermedia per flussi di lavoro di lunga durata
<a name="durable-esm-intermediary-function"></a>

Se il completamento del flusso di lavoro richiede più di 15 minuti, utilizzate una funzione Lambda standard intermedia tra la mappatura della sorgente dell'evento e la funzione duratura. La funzione intermediaria riceve gli eventi dalla mappatura delle sorgenti degli eventi e richiama la funzione duratura in modo asincrono, rimuovendo il limite di esecuzione di 15 minuti.

Questo modello disaccoppia il modello di invocazione sincrona della mappatura della sorgente degli eventi dal modello di esecuzione a lunga durata della funzione duratura. La mappatura delle sorgenti degli eventi richiama la funzione intermedia, che ritorna rapidamente dopo l'avvio dell'esecuzione duratura. La funzione durable viene quindi eseguita in modo indipendente per tutto il tempo necessario (fino a 1 anno).

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

Il modello di funzione intermedia utilizza tre componenti:

1. **Mappatura delle sorgenti degli eventi:** interroga l'origine dell'evento (Amazon SQS, Kinesis, DynamoDB Streams) e richiama la funzione intermediaria in modo sincrono con i batch di record.

1. **Funzione intermedia: una funzione** Lambda standard che riceve gli eventi dalla mappatura dell'origine degli eventi, convalida e trasforma i dati se necessario e richiama la funzione duratura in modo asincrono. Questa funzione si completa rapidamente (in genere in meno di 1 secondo) e restituisce il controllo alla mappatura delle sorgenti degli eventi.

1. **Funzione durevole:** elabora l'evento con una logica complessa a più fasi che può essere eseguita per periodi prolungati. Richiamato in modo asincrono, quindi non è vincolato dal limite di 15 minuti.

### Implementazione
<a name="durable-esm-intermediary-implementation"></a>

La funzione intermediaria riceve l'intero evento dalla mappatura della sorgente dell'evento e richiama la funzione durevole in modo asincrono. Utilizzate il parametro del nome di esecuzione per garantire l'avvio di un'esecuzione idempotente, evitando l'elaborazione duplicata se la mappatura dell'origine dell'evento riprova:

------
#### [ 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}
```

------

Per l'idempotenza nella funzione intermedia stessa, usate [Powertools per](https://docs.aws.amazon.com//powertools/) evitare invocazioni duplicate della funzione durable se la AWS Lambda mappatura della sorgente dell'evento riprova la funzione intermediaria.

La funzione durable riceve il payload con il nome di esecuzione ed elabora tutti i record con una logica di lunga durata:

------
#### [ 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
    }
```

------

### Considerazioni chiave
<a name="durable-esm-intermediary-tradeoffs"></a>

Questo modello rimuove il limite di esecuzione di 15 minuti disaccoppiando la mappatura della sorgente dell'evento dall'esecuzione durevole. La funzione intermedia ritorna immediatamente dopo l'avvio dell'esecuzione duratura, consentendo alla mappatura della fonte dell'evento di continuare l'elaborazione. La funzione durable viene quindi eseguita in modo indipendente per tutto il tempo necessario.

La funzione intermedia ha successo quando richiama la funzione durable, non quando l'esecuzione duratura viene completata. Se l'esecuzione duratura fallisce in un secondo momento, la mappatura della fonte dell'evento non riproverà perché il batch è già stato elaborato correttamente. Implementa la gestione degli errori nella funzione durable e configura le code di lettere morte per le esecuzioni non riuscite.

Utilizzate il parametro del nome di esecuzione per garantire l'avvio di un'esecuzione idempotente. Se la mappatura dell'origine dell'evento riprova la funzione intermedia, la funzione durable non avvierà un'esecuzione duplicata perché il nome dell'esecuzione esiste già.

## Fonti di eventi supportate
<a name="durable-esm-supported-sources"></a>

Le funzioni durevoli supportano tutte le sorgenti di eventi Lambda che utilizzano le mappature delle sorgenti degli eventi:
+ Code Amazon SQS (standard e FIFO)
+ Flussi Kinesis
+ DynamoDB Streams
+ Amazon Managed Streaming for Apache Kafka (Amazon MSK)
+ Apache Kafka gestito dal cliente
+ Amazon MQ (ActiveMQ e RabbitMQ)
+ Flussi di modifica di Amazon DocumentDB

Tutti i tipi di sorgenti di eventi sono soggetti al limite di esecuzione durevole di 15 minuti quando si richiamano funzioni durevoli.

# Riprova per le funzioni durevoli Lambda
<a name="durable-execution-sdk-retries"></a>

Le funzioni durevoli offrono funzionalità di ripetizione automatica che rendono le applicazioni resilienti ai guasti transitori. L'SDK gestisce i nuovi tentativi a due livelli: ripetuti passaggi per gli errori della logica aziendale e i tentativi di backend per gli errori dell'infrastruttura.

## Fase 3 nuovi tentativi
<a name="durable-step-retries"></a>

Quando si verifica un'eccezione non rilevata in un passaggio, l'SDK riprova automaticamente il passaggio in base alla strategia di ripetizione configurata. I nuovi tentativi di passaggio sono operazioni bloccate che consentono all'SDK di sospendere l'esecuzione e riprenderla in un secondo momento senza perdere i progressi.

### Comportamento dei tentativi di ripristino dei passaggi
<a name="durable-step-retry-behavior"></a>

La tabella seguente descrive come l'SDK gestisce le eccezioni all'interno dei passaggi:


| Scenario | Cosa succede | Impatto della misurazione | 
| --- | --- | --- | 
| Eccezione relativa ai tentativi di nuovi tentativi rimanenti | L'SDK crea un checkpoint per il nuovo tentativo e sospende la funzione. Alla chiamata successiva, il passaggio riprova con il ritardo di backoff configurato. | 1 operazione più errore, dimensione del payload | 
| Eccezione in fase iniziale senza tentativi di riprova rimanenti | Il passaggio ha esito negativo e genera un'eccezione. Se il codice del gestore non rileva questa eccezione, l'intera esecuzione fallisce. | 1 operazione più errore (dimensione del payload) | 

Quando è necessario riprovare un passaggio, l'SDK controlla lo stato del nuovo tentativo ed esce dalla chiamata Lambda se non è in esecuzione nessun altro lavoro. Ciò consente all'SDK di implementare ritardi di backoff senza consumare risorse di elaborazione. La funzione riprende automaticamente dopo il periodo di backoff.

### Configurazione delle strategie di ripetizione dei passaggi
<a name="durable-step-retry-configuration"></a>

Configura le strategie di ripetizione dei tentativi per controllare il modo in cui le fasi gestiscono gli errori. È possibile specificare il numero massimo di tentativi, gli intervalli di backoff e le condizioni per i nuovi tentativi.

**Backoff esponenziale con numero massimo di tentativi:**

------
#### [ 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)
)
```

------

**Backoff a intervallo fisso:**

------
#### [ 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)
)
```

------

**Riprova condizionale (riprova solo errori specifici):**

------
#### [ 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)
)
```

------

**Disabilita i tentativi:**

------
#### [ 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}
    )
)
```

------

Quando viene ripristinata la strategia di nuovi tentativi`shouldRetry: false`, il passaggio fallisce immediatamente senza nuovi tentativi. Usalo per operazioni che non devono essere ripetute, come i controlli dell'idempotenza o le operazioni con effetti collaterali che non possono essere ripetuti in sicurezza.

## Eccezioni all'esterno dei gradini
<a name="durable-handler-exceptions"></a>

Quando si verifica un'eccezione non rilevata nel codice del gestore ma al di fuori di qualsiasi passaggio, l'SDK contrassegna l'esecuzione come non riuscita. Ciò garantisce che gli errori nella logica dell'applicazione vengano rilevati e segnalati correttamente.


| Scenario | Cosa succede | Impatto della misurazione | 
| --- | --- | --- | 
| Eccezione nel codice del gestore al di fuori di qualsiasi passaggio | L'SDK contrassegna l'esecuzione come NON RIUSCITA e restituisce l'errore. L'eccezione non viene ritentata automaticamente. | Errore nella dimensione del payload | 

Per abilitare un nuovo tentativo automatico per il codice soggetto a errori, inseriscilo in un unico passaggio con una strategia di riprova. I passaggi prevedono un nuovo tentativo automatico con backoff configurabile, mentre il codice al di fuori dei passaggi fallisce immediatamente.

## Tentativi di backend
<a name="durable-backend-retries"></a>

I nuovi tentativi di backend si verificano quando Lambda rileva guasti dell'infrastruttura, errori di runtime o quando l'SDK non è in grado di comunicare con il servizio di esecuzione durevole. Lambda riprova automaticamente questi errori per aiutare le funzioni durevoli a riprendersi da problemi transitori dell'infrastruttura.

### Scenari di nuovi tentativi nel backend
<a name="durable-backend-retry-scenarios"></a>

Lambda riprova automaticamente la funzione quando si verificano i seguenti scenari:
+ **Errori interni del servizio**: quando Lambda o il servizio di esecuzione durevole restituisce un errore 5xx, che indica un problema temporaneo del servizio.
+ **Limitazione: quando** la funzione viene limitata a causa di limiti di concorrenza o quote di servizio.
+ **Timeout**: quando l'SDK non riesce a raggiungere il servizio di esecuzione durevole entro il periodo di timeout.
+ **Errori di inizializzazione della sandbox**: quando Lambda non è in grado di inizializzare l'ambiente di esecuzione.
+ **Errori di runtime**: quando il runtime Lambda rileva errori esterni al codice della funzione, come out-of-memory errori o arresti anomali del processo.
+ **Errori del token di checkpoint non valido: quando il token** di checkpoint non è più valido, in genere a causa di modifiche dello stato sul lato del servizio.

La tabella seguente descrive come l'SDK gestisce questi scenari:


| Scenario | Cosa succede | Impatto della misurazione | 
| --- | --- | --- | 
| Errore di runtime esterno al gestore durevole (OOM, timeout, crash) | Lambda riprova automaticamente la chiamata. L'SDK riproduce a partire dall'ultimo checkpoint, saltando i passaggi completati. | Errore: dimensione del payload \$1 1 operazione per nuovo tentativo | 
| Errore di servizio (5xx) o timeout durante la chiamata/CheckpointDurableExecutionGetDurableExecutionState APIs | Lambda riprova automaticamente la chiamata. L'SDK viene riprodotto a partire dall'ultimo checkpoint. | Errore: dimensione del payload \$1 1 operazione per nuovo tentativo | 
| Limitazione (429) o token di checkpoint non valido durante la chiamata/CheckpointDurableExecutionGetDurableExecutionState APIs | Lambda ritenta automaticamente la chiamata con un backoff esponenziale. L'SDK viene riprodotto a partire dall'ultimo checkpoint. | Errore: dimensione del payload \$1 1 operazione per nuovo tentativo | 
| Errore del client (4xx, eccetto 429 e token non valido) quando/CheckpointDurableExecutionGetDurableExecutionState APIs | L'SDK contrassegna l'esecuzione come NON RIUSCITA. Non si verifica alcun nuovo tentativo automatico perché l'errore indica un problema permanente. | Errore: dimensione del payload | 

I tentativi di backend utilizzano il backoff esponenziale e continuano fino al successo della funzione o al raggiungimento del timeout di esecuzione. Durante la riproduzione, l'SDK salta i checkpoint completati e continua l'esecuzione dell'ultima operazione riuscita, assicurando che la funzione non riesegua il lavoro completato.

## Riprova le migliori pratiche
<a name="durable-retry-best-practices"></a>

Segui queste best practice per configurare le strategie di riprova:
+ **Configura strategie esplicite di nuovi tentativi**: non fare affidamento sul comportamento predefinito dei nuovi tentativi in produzione. Configura strategie di riprova esplicite con un numero massimo di tentativi e intervalli di backoff appropriati per il tuo caso d'uso.
+ **Utilizza tentativi condizionali: implementa la `shouldRetry` logica per riprovare** solo gli errori transitori (limiti di velocità, timeout) e fallire rapidamente in caso di errori permanenti (errori di convalida, non rilevati).
+ **Imposta il numero massimo di tentativi appropriato**: equilibrio tra resilienza e tempo di esecuzione. Troppi tentativi possono ritardare il rilevamento degli errori, mentre un numero troppo basso può causare errori non necessari.
+ **Utilizza il backoff esponenziale: il backoff** esponenziale riduce il carico sui servizi a valle e aumenta la probabilità di ripristino in caso di guasti transitori.
+ Raccogli il codice soggetto a **errori** in fasi: il codice al di fuori dei passaggi non può essere riprovato automaticamente. Raccogli le chiamate API esterne, le query sul database e altre operazioni soggette a errori in fasi con strategie di riprova.
+ **Monitora le metriche dei tentativi**: monitora le operazioni di ripetizione dei tentativi e gli errori di esecuzione in CloudWatch Amazon per identificare modelli e ottimizzare le strategie di ripetizione dei tentativi.

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

Le funzioni durevoli forniscono un'idempotenza integrata per gli avvii di esecuzione tramite i nomi di esecuzione. Quando fornisci un nome di esecuzione, Lambda lo utilizza per prevenire esecuzioni duplicate e consentire nuovi tentativi sicuri delle richieste di invocazione. Per impostazione predefinita, le fasi hanno una semantica di at-least-once esecuzione: durante la riproduzione, l'SDK restituisce risultati puntuali senza rieseguire i passaggi completati, ma la logica aziendale deve essere idempotente per gestire potenziali tentativi prima del completamento.

**Nota**  
Le mappature delle sorgenti degli eventi Lambda (ESM) non supportano l'idempotenza al momento del lancio. Pertanto, ogni chiamata (inclusi i nuovi tentativi) avvia una nuova esecuzione durevole. Per garantire un'esecuzione idempotente con mappature delle sorgenti degli eventi, implementate la logica di idempotenza nel codice della funzione, ad esempio con Powertools [for, oppure AWS Lambda utilizzate una normale funzione Lambda come proxy (dispatcher) per](https://docs.aws.amazon.com//powertools/) richiamare una funzione durevole con una chiave di idempotenza (parametro del nome di esecuzione).

## Nomi di esecuzione
<a name="durable-idempotency-execution-names"></a>

È possibile fornire un nome di esecuzione quando si richiama una funzione durevole. Il nome di esecuzione funge da chiave di idempotenza, che consente di riprovare in sicurezza le richieste di invocazione senza creare esecuzioni duplicate. Se non fornisci un nome, Lambda genera automaticamente un ID di esecuzione univoco.

I nomi di esecuzione devono essere univoci all'interno del tuo account e della tua regione. Quando si richiama una funzione con un nome di esecuzione già esistente, il comportamento di Lambda dipende dallo stato dell'esecuzione esistente e dalla corrispondenza del payload.

## Comportamento di idempotenza
<a name="durable-idempotency-behavior"></a>

La tabella seguente descrive come Lambda gestisce le richieste di chiamata in base al fatto che tu fornisca un nome di esecuzione, lo stato di esecuzione esistente e se il payload corrisponde:


| Scenario | Nome fornito? | Stato di esecuzione esistente | Payload identico? | Comportamento | 
| --- | --- | --- | --- | --- | 
| 1 | No | N/D | N/D | Nuova esecuzione iniziata: Lambda genera un ID di esecuzione univoco e avvia una nuova esecuzione | 
| 2 | Sì | Non è mai esistito o la conservazione è scaduta | N/D | Nuova esecuzione iniziata: Lambda avvia una nuova esecuzione con il nome fornito | 
| 3 | Sì | In esecuzione | Sì | Avvio idempotente: Lambda restituisce le informazioni di esecuzione esistenti senza avviare un duplicato. Per le chiamate sincrone, ciò funge da ricollegamento all'esecuzione in esecuzione | 
| 4 | Sì | In esecuzione | No | Errore: Lambda restituisce un DurableExecutionAlreadyExists errore perché un'esecuzione con questo nome è già in esecuzione con un payload diverso | 
| 5 | Sì | Chiuso (riuscito, non riuscito, interrotto o scaduto) | Sì | Avvio idempotente: Lambda restituisce le informazioni di esecuzione esistenti senza iniziare una nuova esecuzione. Viene restituito il risultato dell'esecuzione chiusa | 
| 6 | Sì | Chiuso (riuscito, fallito, interrotto o scaduto) | No | Errore: Lambda restituisce un DurableExecutionAlreadyExists errore perché un'esecuzione con questo nome è già stata completata con un payload diverso | 

**Nota**  
Gli scenari 3 e 5 dimostrano un comportamento idempotente in cui Lambda gestisce in modo sicuro le richieste di invocazione duplicate restituendo le informazioni di esecuzione esistenti anziché creare duplicati.

## Fase: idempotenza
<a name="durable-idempotency-steps"></a>

Per impostazione predefinita, i passaggi hanno una semantica di at-least-once esecuzione. Quando la funzione viene riprodotta dopo un'attesa, un callback o un errore, l'SDK confronta ogni passaggio con il registro del checkpoint. Per i passaggi già completati, l'SDK restituisce il risultato del checkpoint senza rieseguire la logica dei passaggi. Tuttavia, se un passaggio fallisce o la funzione viene interrotta prima del completamento del passaggio, il passaggio può essere eseguito più volte.

La logica aziendale racchiusa in fasi deve essere idempotente per gestire potenziali nuovi tentativi. Utilizza le chiavi di idempotenza per garantire che operazioni come pagamenti o scritture di database vengano eseguite una sola volta, anche se il passaggio riprova.

**Esempio: utilizzo delle chiavi di idempotenza in fasi**

------
#### [ 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}
```

------

È possibile configurare i passaggi per utilizzare la semantica di at-most-once esecuzione impostando la modalità di esecuzione su. `AT_MOST_ONCE_PER_RETRY` Ciò garantisce che il passaggio venga eseguito al massimo una volta per ogni nuovo tentativo, ma potrebbe non essere eseguito affatto se la funzione viene interrotta prima del completamento del passaggio.

L'SDK applica la replay deterministica convalidando che i nomi e l'ordine delle fasi corrispondano al registro del checkpoint durante la ripetizione. Se il codice tenta di eseguire i passaggi in un ordine diverso o con nomi diversi, l'SDK genera un. `NonDeterministicExecutionError`

**Come funziona il replay con i passaggi completati:**

1. Prima chiamata: la funzione esegue il passaggio A, crea il checkpoint, quindi attende

1. Seconda invocazione (dopo l'attesa): la funzione viene riprodotta dall'inizio, la fase A restituisce immediatamente il risultato del checkpoint senza rieseguirla, quindi continua con la fase B

1. Terza invocazione (dopo un'altra attesa): la funzione viene riprodotta dall'inizio, i passaggi A e B restituiscono istantaneamente i risultati del checkpoint, quindi prosegue con la fase C

Questo meccanismo di replay assicura che i passaggi completati non vengano rieseguiti, ma la logica aziendale deve comunque essere idempotente per gestire i nuovi tentativi prima del completamento.