SDK de ejecución duradera
El SDK de ejecución duradera es la base para crear funciones duraderas. Proporciona las primitivas que necesita para comprobar el progreso, gestionar los reintentos y administrar el flujo de ejecución. El SDK elimina la complejidad de la administración y reproducción de los puntos de control, y permite escribir código secuencial que se vuelve automáticamente tolerante a errores.
El SDK está disponible para JavaScript, TypeScript y Python. Para ver ejemplos y documentación completa de la API, consulte el SDK para JavaScript/TypeScript
DurableContext
El SDK proporciona a la función un objeto de DurableContext que expone todas las operaciones duraderas. Este contexto reemplaza el contexto estándar de Lambda y proporciona métodos para crear puntos de control, administrar el flujo de ejecución y coordinar con sistemas externos.
Para usar el SDK, encapsule el controlador de Lambda con el encapsulador de ejecución duradera:
El encapsulador intercepta la invocación de la función, carga cualquier registro de puntos de control existente y proporciona el DurableContext que administra la reproducción y los puntos de control.
Operaciones que realiza el SDK
El SDK gestiona tres responsabilidades fundamentales que permiten una ejecución duradera:
Administración de puntos de control: el SDK crea puntos de control automáticamente a medida que la función ejecuta operaciones duraderas. Cada punto de control registra el tipo de operación, las entradas y los resultados. Cuando la función completa un paso, el SDK conserva el punto de control antes de continuar. Esto garantiza que la función pueda reanudarse después de cualquier operación completada en caso de interrupción.
Coordinación de reproducción: cuando la función se reanuda tras una pausa o interrupción, el SDK realiza la reproducción. Ejecuta el código desde el principio, pero omite las operaciones completadas y utiliza los resultados de los puntos de control almacenados en lugar de volver a ejecutarlos. El SDK garantiza que la reproducción sea determinista: con las mismas entradas y el mismo registro de puntos de control, la función produce los mismos resultados.
Aislamiento de estados: el SDK mantiene el estado de ejecución por separado de la lógica empresarial. Cada ejecución duradera tiene su propio registro de puntos de control al que no pueden acceder las demás ejecuciones. El SDK cifra los datos en reposo de los puntos de control y garantiza que el estado se mantenga uniforme en todas las reproducciones.
Cómo funciona la creación de puntos de control
Cuando se llama a una operación duradera, el SDK sigue la secuencia a continuación:
Comprueba si hay un punto de control existente: el SDK comprueba si esta operación ya se completó en una invocación anterior. Si existe un punto de control, el SDK devuelve el resultado almacenado sin volver a ejecutar la operación.
Ejecuta la operación: si no existe ningún punto de control, el SDK ejecuta el código de la operación. En cuanto a los pasos, esto significa llamar a la función. En cuanto a las esperas, esto significa programar la reanudación.
Crea un punto de control: una vez completada la operación, el SDK serializa el resultado y crea un punto de control. El punto de control incluye el tipo de operación, el nombre, las entradas, el resultado y la marca de tiempo.
Conserva el punto de control: el SDK llama a la API del punto de control de Lambda para conservar el punto de control. Esto garantiza que el punto de control sea duradero antes de continuar con la ejecución.
Devuelve el resultado: el SDK devuelve el resultado de la operación a su código, que continúa hasta la siguiente operación.
Esta secuencia garantiza que, una vez completada una operación, su resultado se almacene de forma segura. Si la función se interrumpe en algún momento, el SDK puede reproducir hasta el último punto de control completado.
Comportamiento de reproducción
Cuando la función se reanuda tras una pausa o interrupción, el SDK realiza la reproducción.
Carga el registro de puntos de control: el SDK recupera el registro de puntos de control para esta ejecución de Lambda.
Ejecuta desde el principio: el SDK invoca la función de controlador desde el principio, no desde donde se detuvo.
-
Omite las operaciones duraderas completadas: como su código llama a las operaciones duraderas, el SDK compara cada una de ellas con el registro de puntos de control. En el caso de operaciones duraderas completadas, el SDK devuelve el resultado almacenado sin ejecutar el código de la operación.
nota
Si el resultado de un contexto secundario supera el tamaño máximo del punto de control (256 KB), el código del contexto se vuelve a ejecutar durante la reproducción. Esto le permite elaborar grandes resultados a partir de las operaciones duraderas que se ejecutaron dentro del contexto, que se consultarán en el registro de puntos de control. Por lo tanto, es imperativo ejecutar solo código determinista en el contexto mismo. Cuando se utilizan contextos secundarios con resultados de gran tamaño, la práctica recomendada es realizar trabajos de larga duración o no deterministas dentro de los pasos y llevar a cabo únicamente tareas de corta duración que combinen los resultados en el propio contexto.
Reanuda en el punto de interrupción: cuando el SDK llega a una operación sin un punto de control, se ejecuta con normalidad y crea nuevos puntos de control a medida que se completan las operaciones duraderas.
Este mecanismo de reproducción requiere que el código sea determinista. Con las mismas entradas y el mismo registro de puntos de control, la función debe realizar la misma secuencia de llamadas a operaciones duraderas. El SDK lo impone al validar que los nombres y tipos de operaciones coincidan con el registro de puntos de control durante la reproducción.
Operaciones duraderas disponibles
El DurableContext proporciona operaciones para diferentes patrones de coordinación. Cada operación duradera crea puntos de control automáticamente, lo que garantiza que la función pueda reanudarse desde cualquier punto.
Steps
Ejecuta la lógica empresarial con creación automática de puntos de control y hace un reintento. Siga estos pasos para las operaciones que llaman a servicios externos, realizan cálculos o ejecutan cualquier lógica que deba comprobarse. El SDK crea un punto de control antes y después del paso y almacena el resultado para reproducirlo.
Los pasos admiten estrategias de reintentos configurables, semánticas de ejecución (como máximo una vez o como mínimo una vez) y serialización personalizada.
Esperas
Pausa la ejecución durante un tiempo específico sin consumir recursos de cómputo. El SDK crea un punto de control, finaliza la invocación de la función y programa la reanudación. Cuando finaliza la espera, Lambda vuelve a invocar la función, y el SDK reproduce el punto de espera antes de continuar.
Devoluciones de llamada
Las devoluciones de llamada permiten que la función haga una pausa y espere a que los sistemas externos envíen información. Cuando crea una devolución de llamada, el SDK genera un identificador de devolución de llamada único y crea un punto de control. A continuación, la función suspende (finaliza la invocación) sin incurrir en gastos de cómputo. Los sistemas externos envían los resultados de las devoluciones de llamada mediante las API de SendDurableExecutionCallbackSuccess o SendDurableExecutionCallbackFailure de Lambda. Cuando se envía una devolución de llamada, Lambda vuelve a invocar la función, el SDK la reproduce en el punto de devolución de llamada, y la función continúa con el resultado de la devolución de llamada.
El SDK proporciona dos métodos para trabajar con las devoluciones de llamada:
createCallback: crea una devolución de llamada y devuelve tanto una promesa como un identificador de devolución de llamada. El identificador de devolución de llamada se envía a un sistema externo, que envía el resultado mediante la API de Lambda.
waitForCallback: simplifica la gestión de las devoluciones de llamada al combinar la creación y el envío de las devoluciones de llamada en una sola operación. El SDK crea la devolución de llamada, ejecuta la función de remitente con el identificador de devolución de llamada y espera el resultado.
Configura los tiempos de espera para evitar que las funciones esperen indefinidamente. Si se agota el tiempo de espera de una devolución de llamada, el SDK emitirá un CallbackError y la función podrá gestionar el tiempo de espera. Utilice los tiempos de espera de latido para las devoluciones de llamada de larga duración y para detectar cuándo los sistemas externos dejan de responder.
Utilice la devolución de llamada para los flujos de trabajo con intervención humana, la integración de sistemas externos, las respuestas a webhooks o cualquier situación en la que la ejecución deba hacer una pausa debido a una intervención externa.
Ejecución en paralelo
Ejecuta varias operaciones de forma simultánea con el control de concurrencia opcional. El SDK gestiona la ejecución paralela, crea puntos de control para cada operación y gestiona los errores de acuerdo con su política de finalización.
Utilice parallel para ejecutar operaciones independientes de forma simultánea.
Asignación
Ejecute simultáneamente una operación en cada elemento de una matriz con el control de concurrencia opcional. El SDK gestiona la ejecución simultánea, crea puntos de control para cada operación y gestiona los errores de acuerdo con su política de finalización.
Utilice map para procesar matrices con control de concurrencia.
Contextos secundarios
Crea un contexto de ejecución aislado para agrupar operaciones. Los contextos secundarios tienen su propio registro de puntos de control y pueden contener varios pasos, esperas y otras operaciones. El SDK trata todo el contexto secundario como una sola unidad de reintento y recuperación.
Utilice los contextos secundarios para organizar flujos de trabajo complejos, implementar subflujos de trabajo o aislar operaciones que deberían reintentarse juntas.
El mecanismo de reproducción exige que las operaciones duraderas se realicen en un orden determinista. Cuando se utilizan varios contextos secundarios, se pueden ejecutar varios flujos de trabajo de forma simultánea, y el determinismo se aplica por separado dentro de cada contexto. Esto le permite crear funciones de alto rendimiento que utilizan de manera eficiente varios núcleos de CPU.
Por ejemplo, imagine que iniciamos dos contextos secundarios, A y B. En la invocación inicial, los pasos dentro de los contextos se ejecutaron en este orden, y los pasos «A» se ejecutaron simultáneamente con los pasos «B»: A1, B1, B2, A2, A3. Tras la reproducción, el tiempo es mucho más rápido, ya que los resultados se recuperan del registro del punto de control y los pasos se encuentran en un orden diferente: B1, A1, A2, B2, A3. Como los pasos «A» se encontraron en el orden correcto (A1, A2, A3) y los pasos «B» se encontraron en el orden correcto (B1, B2), la necesidad de determinismo quedó satisfecha correctamente.
Esperas condicionales
Sondea una condición con creación automática de puntos de control entre intentos. El SDK ejecuta la función de verificación, crea un punto de control con el resultado, espera según la estrategia y se repite hasta que se cumpla la condición.
Utilice waitForCondition para sondear sistemas externos, esperar a que los recursos estén listos o implementar el reintento con retroceso.
Invocación de función
Invoca otra función de Lambda y espera su resultado. El SDK crea un punto de control, invoca la función de destino y reanuda la función cuando se completa la invocación. Esto habilita la composición de funciones y la descomposición del flujo de trabajo.
Cómo se mide la durabilidad de las operaciones
Cada operación duradera a la que llama mediante DurableContext crea puntos de control para seguir el progreso de la ejecución y almacenar los datos de estado. Estas operaciones incurren en gastos en función de su uso, y los puntos de control pueden contener datos que contribuyen a los costos de escritura y retención de datos. Los datos almacenados incluyen los datos de los eventos de invocación, las cargas útiles devueltas por los pasos y los datos transferidos cuando se realizan las devoluciones de llamada. Comprender cómo se miden las operaciones duraderas lo ayudará a estimar los costos de ejecución y a optimizar sus flujos de trabajo. Consulte la página de Precios de Lambda
El tamaño de la carga útil se refiere al tamaño de los datos serializados que conserva una operación duradera. Los datos se miden en bytes, y el tamaño puede variar según el serializador utilizado por la operación. La carga útil de una operación podría ser el resultado en sí mismo de una finalización exitosa o el objeto de error serializado si la operación fallara.
Operaciones básicas
Las operaciones básicas son los componentes fundamentales de las funciones duraderas:
| Operación | Temporización de los puntos de control | Número de operaciones | Persistencia de datos |
|---|---|---|---|
| Ejecución | Started | 1 | Tamaño de carga útil de entrada |
| Ejecución | Completado (satisfactorio/fallido/detenido) | 0 | Tamaño de carga útil de salida |
| N.° de paso | Reintento/satisfactorio/fallido | 1 + N reintentos | Se devolvió el tamaño de la carga útil de cada intento. |
| Espere | Started | 1 | N/A |
| WaitForCondition | Cada intento de sondeo | 1 + N sondeos | Se devolvió el tamaño de la carga útil de cada intento de sondeo. |
| Reintento a nivel de invocación | Started | 1 | Carga útil del objeto de error |
Operaciones de devolución de llamada
Las operaciones de devolución de llamada permiten que la función haga una pausa y espere a que los sistemas externos envíen información. Estas operaciones crean puntos de control cuando se crea la devolución de llamada y cuando se completa:
| Operación | Temporización de los puntos de control | Número de operaciones | Persistencia de datos |
|---|---|---|---|
| CreateCallback | Started | 1 | N/A |
| Finalización de la devolución de llamada mediante una llamada a la API | Completado | 0 | Carga útil de devolución de llamada |
| WaitForCallback | Started | 3 + N reintentos (contexto + devolución de llamada + paso) | Cargas útiles devueltas por los intentos de paso del remitente, más dos copias de la carga útil de devolución de llamada |
Operaciones compuestas
Las operaciones compuestas combinan múltiples operaciones duraderas para gestionar patrones de coordinación complejos, como la ejecución paralela, el procesamiento de matrices y los contextos anidados:
| Operación | Temporización de los puntos de control | Número de operaciones | Persistencia de datos |
|---|---|---|---|
| Parallel | Started | 1 + N ramificaciones (1 contexto principal + N contextos secundarios) | Hasta dos copias del tamaño de la carga útil devuelta por cada ramificación, más los estados de cada ramificación |
| Asignación | Started | 1 + N ramificaciones (1 contexto principal + N contextos secundarios) | Hasta dos copias del tamaño de la carga útil devuelta por cada iteración, más los estados de cada iteración |
| Ayudantes de promesas | Completado | 1 | El tamaño de la carga útil devuelto según la promesa |
| RunInChildContext | Satisfactorio/fallido | 1 | El tamaño de la carga útil devuelto desde el contexto secundario |
En el caso de contextos, como los procedentes de runInChildContext o utilizados internamente por operaciones compuestas, los resultados de menos de 256 KB se controlan directamente mediante puntos de control. Los resultados más grandes no se almacenan, sino que se reconstruyen durante la reproducción mediante el reprocesamiento de las operaciones del contexto.