8000 [ESM] Re-initialize shards when NextShardIterator value is empty by gregfurman · Pull Request #12483 · localstack/localstack · GitHub
[go: up one dir, main page]

Skip to content

[ESM] Re-initialize shards when NextShardIterator value is empty #12483

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
Apr 4, 2025

Conversation

gregfurman
Copy link
Contributor
@gregfurman gregfurman commented Apr 4, 2025

Motivation

We do not currently cater for the case of a next shard iterator value not being present in a GetRecords response. According to the AWS doc:

In a production scenario, the only time the continuous loop should be exited is when the NextShardIterator value is NULL. When NextShardIterator is NULL, it means that the current shard has been closed and the ShardIteratorvalue would otherwise point past the last record.

In addition, DynamoDB Local can occasionally not return a NextShardIterator in its response. This seems to occur when trying to read from a closed shard or when using an expired iterator. Hence, an exception is raised since the StreamPoller always expects this field in a GetRecords response -- raising the below KeyError exception:

2025-03-20T16:02:18.318 ERROR --- [functhread17] l.s.l.e.esm_worker         : Error while polling messages for event source arn:aws:dynamodb:us-east-1:000000000000:table/test_table/stream/2025-03-19T22:20:57.833: 'NextShardIterator'
Traceback (most recent call last):
  File "/opt/code/localstack/.venv/lib/python3.11/site-packages/localstack/services/lambda_/event_source_mapping/esm_worker.py", line 155, in poller_loop
    self.poller.poll_events()
  File "/opt/code/localstack/.venv/lib/python3.11/site-packages/localstack/services/lambda_/event_source_mapping/pollers/stream_poller.py", line 155, in poll_events
    self.poll_events_from_shard(*current_shard_tuple)
  File "/opt/code/localstack/.venv/lib/python3.11/site-packages/localstack/services/lambda_/event_source_mapping/pollers/stream_poller.py", line 166, in poll_events_from_shard
    self.shards[shard_id] = get_records_response["NextShardIterator"]

Changes

  • Re-initialize shards when a NextShardIterator is not returned or is None in a GetRecords response.

@gregfurman gregfurman added semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases aws:lambda:event-source-mapping AWS Lambda Event Source Mapping (ESM) labels Apr 4, 2025
@gregfurman gregfurman added this to the 4.4 milestone Apr 4, 2025
@gregfurman gregfurman self-assigned this Apr 4, 2025
Copy link
github-actions bot commented Apr 4, 2025

LocalStack Community integration with Pro

    2 files  ±    0      2 suites  ±0   1h 32m 52s ⏱️ - 21m 52s
3 150 tests  - 1 173  2 923 ✅  - 1 056  227 💤  - 117  0 ❌ ±0 
3 152 runs   - 1 173  2 923 ✅  - 1 056  229 💤  - 117  0 ❌ ±0 

Results for commit cdc35b3. ± Comparison against base commit 8999cc4.

This pull request removes 1175 and adds 2 tests. Note that renamed tests count towards both.
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]
…
tests.aws.services.secretsmanager.test_secretsmanager.TestSecretsManager ‑ test_first_rotate_secret_with_missing_lambda_arn
tests.aws.services.secretsmanager.test_secretsmanager.TestSecretsManager ‑ test_rotate_secret_multiple_times_with_lambda_success

♻️ This comment has been updated with latest results.

@gregfurman gregfurman marked this pull request as ready for review April 4, 2025 12:25
Copy link
Member
@joe4dev joe4dev left a comment

Choose a reason for hiding this comment

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

Good catch and excellent link 👍

General limitation (unrelated to this change):
Do we clarify in the code and docs that resharding might lead to undefined/untested behavior?
I guess we could lose data with LATEST and potentially re-process records with AT_TIMESTAMP and TRIM_RECORDS here 😬

@@ -185,7 +185,10 @@ def poll_events(self):
def poll_events_from_shard(self, shard_id: str, shard_iterator: str):
get_records_response = self.get_records(shard_iterator)
records: list[dict] = get_records_response.get("Records", [])
next_shard_iterator = get_records_response["NextShardIterator"]
if not (next_shard_iterator := get_records_response.get("NextShardIterator")):
# If the next shard iterator is None, we can assume the shard is closed or
Copy link
Member

Choose a reason for hiding this comment

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

@gregfurman gregfurman merged commit 30a0d92 into master Apr 4, 2025
31 checks passed
@gregfurman gregfurman deleted the fix/esm/no-shard-iterator branch April 4, 2025 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws:lambda:event-source-mapping AWS Lambda Event Source Mapping (ESM) semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0