AWS Lambda: does it matter if handlers are sync vs async, w.r.t. concurrent calls? - aws-lambda

For AWS Lambda handlers, does it matter if the code is async vs sync (eg async def vs def), with respect to the concurrency performance of multiple calls to that Lambda function? That is, if I write a synchronous function, will that function be called "asynchronously" anyway due to the way AWS internally handles Lambda invocations from separate calls? Or will the function start processing UserA, and queue UserB's request until it has completed UserA?
Backstory: I'm writing some Python + SQLAlchemy Lambda functions. SQLAlchemy 1.4 just released asyncio support, but there will be some re-write overhead on my part. I'm wondering if I can just write traditional synchronous Python code without concurrency consideration on Lambda (where concurrency is something I'd definitely need to consider for custom Flask / FastAPI code).

If you have more than one request to invoke a lambda at the same time the service will attempt to run multiple instances of the lambda. You may run into throttling due to the concurrency limits on either the lambda itself, or the account. Lambda does not queue requests to the same lambda function. A function is never processing more than one request at a time. Even in cases where the system is providing a queuing mechanism to handle the requests, they are not a thread queue, like you might have with a server. They are really just internal SQS queues that are invoking the lambda with one request at a time.

Related

How to do performance testing of a lambda which is triggered by event bridge?

I have a lambda that is triggered whenever an event is dropped in the eventbus to which my lambda is connected and is triggered automatically. How can I performance test it to test how it performs of 500 events are dropped at a time?
Also I know aws has some inbuilt metrics like lambda execution time, xray tracing etc. Can anyone let me know how to use them for my use case?
If by "eventbus" you mean AWS EventBus which is a part of Amazon EventBrigde my expectation is that the easiest would be using PutEvents API endpoint, you can come up with a JSON payload having 500 events or make 500 separate calls with 1 event or any combination you can think of.
Be aware that the AWS API requests need to be signed to the load testing tool you choose must have the possibility to calculate this signature. A guide for Apache JMeter: How to Handle Dynamic AWS SigV4 in JMeter
With regards to metrics - check out AWS CloudWatch

What are the benefits of using SNS to SQS to Lambda compared to having SNS to SQS to SQSConsumers?

We have a SQS queue subscribe to SNS Topic which publishes about 1-5 million events per month. I want to know which of these combinations - SNS->SQS->Lambda vs SNS->SQS->SQSConsumer would benefit me for such use-cases.
I understand the maintain difference between them is Event driven Vs Pull Driven. A lambda is triggered for each message that comes into a queue so that is an event driven architecture, an SQSConsumer has to constantly poll for messages. You have to have constant up time for a poller like that vs a lambda that is only triggered once a message is received.
I have couple of questions here :
Why SNS->SQS-> Lambda is considered Event driven, when lambda has to poll the SQS queue similar to what SQSConsumer does?
Followup : When Lambda is also constantly polling, then why lambda is considered to be more cost efficient than SQSConsumer?
If you ignore the 'internals' of how Amazon SQS with AWS Lambda is implemented, simply think of it as SQS directly triggering the Lambda function. This is a serverless model, whereas using an SQS consumer requires code to be running on a computer somewhere. Lambda will automatically scale, so it is more cost effective than having computing infrastructure waiting around for events (and costing money even when it isn't used).
So, it's really a decision about whether to use a serverless architecture.
You could also subscribe the AWS Lambda function direction to the Amazon SNS topic, without using Amazon SQS in the middle.

AWS Event Bridge Lambda invocation

I have configured a lambda function as EventBridge rule target and I have configured a Dead Letter Queue on the EventBridge rule to capture exceptions.
Now, if the lambda function fails, Event Bridge does not recognize that failure as an error.
Since the EventBridge invocation to the Lambda is asynchronous, for EventBridge it is enough to reach the lambda to consider the event as successfull,but in this way I am not able to track and retry events once lambda fails.
Anyone know a way to make the EventBridge to the Lamdba request synchronous or another way to be able to Retry the events if the Lambda code fails after the invocation?
one option is to make the SQS to be rule target and use SQS event to trigger the lambda. when failure occurs, the lambda won't flag the event done so as to keep the event in the SQS. retry will auto happen after a configured period (SQS configuration). also you can configure dead letter queue after the retention time expires
EventBridge guarantees the delivery of the event to the lambda function but is not aware of what happens post that. It's lambda invocation vs lambda execution. Eventbridge successfully delivered the message to the lambda service, so it's a successful invocation.
For Lambda, EventBridge calls invokeAsync API. So, if this API sends a success response, EventBridge will assume the delivery was successful. Any failures within Lambda from async to sync is not visible to EventBridge. We should configure retries and create DLQs in our Lambda functions to make sure the events are not lost in case the Lambda function fails to execute. We could in fact configure the same DLQ used by the EventBridge to be used by the Lambda as well so that all eventual failures land in a single place.
AWS has a dedicated documentation page for this, which states the following for asynchronous invocation:
Lambda retries function errors twice. If the function doesn't have enough capacity to handle all incoming requests, events might wait in the queue for hours or days to be sent to the function. You can configure a dead-letter queue on the function to capture events that weren't successfully processed. For more information, see Asynchronous invocation.
So that means that as long as your Lambda functions handler function does return an error, the AWS Lambda service should retry to run your Lambda again.
Therefore, you might not need EventBridge to retry your event.
See: Error handling and automatic retries in AWS Lambda

Can a connected lambda function spin down before replying to Lex?

tldr: Is it possible for a connected Lambda codehook to spin down then spin back up (possibly multiple times) before replying to Lex?
Some details first: I have a Lambda function in Java 8 which is connected to an Intent on my Lex chatbot. This is a "Initialization and validation code hook" Lambda, meaning any time my intent is activated, Lex queries my Lambda with the input from the user using the Input Event format specified here: https://docs.aws.amazon.com/lex/latest/dg/lambda-input-response-format.html#using-lambda-response-format. Now the way I've been handling input events and responses is through a function called "handleRequest()", which takes as args an InputStream, OutputStream, and Context. After reading the InputStream and activating appropriate logic, I write to the OutputStream object provided as input to handleRequest (using the response format in the link above) and Lex is happy.
This is how things work now, and it has met my needs.
However, now I have a new problem. Part of my Lambda logic now relies on making a request to a third-party web API. After making this request, my Lambda spins down (it stops computing). Eventually, this third party API will make a call to my Lambda with information needed to fulfill my intent, but by this point since I have spun down my Lambda I have lost that OutputStream object which I used to write my response to Lex into.
My question is if there is another way. Is there a way to reply to Lex somehow else using Java 8? Maybe I make a reply to Lex directly from Lambda sometime after Lex calls Lambda and Lambda is ready. Has anyone else ever done this or had experience with a Lambda which needs to spin down before replying to Lex?
Please share any insights.
The old process that you describe was synchronous but now you're migrating it to be async and that means that you'll need to change your design: since the same lambda cannot do both the querying (to the 3rd party) and responding back to Lex, you'll have to create new "players":
once a lambda called the 3rd party, it should persist its data (context) into a persistence storage (DB) and exit
receiving the callback from the 3rd party will have to be done by a different lambda which will look in the DB to get the relevant context and combine it with the data it got from the 3rd party and after composing the result it will have to call Lex (this is not a response anymore!) to update it.
I'm not familiar with Lex so I can't tell you if that's supported by it.
Another option is, to see if instead of getting a callback from the third-party, you can poll for the result. If there's such an option the lambda can run in a loop that sleeps for a few seconds, then polls the 3rd party to get the result, until it does.
Important to note that lambda execution time in AWS is limited (up to 15 minutes) so if it takes longer to the 3rd party to resolve your queries - this solution will not work.

Best way to schedule one-time events in serverless environments

Example use case
Send the user a notification 2 hours after signup.
Options considered
setTimeout(() => { /* send notification */ }, 2*60*60*1000); is not an option in serverless environments since the function terminates after execution (so it has to be stateless).
CloudWatch events can schedule lambda invocations using cron expressions - but this was designed for repetitive invocations (there's a limit of 100 rules/region).
I have not seen scheduling options in AWS SNS/SQS or GCP Pub/Sub. Are there alternatives with scheduling?
I want to avoid (if possible) setting up a dedicated message broker (overkill) or stateful/non-serverless instance - is there a serverless way to do this?
I can queue the events in a database and invoke a lambda function every minute to poll the database for events to execute in that minute... is there a more elegant solution?
Use AWS Step functions, they are like serverless functions that don't have the 15 minute limit like AWS Lambda does. You can design a workflow in AWS step that integrates with API Gateway, Lambda and SNS to send email and text notifications as follows:
Create a REST API via API gateway that will invoke a Lambda function passing in for example, the destination address (email, phone #) of the SNS notification, when it should be sent, notification method (e.g. email, text, etc.).
The Lambda function on invocation will invoke the Step function passing in the data (Lambda is needed because API Gateway currently can't invoke Step functions directly).
The Step function is basically a workflow, you can define states for waiting (like waiting for the specified time to send the notification e.g. 30 seconds), and states for invoking other Lambda functions that can use SNS to send out an email and/or text notifications.
A rudimentary example is provided by AWS w/ their Task Timer example.
Things are coming on GCP for doing this, but not very soon. Thereby, today, the solution is to poll a database.
You can to that with Datastore/firestore with the execution datetime indexed (to prevent to read all the documents each minute). But be careful of traffic spike, you could create hotspot.
You can use Cloud Scheduler on Google Cloud Platform. As is is stated in the official documentation :
Cloud Scheduler is a fully managed enterprise-grade cron job scheduler. It allows you to schedule virtually any job, including batch, big data jobs, cloud infrastructure operations, and more. You can automate everything, including retries in case of failure to reduce manual toil and intervention. Cloud Scheduler even acts as a single pane of glass, allowing you to manage all your automation tasks from one place.
Here you can check a quickstart for using it with Pub/Sub and Cloud Functions.

Resources