2

I am building a Telegram bot in C#, deployed with AWS Lambda. Telegram bot and Lambda are connected via a webhook and work fine. I need to schedule deleting a bot's message in a few minutes without blocking the bot. It must keep accepting and process new requests.

As for now I see the solution in using Task.Delay. However, the instance created by AWS to execute lambda doesn't scale and users have to wait until the delay is ended to handle the following request from the queue.

From the official documentation:

The first time you invoke your function, AWS Lambda creates an instance of the function and runs its handler method to process the event. When the function returns a response, it stays active and waits to process additional events. If you invoke the function again while the first event is being processed, Lambda initializes another instance, and the function processes the two events concurrently. As more events come in, Lambda routes them to available instances and creates new instances as needed. When the number of requests decreases, Lambda stops unused instances to free up scaling capacity for other functions.

The default regional concurrency quota starts at 1,000 instances.

As far as I understand the whole Lambda thing is about delegating concurrent execution to AWS. If a handler takes some time to fulfil a request, then AWS automatically creates the second instance to process the following request. Isn't it?

How can I implement concurrency/configure lambda/rewrite code to enable handling multiple bot events?

I've already watched through AWS Step Functions and EventBridges to solve the problem, but before diving deeper into them it would make sense to clarify that there is no a simple and straightforward solution that I missed.

P.S. Please keep in mind that this is my first experience in building a telegram bot and using AWS Lambda functions. The problem may lie completely outside AWS and Telegram Bot API.

  • "However, the instance created by AWS to execute lambda doesn't scale and users have to wait until the delay is ended to handle the following request from the queue." How do you know this? You've tested this and seen this behavior? That's not how AWS Lambda works unless you have the concurrent execution setting configured with a value of `1`. – Mark B Feb 14 '22 at 13:26
  • Also, since you have to pay for each millisecond you run an AWS Lambda function, using `Task.Delay` inside a Lambda function is horribly inefficient and expensive. A better option would be to place the message in an SQS delay queue, and have another Lambda function read from that queue and do your deletes. – Mark B Feb 14 '22 at 13:27
  • @MarkB thanks for reply. I've concluded that basing on calling lambda with delay inside multiple times results in multiple responses with even delay between them. Where can I check configuration for concurrent execution? As for SQS delay queue I will check it out, thanks – alekseyknows Feb 14 '22 at 13:38

1 Answers1

2

You need to realize that when you trigger that delay in a Lambda function, that instance of the function becomes suspended and will not handle another request. A Lambda function instance will not be sent another request until it returns a response. The Lambda function instance is effectively blocked, just watching its system clock waiting for the 2 minute delay to finish.

When you trigger another request while the first request is waiting for the delay, all you are doing is starting another instance, which is then also going to sit and wait for its own 2 minute delay to complete.

The way you've coded this Lambda function, each request is going to trigger a 2 minute delay and wait for that delay before it returns a response. And you are getting charged for each of those 2 minute delays, because you are still occupying AWS compute resources, although all they are doing is monitoring a system clock for 2 minutes.

I suggest having your Lambda function quickly push the message into an SQS delay queue and exit as soon as it has done that. Then have another Lambda function configured with the SQS queue as an event source, that takes the SQS message and does your delete.

Mark B
  • 183,023
  • 24
  • 297
  • 295
  • 2
    I've created an SQS and another Lambda to handle delayed event and now it works like a charm. Thanks for your help! – alekseyknows Feb 14 '22 at 21:02