Skip to content

Idempotent start of the DynamoDB server #11815

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 2 commits into from
Nov 11, 2024
Merged

Idempotent start of the DynamoDB server #11815

merged 2 commits into from
Nov 11, 2024

Conversation

giograno
Copy link
Member

@giograno giograno commented Nov 8, 2024

Motivation

This PR is a follow-up of #11789.
@HarshCasper noticed a bunch of logs like the following when loading a DDB state in a container without an initialized DDB provider (i.e., start LS and immediately load):

2024-11-08T16:47:39.854 DEBUG --- [functhread27] l.services.dynamodb.server : Initializing DynamoDB Local with the following configuration:
2024-11-08T16:47:39.854 DEBUG --- [functhread27] l.services.dynamodb.server : Port:	37097
2024-11-08T16:47:39.854 DEBUG --- [functhread27] l.services.dynamodb.server : InMemory:	false
2024-11-08T16:47:39.854 DEBUG --- [functhread27] l.services.dynamodb.server : Version:	2.5.3
2024-11-08T16:47:39.854 DEBUG --- [functhread27] l.services.dynamodb.server : DbPath:	/tmp/localstack/state/dynamodb
2024-11-08T16:47:39.854 DEBUG --- [functhread27] l.services.dynamodb.server : SharedDb:	false
2024-11-08T16:47:39.854 DEBUG --- [functhread27] l.services.dynamodb.server : shouldDelayTransientStatuses:	false
2024-11-08T16:47:39.854 DEBUG --- [functhread27] l.services.dynamodb.server : CorsParams:	null
2024-11-08T16:47:39.855 DEBUG --- [functhread27] l.services.dynamodb.server : 
2024-11-08T16:47:40.456 DEBUG --- [functhread27] l.services.dynamodb.server : Exception in thread "main" java.io.IOException: Failed to bind to 0.0.0.0/0.0.0.0:37097
2024-11-08T16:47:40.458 DEBUG --- [functhread27] l.services.dynamodb.server : at org.eclipse.jetty.server.ServerConnector.openAcceptChannel(ServerConnector.java:349)

One can simply verify the behavior with:

export LOCALSTACK_AUTH_TOKEN="xxx"
localstack start
localstack pod load ddb-test # created this pod with some ddb state

This described scenario triggers these provider hooks in the following order:

  • on_after_state_load, which starts the DDB server on a given port via DynamodbServer::start_dynamodb;
  • on_before_start, which also calls DynamodbServer::start_dynamodb and tries to start DDB once again on the same port, causing the issue above.

Changes

  • To tackle the issue, I added a check in start_dynamoddb that verifies if the thread is already running and healthy, making the function idempotent.

ext pipeline to make sure persistence works correctly.

@giograno giograno added semver: patch Non-breaking changes which can be included in patch releases aws:dynamodb Amazon DynamoDB labels Nov 8, 2024
@giograno giograno added this to the 4.0 milestone Nov 8, 2024
Copy link

github-actions bot commented Nov 8, 2024

LocalStack Community integration with Pro

  2 files  ±    0    2 suites  ±0   26m 34s ⏱️ - 1h 16m 18s
870 tests  - 2 668  809 ✅  - 2 314  61 💤  - 354  0 ❌ ±0 
872 runs   - 2 668  809 ✅  - 2 314  63 💤  - 354  0 ❌ ±0 

Results for commit 74e1c23. ± Comparison against base commit d08dfc5.

This pull request removes 2668 tests.
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_lambda_dynamodb
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_opensearch_crud
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_search_books
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_setup
tests.aws.scenario.kinesis_firehose.test_kinesis_firehose.TestKinesisFirehoseScenario ‑ test_kinesis_firehose_s3
tests.aws.scenario.lambda_destination.test_lambda_destination_scenario.TestLambdaDestinationScenario ‑ test_destination_sns
tests.aws.scenario.lambda_destination.test_lambda_destination_scenario.TestLambdaDestinationScenario ‑ test_infra
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_prefill_dynamodb_table
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_stepfunctions_input_recipient_list[step_function_input0-SUCCEEDED]
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_stepfunctions_input_recipient_list[step_function_input1-SUCCEEDED]
…

♻️ This comment has been updated with latest results.

@giograno giograno marked this pull request as ready for review November 8, 2024 20:01
@@ -79,6 +79,10 @@ def get() -> "DynamodbServer":
def start_dynamodb(self) -> bool:
"""Start the DynamoDB server."""

# We want this method to be idempotent.
if self.is_running() and self.is_up():
return True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be invoked in a multi-threaded environment? If so, this should happen within the context of a mutex.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! I annotated the start_dynamodb function as we already do with stop_dynamodb. I think this should suffice.

Copy link
Member

@viren-nadkarni viren-nadkarni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ✔️

@giograno giograno merged commit ab64e0f into master Nov 11, 2024
32 checks passed
@giograno giograno deleted the ddb-idempotent-start branch November 11, 2024 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws:dynamodb Amazon DynamoDB semver: patch Non-breaking changes which can be included in patch releases
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants