8000 Make lambdas triggered by SQS run asynchronously by ronaldotd · Pull Request #1973 · localstack/localstack · GitHub
[go: up one dir, main page]

Skip to content

Make lambdas triggered by SQS run asynchronously #1973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 24, 2020
Merged

Make lambdas triggered by SQS run asynchronously #1973

merged 1 commit into from
Jan 24, 2020

Conversation

ronaldotd
Copy link
Contributor

This PR decouples SQS message processing and lambda execution by running lambdas asynchronously. It also adds a test on SNS-triggered lambdas to see if messages end up in the correct dead letter queue.
It addresses #1967.

@rfunix and @georgeyk contributed with suggestions and pairing.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.2%) to 50.608% when pulling 0dc0852 on ronaldotd:async-sqs-lambda into 178c22b on localstack:master.

@whummer
Copy link
Member
whummer commented Jan 24, 2020

Fantastic. Thanks a lot for adding this enhancement @ronaldotd and team!

@whummer whummer merged commit 132dd1a into localstack:master Jan 24, 2020
@ronaldotd
Copy link
Contributor Author

You're welcome @whummer 😉
Are there any plans for a new release on docker hub?

@whummer
Copy link
Member
whummer commented Jan 24, 2020

@ronaldotd The changes are automatically pushed by Travis-CI under the tag latest. Plus, we'll cut over a new release version soon (in the next couple of days).

@rp-199
Copy link
rp-199 commented Jan 26, 2020

@whummer Is it planned to make this optional? I know the goal it's to mimic the real AWS behaviour but having it running synchronously can be useful for testing.

For exemple, if we want to validate something just after the lambda execution ends ( e.g. check if something is saved into dynamodb). In a synchronous call the tests waits for the message to be processed so it is easy in the next step to validate the result in the database.

In an asynchronous call, we must implement that lock mechanism ourselves.

I currently have this problem in one of my java projects where all tests started failing after this change.

Test scenario:

  1. Start localstack with a docker compose with an SQS, lambda and Dynamodb
  2. Publish something into the SQS
  3. The lambda is triggered saving some data into DynamoDb
  4. Validate the data in the dynamodb.

The problem is that the step 4 runs before the step 3 finishes, because there's nothing that waits for it. Before this change, the test paused at step 2 and waited for step 3 to finish.

I haven't find a good workaround yet. The only thing that works it's to make the program wait for about 5-7 seconds after the message is published or use the last release.

Maybe there's some way to wait for the lambda execution to finish that I don't know of.

Sorry if here is not the place to ask this question...

@whummer
Copy link
Member
whummer commented Jan 26, 2020

@rp-199 I see your point. This indeed was a breaking change that may break existing tests out there.

Is it planned to make this optional? I know the goal it's to mimic the real AWS behaviour but having it running synchronously can be useful for testing.

I think the goal should be to mimic AWS as closely as possible. Clearly, the previous implementation (before we merged this PR) was making wrong assumptions in assuming that pushing a message to SQS synchronously waits until this message has been processed.

I think the best approach here would be to have some retry logic in place (rather than sleep-based test logic, which is often inherently error-prone).

Note that the same logic (e.g., retries) would be required if testing against real AWS - and I don't think we should introduce shortcuts that make our lives "easier" by diverging from AWS.

I'd rather invest in building utility libraries that simplify testing in this case. We could create a small utility function that blocks and waits until an SQS message has been processed, or blocks and polls results from a DynamoDB table until they appear.

Which programming language are you using in your project? Happy to help build a few such libraries that are commonly useful and could be shared with the community.

Thoughts?

@rp-199
Copy link
rp-199 commented Jan 27, 2020

Thanks for the reply @whummer and for the support of this awesome project!

I totally agree with you, I think the localstack must be as approximate as possible to the real thing, just suggested to make this optional to allow retrocompatibility. But you have a good point, is better to implement this logic through some test utility library.

Sleep based test logic is horrible and only should be used like a last resort thing, should be avoid at all costs.

My project has a microservice architecture, all based in AWS and all written in Java 8 (I was trying to move it to 11 when I discover this issue). I use localstack for functional testing on each microservice using cucumber.

The common use case is the following:
SNS -> SQS -> Lambda -> DynamoDB

I need a way to figure out that lambda execution is finished. I tried to use cloudwatch for that, to check the invocation metrics but encountered some strange behaviour.

We could create a small utility function that blocks and waits until an SQS message has been processed

That would be great! I'll gladly help with any Java development... I can read python but I've no experience on developing with it.

@mywill
Copy link
mywill commented Oct 28, 2021

@whummer was anything done in regards to a utility or some way to recreate the old functionality I'm attempting to update a older project that relied on synchronous invocation from sqs to a lambda for use in some testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0