node.js - nodejs - La función AWS lambda deja de funcionar después de un error de tiempo de espera agotado
lambda node js tutorial (5)
Tengo una función lambda simple que asincrónicamente realiza una API y luego devuelve datos. El 99% del tiempo esto funciona genial. Cuando alguna vez la API tarda más tiempo que el tiempo de espera configurado lambda, da un error como se esperaba. Ahora el problema es que cuando realizo cualquier llamada posterior a la función lambda, me da el error de tiempo de espera permanentemente.
"errorMessage": "2016-05-14T22:52:07.247Z {session} Task timed out after 3.00 seconds"
Para probar que este era el caso, establecí el tiempo de espera de lambda en 3 segundos y tengo una manera de desencadenar estas dos funciones dentro de la lambda.
Javascript
function now() {
return response.tell(''success'');
}
function wait() {
setTimeout(function() { return response.tell(''success''); }, 4000);
}
Cuando llamo a la función now
no hay problemas. Cuando llamo a la función de wait
obtengo el error de tiempo de espera y todas las llamadas posteriores now
me dan el mismo error.
¿Es esto un comportamiento esperado? Creo que cualquier llamada posterior a la función lambda debería funcionar. Entiendo que siempre puedo aumentar el tiempo de espera de la configuración, pero preferiría no hacerlo.
Bueno, si definiste 3 segundos en la configuración de tu función, este tiempo de espera anulará el tiempo dentro de tu código, así que asegúrate de aumentar el tiempo de espera de las configuraciones de la función lambda e intenta de nuevo la espera () ¡y debería funcionar!
Debería buscar cómo funciona su identificador de función con un context.callbackWaitsForEmptyEventLoop
específico.callbackWaitsForEmptyEventLoop
Si ese tipo booleano es false
, el setTimeout no se activará nunca, porque es posible que haya respondido / manejado la invocación lambda anteriormente. Pero si el valor de callbackWaitsForEmptyEventLoop
es true
, entonces su código hará lo que está buscando.
Además, probablemente sea más fácil manejar todo a través de devoluciones de llamadas directamente, sin la necesidad de tiempos de espera "escritos a mano", cambiar los tiempos de espera de configuración, etc.
P.ej
function doneFactory(cb) { // closure factory returning a callback function which knows about res (response)
return function(err, res) {
if (err) {
return cb(JSON.stringify(err));
}
return cb(null, res);
};
}
// you''re going to call this Lambda function from your code
exports.handle = function(event, context, handleCallback) {
// allows for using callbacks as finish/error-handlers
context.callbackWaitsForEmptyEventLoop = false;
doSomeAsyncWork(event, context, doneFactory(handleCallback));
};
En la consola AWS de Amazon, debe cambiar el tiempo de espera predeterminado de 3 segundos a más (5 minutos como máximo)
Me encontré con el mismo problema, de hecho, hay muchos casos en que Lambda deja de responder, por ejemplo:
El análisis no es válido json:
exports.handler = function(event, context, callback) { var nonValidJson = "Not even Json"; var jsonParse = JSON.parse(nonValidJson);
Accediendo a propiedad de variable indefinida:
exports.handler = function(event, context, callback) { var emptyObject = {}; var value = emptyObject.Item.Key;
No cerrar la conexión mySql después de acceder a RDS conduce al tiempo de espera de Lambda y luego deja de responder.
Cuando digo que no responde, literalmente ni siquiera se carga, es decir, la primera impresión dentro del controlador no se imprime, y Lambda simplemente sale de cada ejecución con tiempo de espera:
exports.handler = function(event, context, callback)
{
console.log("Hello there");
Es un error conocido por el equipo de AWS durante casi un año:
https://forums.aws.amazon.com/thread.jspa?threadID=238434&tstart=0
Lamentablemente, todavía no está solucionado, después de algunas pruebas se revela que, de hecho, Lambda intenta reiniciar (¿volver a cargar el contenedor?), Simplemente no hay tiempo suficiente. Si establece el tiempo de espera en 10s, después de ~ 4s de tiempo de ejecución, Lambda comienza a funcionar, y luego en las próximas ejecuciones llega a comportarse normalmente. También intenté jugar con la configuración:
context.callbackWaitsForEmptyEventLoop = false;
y poner todos los bloques ''necesarios'' dentro del controlador, nada funcionó realmente. La única manera de evitar que Lambda se muera es establecer un tiempo de espera mayor, 10s debería ser más que suficiente como una solución alternativa contra este error.
Solo tuve que aumentar el tiempo de espera y el error disminuyó. Lo aumenté a 5 sec. Esto estuvo bien para mí porque no iba a usar este Lambda en producción.