Saltar al contenido

Usando boto para invocar funciones lambda, ¿cómo lo hago de forma asincrónica?

Solución:

Hay una diferencia entre un ‘invocación asíncrona de AWS lambda’ y ‘código python asíncrono’. Cuando configura el InvocationType para 'Event', por definición, nunca devuelve una respuesta.

En tu ejemplo, invoke() regresa inmediatamente None, y no inicia implícitamente nada en segundo plano para cambiar ese valor en un momento posterior (¡gracias a Dios!). Entonces, cuando miras el valor de response 15 segundos después, todavía está None.

Parece que lo que realmente quieres es el RequestResponse tipo de invocación, con código Python asincrónico. Tienes un montón de opciones para elegir, pero mi favorita es concurrent.futures. Otro es threading.

Aquí hay un ejemplo usando concurrent.futures:

(Si está usando Python2, necesitará pip install futures)

from concurrent.futures import ThreadPoolExecutor
import json

payload = {...}

with ThreadPoolExecutor(max_workers=5) as executor:
    futs = []
    for x in xrange(0, 5):
        futs.append(
            executor.submit(client.invoke,
                FunctionName   = "loadSpotsAroundPoint",
                InvocationType = "RequestResponse",
                Payload        = bytes(json.dumps(payload))
            )
        )
    results = [ fut.result() for fut in futs ]

print results

Otro patrón que puede considerar es utilizar el Event tipo de invocación y haga que su función Lambda envíe mensajes a SNS, que luego son consumidos por otra función Lambda. Puede consultar un tutorial para las funciones lambda activadas por SNS aquí.

Una función de AWS Lambda ejecutada de forma asincrónica no devuelve el resultado de la ejecución. Si una solicitud de invocación asincrónica tiene éxito (es decir, no hubo errores debido a permisos, etc.), AWS Lambda devuelve inmediatamente el código de estado HTTP 202 ACEPTADO y no tiene más responsabilidad de comunicar información sobre el resultado de esta invocación asincrónica.

De la documentación de AWS Lambda Invoke action:

Sintaxis de respuesta

HTTP/1.1 StatusCode
X-Amz-Function-Error: FunctionError
X-Amz-Log-Result: LogResult

Payload

Elementos de respuesta

Si la acción tiene éxito, el servicio devuelve la siguiente respuesta HTTP.

Código de estado

El código de estado HTTP estará en el rango 200 para una solicitud exitosa. Para el RequestResponse tipo de invocación, este código de estado será 200.
Para el Event tipo de invocación este código de estado será 202. Para el DryRun tipo de invocación, el código de estado será 204.

[…]

La respuesta devuelve lo siguiente como cuerpo HTTP.

Carga útil

Es la representación JSON del objeto devuelto por la función Lambda. Esto está presente solo si el tipo de invocación es
RequestResponse.

A continuación, se muestra una función de Python que acepta lambda-function-Name para invocar y payload para enviar a esa función.

Invoca la función lambda por el cliente boto3.

import boto3, json, typing

def invokeLambdaFunction(*, functionName:str=None, payload:typing.Mapping[str, str]=None):
    if  functionName == None:
        raise Exception('ERROR: functionName parameter cannot be NULL')
    payloadStr = json.dumps(payload)
    payloadBytesArr = bytes(payloadStr, encoding='utf8')
    client = boto3.client('lambda')
    response = client.invoke(
        FunctionName=functionName,
        InvocationType="RequestResponse",
        Payload=payloadBytesArr
    )
    return response

Y uso:

if __name__ == '__main__':
    payloadObj = {"something" : "1111111-222222-333333-bba8-1111111"}
    response = invokeLambdaFunction(functionName="myLambdaFuncName",  payload=payloadObj
    print(f'response:{response}')
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *