Idempotenza - AWS Lambda

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à.

Idempotenza

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 richiamare una funzione durevole con una chiave di idempotenza (parametro del nome di esecuzione).

Nomi di esecuzione

È 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

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 Non è mai esistito o la conservazione è scaduta N/D Nuova esecuzione iniziata: Lambda avvia una nuova esecuzione con il nome fornito
3 In esecuzione 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 In esecuzione No Errore: Lambda restituisce un DurableExecutionAlreadyExists errore perché un'esecuzione con questo nome è già in esecuzione con un payload diverso
5 Chiuso (riuscito, non riuscito, interrotto o scaduto) Avvio idempotente: Lambda restituisce le informazioni di esecuzione esistenti senza iniziare una nuova esecuzione. Viene restituito il risultato dell'esecuzione chiusa
6 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

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

  2. 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

  3. 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.