SDK für langlebige Ausführung - AWS Lambda

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

SDK für langlebige Ausführung

Das Durable Execution SDK ist die Grundlage für die Entwicklung langlebiger Funktionen. Es bietet die Grundelemente, die Sie benötigen, um den Fortschritt zu überprüfen, Wiederholungsversuche zu verarbeiten und den Ausführungsablauf zu verwalten. Das SDK abstrahiert die Komplexität der Verwaltung und Wiedergabe von Checkpoints und ermöglicht es Ihnen, sequentiellen Code zu schreiben, der automatisch fehlertolerant wird.

Das SDK ist für JavaScript TypeScript, und Python verfügbar. Eine vollständige API-Dokumentation und Beispiele finden Sie im JavaScript/TypeScript SDK und im Python-SDK unter GitHub.

DurableContext

Das SDK stellt Ihrer Funktion ein DurableContext Objekt zur Verfügung, das alle dauerhaften Operationen verfügbar macht. Dieser Kontext ersetzt den Standard-Lambda-Kontext und bietet Methoden für die Erstellung von Checkpoints, die Verwaltung des Ausführungsflusses und die Koordination mit externen Systemen.

Um das SDK zu verwenden, umschließen Sie Ihren Lambda-Handler mit dem Durable Execution Wrapper:

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

Der Wrapper fängt Ihren Funktionsaufruf ab, lädt alle vorhandenen Checkpoint-Logs und stellt das zur Verfügung, das Replay und Checkpointing verwaltet. DurableContext

Was macht das SDK

Das SDK erfüllt drei wichtige Aufgaben, die eine dauerhafte Ausführung ermöglichen:

Checkpoint-Verwaltung: Das SDK erstellt automatisch Checkpoints, wenn Ihre Funktion dauerhafte Operationen ausführt. Jeder Checkpoint zeichnet den Operationstyp, die Eingaben und die Ergebnisse auf. Wenn Ihre Funktion einen Schritt abgeschlossen hat, behält das SDK den Checkpoint bei, bevor der Vorgang fortgesetzt wird. Dadurch wird sichergestellt, dass Ihre Funktion nach jeder abgeschlossenen Operation wieder aufgenommen werden kann, falls sie unterbrochen wird.

Koordination der Wiedergabe: Wenn Ihre Funktion nach einer Pause oder Unterbrechung wieder aufgenommen wird, führt das SDK eine Wiederholung durch. Es führt Ihren Code von Anfang an aus, überspringt jedoch abgeschlossene Operationen und verwendet gespeicherte Checkpoint-Ergebnisse, anstatt sie erneut auszuführen. Das SDK stellt sicher, dass die Wiedergabe deterministisch ist. Bei denselben Eingaben und demselben Checkpoint-Log erzeugt Ihre Funktion dieselben Ergebnisse.

Zustandsisolierung: Das SDK behält den Ausführungsstatus getrennt von Ihrer Geschäftslogik bei. Jede dauerhafte Ausführung hat ihr eigenes Checkpoint-Protokoll, auf das andere Ausführungen nicht zugreifen können. Das SDK verschlüsselt Checkpoint-Daten im Ruhezustand und stellt sicher, dass der Status bei allen Wiederholungen konsistent bleibt.

Wie funktioniert Checkpointing

Wenn Sie einen dauerhaften Vorgang aufrufen, folgt das SDK dieser Reihenfolge:

  1. Nach einem vorhandenen Checkpoint suchen: Das SDK prüft, ob dieser Vorgang bereits bei einem früheren Aufruf abgeschlossen wurde. Wenn ein Checkpoint vorhanden ist, gibt das SDK das gespeicherte Ergebnis zurück, ohne den Vorgang erneut auszuführen.

  2. Führen Sie den Vorgang aus: Wenn kein Checkpoint vorhanden ist, führt das SDK Ihren Operationscode aus. Für Schritte bedeutet das, dass Sie Ihre Funktion aufrufen. Für Wartezeiten bedeutet dies, die Wiederaufnahme zu planen.

  3. Checkpoint erstellen: Nach Abschluss des Vorgangs serialisiert das SDK das Ergebnis und erstellt einen Checkpoint. Der Checkpoint umfasst den Operationstyp, den Namen, die Eingaben, das Ergebnis und den Zeitstempel.

  4. Checkpoint beibehalten: Das SDK ruft die Lambda-Checkpoint-API auf, um den Checkpoint beizubehalten. Dadurch wird sichergestellt, dass der Checkpoint dauerhaft ist, bevor die Ausführung fortgesetzt wird.

  5. Ergebnis zurückgeben: Das SDK gibt das Vorgangsergebnis an Ihren Code zurück, der mit der nächsten Operation fortgeführt wird.

Diese Reihenfolge stellt sicher, dass das Ergebnis eines Vorgangs sicher gespeichert wird, sobald er abgeschlossen ist. Wenn Ihre Funktion zu irgendeinem Zeitpunkt unterbrochen wird, kann das SDK die Wiedergabe bis zum letzten abgeschlossenen Checkpoint wiederholen.

Verhalten bei der Wiedergabe

Wenn Ihre Funktion nach einer Pause oder Unterbrechung wieder aufgenommen wird, führt das SDK eine Wiederholung durch:

  1. Checkpoint-Log laden: Das SDK ruft das Checkpoint-Log für diese Ausführung von Lambda ab.

  2. Von Anfang an ausführen: Das SDK ruft Ihre Handler-Funktion von Anfang an auf, nicht von der Stelle aus, an der sie angehalten wurde.

  3. Abgeschlossene dauerhafte Operationen überspringen: Da Ihr Code dauerhafte Operationen aufruft, überprüft das SDK jeden Vorgang anhand des Checkpoint-Logs. Bei abgeschlossenen dauerhaften Vorgängen gibt das SDK das gespeicherte Ergebnis zurück, ohne den Operationscode auszuführen.

    Anmerkung

    Wenn das Ergebnis eines untergeordneten Kontextes größer als die maximale Checkpoint-Größe (256 KB) war, wird der Code des Kontextes während der Wiedergabe erneut ausgeführt. Auf diese Weise können Sie aus den dauerhaften Vorgängen, die innerhalb des Kontextes ausgeführt wurden, umfangreiche Ergebnisse erstellen, die dann im Checkpoint-Log nachgeschlagen werden. Daher ist es unerlässlich, deterministischen Code nur im Kontext selbst auszuführen. Bei der Verwendung untergeordneter Kontexte mit großen Ergebnissen ist es eine bewährte Methode, lang andauernde oder nicht deterministische Arbeiten innerhalb von Schritten auszuführen und nur Aufgaben mit kurzer Laufzeit auszuführen, die die Ergebnisse im Kontext selbst kombinieren.

  4. Am Unterbrechungspunkt fortsetzen: Wenn das SDK einen Vorgang ohne Checkpoint erreicht, wird es normal ausgeführt und erstellt neue Checkpoints, sobald dauerhafte Operationen abgeschlossen sind.

Für diesen Wiedergabemechanismus muss Ihr Code deterministisch sein. Bei denselben Eingaben und demselben Checkpoint-Log muss Ihre Funktion dieselbe Reihenfolge von dauerhaften Operationsaufrufen ausführen. Das SDK erzwingt dies, indem es bei der Wiedergabe überprüft, ob die Namen und Typen der Operationen mit dem Checkpoint-Protokoll übereinstimmen.

Verfügbare dauerhafte Operationen

Das DurableContext bietet Operationen für verschiedene Koordinationsmuster. Bei jeder dauerhaften Operation werden automatisch Checkpoints erstellt, sodass Ihre Funktion an jedem beliebigen Punkt wieder aufgenommen werden kann.

Schritte

Führt Geschäftslogik mit automatischem Checkpoint und Wiederholungsversuch aus. Verwenden Sie Schritte für Operationen, die externe Dienste aufrufen, Berechnungen durchführen oder Logik ausführen, für die ein Checkpoint erforderlich ist. Das SDK erstellt vor und nach dem Schritt einen Checkpoint und speichert das Ergebnis zur Wiederholung.

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' )

Die Schritte unterstützen konfigurierbare Wiederholungsstrategien, Ausführungssemantik (at-most-once oder at-least-once) und benutzerdefinierte Serialisierung.

Waits (Warteereignis)

Hält die Ausführung für eine angegebene Dauer an, ohne Rechenressourcen zu verbrauchen. Das SDK erstellt einen Checkpoint, beendet den Funktionsaufruf und plant die Wiederaufnahme. Wenn die Wartezeit abgeschlossen ist, ruft Lambda Ihre Funktion erneut auf und das SDK wiederholt die Wiedergabe bis zum Wartepunkt, bevor es fortfährt.

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

Rückrufe

Callbacks ermöglichen es Ihrer Funktion, eine Pause einzulegen und darauf zu warten, dass externe Systeme Eingaben bereitstellen. Wenn Sie einen Callback erstellen, generiert das SDK eine eindeutige Callback-ID und erstellt einen Checkpoint. Ihre Funktion wird dann unterbrochen (beendet den Aufruf), ohne dass Rechengebühren anfallen. Externe Systeme senden Rückrufergebnisse mit dem SendDurableExecutionCallbackSuccess oder SendDurableExecutionCallbackFailure APIs Lambda. Wenn ein Callback gesendet wird, ruft Lambda Ihre Funktion erneut auf, das SDK wiederholt die Wiedergabe bis zum Callback-Point und Ihre Funktion fährt mit dem Callback-Ergebnis fort.

Das SDK bietet zwei Methoden für die Arbeit mit Callbacks:

createCallback: Erstellt einen Callback und gibt sowohl eine Promise- als auch eine Callback-ID zurück. Sie senden die Callback-ID an ein externes System, das das Ergebnis mithilfe der Lambda-API übermittelt.

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()

waitForCallback: Vereinfacht die Bearbeitung von Rückrufen, indem die Erstellung und Übermittlung von Rückrufen in einem Vorgang kombiniert werden. Das SDK erstellt den Callback, führt Ihre Absenderfunktion mit der Callback-ID aus und wartet auf das Ergebnis.

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

Konfigurieren Sie Timeouts, um zu verhindern, dass Funktionen auf unbestimmte Zeit warten. Wenn bei einem Callback eine Zeitüberschreitung auftritt, löst das SDK eine aus CallbackError und Ihre Funktion kann den Timeout-Fall behandeln. Verwenden Sie Heartbeat-Timeouts für lang andauernde Rückrufe, um zu erkennen, wann externe Systeme nicht mehr reagieren.

Verwenden Sie Callbacks für human-in-the-loop Workflows, die Integration externer Systeme, Webhook-Antworten oder jedes Szenario, in dem die Ausführung für externe Eingaben unterbrochen werden muss.

Parallele Ausführung

Führt mehrere Operationen gleichzeitig mit optionaler Parallelitätssteuerung aus. Das SDK verwaltet die parallel Ausführung, erstellt Prüfpunkte für jeden Vorgang und behandelt Fehler gemäß Ihrer Abschlussrichtlinie.

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') )

Wird verwendetparallel, um unabhängige Operationen gleichzeitig auszuführen.

Zuordnung

Führt gleichzeitig einen Vorgang für jedes Element in einem Array mit optionaler Parallelitätssteuerung aus. Das SDK verwaltet die gleichzeitige Ausführung, erstellt Prüfpunkte für jeden Vorgang und behandelt Fehler gemäß Ihrer Abschlussrichtlinie.

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' ) )

Wird verwendetmap, um Arrays mit Parallelitätssteuerung zu verarbeiten.

Kontexte für Kinder

Erzeugt einen isolierten Ausführungskontext für Gruppierungsvorgänge. Untergeordnete Kontexte haben ihr eigenes Checkpoint-Log und können mehrere Schritte, Wartezeiten und andere Operationen enthalten. Das SDK behandelt den gesamten untergeordneten Kontext für Wiederholungen und Wiederherstellungen als eine Einheit.

Verwenden Sie untergeordnete Kontexte, um komplexe Workflows zu organisieren, Unterworkflows zu implementieren oder Vorgänge zu isolieren, die zusammen wiederholt werden sollten.

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' )

Der Wiederholungsmechanismus erfordert, dass dauerhafte Operationen in einer deterministischen Reihenfolge ablaufen. Wenn Sie mehrere untergeordnete Kontexte verwenden, können Sie mehrere Arbeitsabläufe gleichzeitig ausführen lassen, und der Determinismus gilt für jeden Kontext separat. Auf diese Weise können Sie Hochleistungsfunktionen erstellen, die mehrere CPU-Kerne effizient nutzen.

Stellen Sie sich zum Beispiel vor, wir starten zwei untergeordnete Kontexte, A und B. Beim ersten Aufruf wurden die Schritte innerhalb der Kontexte in dieser Reihenfolge ausgeführt, wobei die A-Schritte gleichzeitig mit den B-Schritten ausgeführt wurden: A1, B1, B2, A2, A3. Bei der Wiedergabe ist das Timing viel schneller, da die Ergebnisse aus dem Checkpoint-Protokoll abgerufen werden und die Schritte zufällig in einer anderen Reihenfolge ausgeführt werden: B1, A1, A2, B2, A3. Da die A-Schritte in der richtigen Reihenfolge (A1, A2, A3) und die B-Schritte in der richtigen Reihenfolge (B1, B2) angetroffen wurden, wurde die Notwendigkeit des Determinismus korrekt erfüllt.

Bedingte Wartezeiten

Führt Abfragen nach einer Bedingung durch, bei der zwischen den Versuchen automatisch ein Checkpoint angezeigt wird. Das SDK führt Ihre Prüffunktion aus, erstellt einen Checkpoint mit dem Ergebnis, wartet entsprechend Ihrer Strategie und wiederholt den Vorgang, bis die Bedingung erfüllt ist.

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} ) )

Wird verwendet, waitForCondition um externe Systeme abzufragen, darauf zu warten, dass Ressourcen bereit sind, oder um Wiederholungsversuche mit Backoff zu implementieren.

Funktionsaufruf

Ruft eine weitere Lambda-Funktion auf und wartet auf ihr Ergebnis. Das SDK erstellt einen Checkpoint, ruft die Zielfunktion auf und nimmt Ihre Funktion wieder auf, wenn der Aufruf abgeschlossen ist. Dies ermöglicht die Funktionskomposition und die Workflow-Zerlegung.

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

Wie lange Betriebsabläufe gemessen werden

Jeder dauerhafte Vorgang, über den Sie aufrufen, DurableContext erstellt Kontrollpunkte, um den Ausführungsfortschritt zu verfolgen und Statusdaten zu speichern. Für diese Operationen fallen je nach Nutzung Gebühren an, und die Checkpoints können Daten enthalten, die zu Ihren Schreib- und Aufbewahrungskosten beitragen. Zu den gespeicherten Daten gehören Aufrufereignisse, Payloads, die von Schritten zurückgegeben wurden, und Daten, die beim Ausführen von Rückrufen weitergegeben werden. Wenn Sie wissen, wie langlebige Operationen gemessen werden, können Sie die Ausführungskosten abschätzen und Ihre Arbeitsabläufe optimieren. Einzelheiten zur Preisgestaltung finden Sie auf der Seite mit den Lambda-Preisen.

Die Größe der Nutzlast bezieht sich auf die Größe der serialisierten Daten, die bei einem dauerhaften Betrieb fortgeführt werden. Die Daten werden in Byte gemessen und die Größe kann je nach dem für den Vorgang verwendeten Serializer variieren. Die Nutzlast eines Vorgangs kann das Ergebnis selbst sein, wenn der Vorgang erfolgreich abgeschlossen wurde, oder das serialisierte Fehlerobjekt, falls der Vorgang fehlschlägt.

Grundlegende Operationen

Grundoperationen sind die grundlegenden Bausteine für dauerhafte Funktionen:

Operation Zeitlicher Ablauf der Checkpoints Anzahl der Operationen Die Daten wurden beibehalten
Ausführung Gestartet 1 Größe der eingegebenen Nutzlast
Ausführung Abgeschlossen () Succeeded/Failed/Stopped 0 Größe der Ausgangsnutzlast
Schritt Retry/Succeeded/Failed 1 +1 N Wiederholungen Bei jedem Versuch wurde die Nutzlastgröße zurückgegeben
Wait Gestartet 1
WaitForCondition Jeder Abfrageversuch 1 + N Umfragen Bei jedem Abfrageversuch wurde die Größe der Nutzlast zurückgegeben
Wiederholter Versuch auf Aufrufebene Gestartet 1 Nutzlast für das Fehlerobjekt

Callback-Operationen

Callback-Operationen ermöglichen es Ihrer Funktion, eine Pause einzulegen und darauf zu warten, dass externe Systeme Eingaben bereitstellen. Diese Operationen erstellen Checkpoints, wenn der Callback erstellt und abgeschlossen ist:

Operation Zeitpunkt der Checkpoints Anzahl der Operationen Die Daten wurden beibehalten
CreateCallback Gestartet 1
Abschluss des Rückrufs per API-Aufruf Completed 0 Payload des Rückrufs
WaitForCallback Gestartet 3 + N Wiederholungen (Kontext + Rückruf + Schritt) Payloads, die durch Versuche des Absenders zurückgesendet wurden, plus zwei Kopien der Payload für den Rückruf

Zusammengesetzte Operationen

Zusammengesetzte Operationen kombinieren mehrere dauerhafte Operationen, um komplexe Koordinationsmuster wie parallel Ausführung, Array-Verarbeitung und verschachtelte Kontexte zu handhaben:

Operation Zeitplan für Checkpoints Anzahl der Operationen Die Daten wurden beibehalten
Parallel Gestartet 1 + N Zweige (1 übergeordneter Kontext + N untergeordnete Kontexte) Bis zu zwei Kopien der zurückgegebenen Nutzdatengröße aus jedem Zweig plus den Status jedes Zweigs
Zuordnung Gestartet 1 + N Zweige (1 übergeordneter Kontext + N untergeordnete Kontexte) Bis zu zwei Kopien der zurückgegebenen Payload-Größe aus jeder Iteration plus der Status jeder Iteration
Versprich Helfer Completed 1 Die Nutzlastgröße wurde aus dem Versprechen zurückgegeben
RunInChildContext Erfolgreich/Fehlgeschlagen 1 Die Nutzdatengröße wurde aus dem untergeordneten Kontext zurückgegeben

Bei Kontexten, die z. B. aus zusammengesetzten Operationen stammen runInChildContext oder intern von zusammengesetzten Operationen verwendet werden, werden Ergebnisse, die kleiner als 256 KB sind, direkt überprüft. Größere Ergebnisse werden nicht gespeichert, sondern während der Wiedergabe rekonstruiert, indem die Operationen des Kontextes erneut verarbeitet werden.