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 elEvent
tipo de invocación este código de estado será 202. Para elDryRun
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}')