Handling AWS Lambda timeout using AWS SNS

Posted By : Ankit Uniyal | 25-Sep-2017

We can handle AWS Lambda function 5 minutes timeout failure using AWS SNS integration.AWS Lambda has some limitations which include 5 minutes maximum execution time.

We can handle this by using AWS SNS but before going further if you are not familiar with AWS Lambda, you can refer the below blog for a brief introduction about AWS Lambda.

 

http://www.oodlestechnologies.com/blogs/An%20Introduction%20to%20AWS%20Lambda

 

Our ideal workflow will follow the below steps :

1.Firstly, our lambda function will invoke AWS CloudWatch event or from API Gateway.

2.When Lambda timeout about to come, it sends SNS Message to AWS SNS with necessary information.

3.AWS SNS will then invoke AWS Lambda and provide the details to Lambda which provided to SNS via SNS Messages.

 

How to set Permissions for AWS Lambda role to send SNS Messages to AWS SNS :

We need to set permissions for AWS Lambda role so that it can send SNS messages to AWS SNS and this can be done on setting permission under AWS IAM role tab by following below steps :

1.Go to IAM Role feature and Click on Roles which on the left side of the page.

2.Select the role for which your lambda function is defined.

3.Select the one-click Lambda policy if not created before, you can create a one.

4.If it is already created before, then click on Edit policy and add the below permissions rule :

          {
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": "*"
}   
    

5.Now, click on validate Policy and then Save.

Now, you have added the permission policy for your Lambda function and your Lambda can trigger AWS SNS.

 

How to publish a Message to SNS Topic using AWS Lambda function in Node.js?

1.First, you need to create an SNS topic, so that lambda can send SNS Message. For this, go to AWS SNS dashboard and Click on "Create a Topic" and enter the topic name and its display name.

2.Next, you have to set the corresponding topic Subscription (i.e recipients). A single topic can have multiple subscriptions and in this case, we need Lambda as a subscription.

3.Now, go the created topic page, and then click on "Create Subscription" and then set the protocol (AWS Lambda should be used in this case) and then the end point (i.e Lambda arn) and select which version you want to use and then create Subscription.

4.How to identify when AWS SNS message is to be sent on lambda timeout :

We can track lambda timeout failure by below code snippet so that we can send SNS message to AWS Lambda using point (5).

exports.snsHanlder = function(event, context) {
var threshold_millis = 13 * 1000;
var remain_millis = context.getRemainingTimeInMillis();
if (remain_millis < threshold_millis) {
msg = {"necessary information for next function": "here"}
        publish_to_sns(msg)
    }
}     
    

5.After creating SNS topic and Subscription, you need to Integrate AWS Lambda with AWS Lambda in code which can be done using below code snippet :

    var publish_to_sns = function (event, snsMessage,context,callback) {
    var AWS = require("aws-sdk");
    var eventText = JSON.stringify(event, null, 2);
    console.log("Received event:", eventText);
    var sns = new AWS.SNS();
    var params = {
        Message: snsMessage, 
        Subject: "Test SNS From Lambda function",
        TopicArn: "your_aws_sns_topic_arn"
    };
    sns.publish(params, function(err, data) {
            if(err) {
                console.error('error publishing to SNS');
                context.fail(err);
            } else {
                console.info('message published to SNS');
                context.done(null, data);
            }
      });
  };   
    

6.An SNS event will look like this :

          "event:": {
          "Records": [
            {
                "EventVersion": "1.0",
                "EventSubscriptionArn": "your event Arn",
                "EventSource": "aws:sns",
                "Sns": {
                    "SignatureVersion": "1",
                    "Timestamp": "2016-09-06T08:25:15.206Z",
                    "Signature": "F4Ylh6sP71lkSJIdAyKRf==",
                    "MessageId": "c58d6478-6de0-590c-9346-3430124b755b",
                    "Message": "{"necessary information for next function": "here"}",
                    "MessageAttributes": {
                        "summary": {
                            "Type": "String",
                            "Value": "just a summary"
                        }
                    }
                }
            }
        ]
    }     
    

And you need to find out whether the Lambda is invoked by AWS CloudWatch event/ API Gateway or from AWS SNS and this we can check for AWS SNS by checking Record name field in event object :

          if(!event.Records) {
             console.log("Not Invoked by SNS"); 
          }
          else {
             console.log("Invoked by SNS");
          }    
    

No, you can set your Lambda timeout to be maximum 5 minutes execution time and this will re-invoke the lambda if lambda execution was not completed within 5 minutes time interval.

You can also test the mechanism on setting timeout time to be of few seconds, and this will invoke your lambda till lambda process has not completed.

 

Thanks.

About Author

Author Image
Ankit Uniyal

Ankit has knowledge in Javascript, NodeJS, AngularJS and MongoDB also have experience in using AWS Services.

Request for Proposal

Name is required

Comment is required

Sending message..