Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does AWS Lambda function always time out?

Tags:

I am testing out aws lambda, using nodejs with the 4.3 version. I'm able to successfully complete all the statements in my handler function within the console test, which includes connecting to a mongodb host within our vpc. But, the function always times out. I've found several posts and resources that discuss using the callback, and setting properties on the context, and IAM role permissions, but no matter what I do, it always ends up timing out. Current code:

'use strict';  var Mongoose = require('mongoose'); var Device = require('./device_model'); var Alarm = require('./alarm_model'); var Event = require('./event_model');  var mongoConnection = process.env.MONGO_URL;  var connection = Mongoose.connect(mongoConnection);  Mongoose.connection.once('open', function() {     console.log("Connecting to mongo at: " + mongoConnection);     console.log("Mongoose connection in lambda opened"); });  Mongoose.connection.on('error', function(){     console.error("Error creating mongoose connection in lambda, exiting!");     process.exit(1); });  exports.check_alarms = function(event, context, callback) {      context.callbackWaitsForEmtpyEventLoop = false;     console.log("The incoming event: " + JSON.stringify(event));      var device = null;     Device.findByUUID(event.uuid, function(error, result){         if(!error){             device = result;             console.log("the device: " + JSON.stringify(device));             if(event.Ale && event.Ale.length > 0) {                 console.log("We have an alarm, checking if already set");                 callback(null, {"status":"alarms"});             } else {                 console.log("Event contains no alarm; checking for historic active");                 callback(null, {"status":"no alarms"});             }         } else {             console.log("there's a problem on mongo");             callback("problem", "status not so good");         }     });      callback(null, {"status":"outside of device find block"}); } 
like image 520
wkhatch Avatar asked Jan 12 '17 19:01

wkhatch


People also ask

What is the most likely issue with the Lambda function timeout?

Finding the root cause of the timeout. There are many reasons why a function might time out, but the most likely is that it was waiting on an IO operation to complete.

What is the default timeout for an AWS Lambda function?

You can now configure your AWS Lambda functions to run up to 15 minutes per execution. Previously, the maximum execution time (timeout) for a Lambda function was 5 minutes.

How to solve task timed out after x seconds in AWS Lambda?

To solve the "Task timed out after X seconds" error in AWS lambda, you have to: 1 Increase the function's timeout. The default value is 3 seconds , the maximum is 15 minutes. 2 Increase the function's memory. By default it's set to 128 Mb which is way too low and ads onto the function's execution... More ...

What does it mean when AWS intentionally stops a lambda function?

AWS intentionally stopped a function invocation once it hit a run-time of X seconds. What does this mean? Lambda functions are limited to a maximum execution time of 15 minutes. A custom limit can be configured when the Lambda function is created.

What is the timeout limit for AWS Lambda?

The function has a timeout of 15 minutes, so the thread will be kept waiting for the response. However, the threshold limit for API Gateway is 29 seconds, so the user will receive the AWS Lambda timeout error after 29 seconds. Not only is this a poor experience for the user but it will also result in additional cost.

Why is there a time limit on lambda?

The limit is in place because Lambda functions are meant to be small and quick rather than large applications. How do I fix if Lambda task is timed out? Enable AWS X-ray tracing to get a breakdown of the execution.


2 Answers

You have a typo:

context.callbackWaitsForEmtpyEventLoop = false; 

should be:

context.callbackWaitsForEmptyEventLoop = false; 

Here's what the documentation says about the behavior of callbackWaitsForEmptyEventLoop:

callbackWaitsForEmptyEventLoop

The default value is true. This property is useful only to modify the default behavior of the callback. By default, the callback will wait until the Node.js runtime event loop is empty before freezing the process and returning the results to the caller. You can set this property to false to request AWS Lambda to freeze the process soon after the callback is called, even if there are events in the event loop. AWS Lambda will freeze the process, any state data and the events in the Node.js event loop (any remaining events in the event loop processed when the Lambda function is called next and if AWS Lambda chooses to use the frozen process). For more information about callback, see Using the Callback Parameter.

Minimal example:

// Times out due to typo exports.function1 = (event, context, callback) => {     setInterval(() => console.log('Long wait'), 100000);     context.callbackWaitsForEmtpyEventLoop = false;     callback(null, 'Hello from Lambda'); };  // Returns successfully exports.function2 = (event, context, callback) => {     setInterval(() => console.log('Long wait'), 100000);     context.callbackWaitsForEmptyEventLoop = false;     callback(null, 'Hello from Lambda'); }; 
like image 88
wjordan Avatar answered Sep 21 '22 15:09

wjordan


If anybody was confused like I was with how to add callbackWaitsForEmptyEventLoop to new Alexa projects that look like this:

const skillBuilder = Alexa.SkillBuilders.custom();  exports.handler = skillBuilder   .addRequestHandlers(       GetNewFactHandler,       HelpHandler,       ExitHandler,       FallbackHandler,       SessionEndedRequestHandler,   )   .addRequestInterceptors(LocalizationInterceptor)   .addErrorHandlers(ErrorHandler)   .lambda(); 

Example project found here: https://github.com/alexa/skill-sample-nodejs-fact/blob/master/lambda/custom/index.js

This solution worked for me:

// create a custom skill builder const skillBuilder = Alexa.SkillBuilders.custom();  exports.handler = (event, context, callback) => {   // we need this so that async stuff will work better   context.callbackWaitsForEmptyEventLoop = false    // set up the skill with the new context   return skillBuilder     .addRequestHandlers(       GetNewFactHandler,       HelpHandler,       ExitHandler,       FallbackHandler,       SessionEndedRequestHandler,     )     .addRequestInterceptors(LocalizationInterceptor)     .addErrorHandlers(ErrorHandler)     .lambda()(event, context, callback); } 
like image 38
tdon Avatar answered Sep 22 '22 15:09

tdon