12

I'm trying to publish some data to SNS from a Lambda function call, but it doesn't seem to be working. My function code is -

public class Handler implements RequestHandler<DynamodbEvent, Void> {

    private static final String SNS_TOPIC_ARN = "arn:aws:sns:us-west-2:account_number:function_name";

    @Override
    public Void handleRequest(DynamodbEvent dynamodbEvent, Context context) {

        LambdaLogger logger = context.getLogger();

        AmazonSNSClient snsClient = new AmazonSNSClient(new DefaultAWSCredentialsProviderChain());
        snsClient.setRegion(Region.getRegion(Regions.US_WEST_2));

        for (DynamodbStreamRecord record : dynamodbEvent.getRecords()) {
            Map<String, AttributeValue> newImage = record.getDynamodb().getNewImage();

            if (newImage == null) {
                continue;
            }

            String sensorId = newImage.get("sensorID").getS();
            long timestamp = Long.parseLong(newImage.get("timestamp").getS());
            double temperature = Double.parseDouble(newImage.get("payload").getM().get("temp").getN());

            String data = sensorId + " " + timestamp + " " + temperature;

            logger.log(data);

            PublishRequest publishRequest = new PublishRequest(SNS_TOPIC_ARN, data);

            PublishResult publishResult = snsClient.publish(publishRequest);

            logger.log("Publish Successful " + publishResult.getMessageId());
        }

        snsClient.shutdown();

        return null;
    }
}

This call results in a timeout (10 seconds) and the lambda invocation fails. If I comment out the SNS publishing part, i.e., if I just log the data received from DynamoDB, it works just fine. As soon as the SNS publishing code is added, it times out.

The timeout message logged in CloudWatch is -

START RequestId: 8db74187-459b-42c5-8a06-b3a74873b236 Version: $LATEST END RequestId: 8db74187-459b-42c5-8a06-b3a74873b236 REPORT RequestId: 8db74187-459b-42c5-8a06-b3a74873b236 Duration: 10001.66 ms Billed Duration: 10000 ms Memory Size: 128 MB Max Memory Used: 37 MB Task timed out after 10.00 seconds

I have all the proper permissions in place, and I'm able to publish to SNS using just the following code running on my PC -

PublishRequest publishRequest = new PublishRequest(SNS_TOPIC_ARN, data);
PublishResult publishResult = snsClient.publish(publishRequest);
System.out.println("Publish Successful " + publishResult.getMessageId());

I have also tried using AmazonSNSAsyncClient instead of AmazonSNSClient, it gives the same result.

What am I missing here ?

Rohan
  • 1,180
  • 2
  • 15
  • 28
  • Try increasing the allocated memory setting to the max. This will speed up the processing necessary to perform the SNS API calls. You currently have it at the slowest setting. Then try increasing the timeout seconds. How many DynamoDB events are you receiving in each AWS Lambda function invocation that times out? – Eric Hammond Dec 28 '15 at 09:17
  • @EricHammond I'm receiving just 1 event per lambda call. I doubt that requires more memory and time. The payload is also very tiny. Also, when I add the SNS part, even the first call to `logger.log()` (the one that logs the received data) is not reached. – Rohan Dec 28 '15 at 09:30
  • Java functions are definitely slower to start and need more memory on Lambda than NodeJS or Python functions. I would definitely start by increasing the timeout and available memory. – Mark B Dec 28 '15 at 18:50
  • 1
    The timeout could also be caused by the fact that requests using the AWS SDK fail they are automatically retried using exponential backoff. This could be happening if there resource doesn't exist, there is a permission issue, or the service is actually down. Set the Lambda function timeout to over a minute or change the SDKs retry logic to avoid this type of timeout altogether. – JaredHatfield Dec 28 '15 at 23:33
  • Seems like it was a memory issue after all. Thanks guys. Can one of you post it as an answer ? – Rohan Dec 29 '15 at 04:51

3 Answers3

10

Well, since none of the people who commented on my question are answering, I'll answer it myself.

Increasing the memory usage to 256 MB and timeout to 30 seconds seems to have solved the issue.

Rohan
  • 1,180
  • 2
  • 15
  • 28
  • where did specifically increase the memory usage and time out? – TheQ Jan 24 '17 at 03:58
  • 8
    For future readers: it could very well be a network issue if your lambda's VPC is missing a NAT gateway. See e.g. https://stackoverflow.com/a/43234476/2442804 – luk2302 Jul 24 '17 at 10:08
2

Increase the amount of memory allocated for the Lambda operation.

Josh Wulf
  • 4,727
  • 2
  • 20
  • 34
0

Increasing the memory allocated to the lambda function worked for me as well (this setting is in the lambda console under basic settings).

This one was maddening for me - I was using the same JAR file for 2 different lambda functions with identical configurations, and the SNS call was working for one but timing out for the other. Maddening!