From 92d21eccf3a4dc30b2160fd7b89cb3f67572f16d Mon Sep 17 00:00:00 2001 From: Dan Straw Date: Mon, 4 Dec 2023 11:35:03 +0000 Subject: [PATCH 01/11] feat: add ReturnValuesOnConditionCheckFailure to DynamoDB idempotency to return a copy of the item on failure and avoid a subsequent get #3327 --- .../utilities/idempotency/base.py | 16 ++- .../utilities/idempotency/exceptions.py | 16 +++ .../utilities/idempotency/persistence/base.py | 107 ++++-------------- .../idempotency/persistence/datarecord.py | 93 +++++++++++++++ .../idempotency/persistence/dynamodb.py | 44 ++++++- docs/utilities/idempotency.md | 4 +- pyproject.toml | 2 +- tests/functional/idempotency/conftest.py | 8 +- .../idempotency/test_idempotency.py | 101 +++++------------ tests/functional/idempotency/utils.py | 1 + .../idempotency/test_dynamodb_persistence.py | 11 ++ 11 files changed, 235 insertions(+), 168 deletions(-) create mode 100644 aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py diff --git a/aws_lambda_powertools/utilities/idempotency/base.py b/aws_lambda_powertools/utilities/idempotency/base.py index a8d509b86eb..ed9fe4da0eb 100644 --- a/aws_lambda_powertools/utilities/idempotency/base.py +++ b/aws_lambda_powertools/utilities/idempotency/base.py @@ -14,8 +14,10 @@ IdempotencyValidationError, ) from aws_lambda_powertools.utilities.idempotency.persistence.base import ( - STATUS_CONSTANTS, BasePersistenceLayer, +) +from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import ( + STATUS_CONSTANTS, DataRecord, ) from aws_lambda_powertools.utilities.idempotency.serialization.base import ( @@ -118,11 +120,15 @@ def _process_idempotency(self): data=self.data, remaining_time_in_millis=self._get_remaining_time_in_millis(), ) - except IdempotencyKeyError: + except (IdempotencyKeyError, IdempotencyValidationError): raise - except IdempotencyItemAlreadyExistsError: - # Now we know the item already exists, we can retrieve it - record = self._get_idempotency_record() + except IdempotencyItemAlreadyExistsError as exc: + # We now know the item exists + # Attempt to retrieve the record from the exception where ReturnValuesOnConditionCheckFailure is supported + record = exc.old_data_record + if record is None: + # Perform a GET on the record + record = self._get_idempotency_record() if record is not None: return self._handle_for_status(record) except Exception as exc: diff --git a/aws_lambda_powertools/utilities/idempotency/exceptions.py b/aws_lambda_powertools/utilities/idempotency/exceptions.py index 6e5930549c4..8f5f6698bba 100644 --- a/aws_lambda_powertools/utilities/idempotency/exceptions.py +++ b/aws_lambda_powertools/utilities/idempotency/exceptions.py @@ -5,6 +5,8 @@ from typing import Optional, Union +from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import DataRecord + class BaseError(Exception): """ @@ -30,6 +32,20 @@ class IdempotencyItemAlreadyExistsError(BaseError): Item attempting to be inserted into persistence store already exists and is not expired """ + def __init__(self, *args: Optional[Union[str, Exception]], old_data_record: Optional[DataRecord] = None): + self.message = str(args[0]) if args else "" + self.details = "".join(str(arg) for arg in args[1:]) if args[1:] else None + self.old_data_record = old_data_record + + def __str__(self): + """ + Return all arguments formatted or original message + """ + old_data_record = f" from [{(str(self.old_data_record))}]" if self.old_data_record else "" + details = f" - ({self.details})" if self.details else "" + + return f"{self.message}{details}{old_data_record}" + class IdempotencyItemNotFoundError(BaseError): """ diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/base.py b/aws_lambda_powertools/utilities/idempotency/persistence/base.py index eaea36127c1..bf661965807 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/base.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/base.py @@ -8,7 +8,6 @@ import os import warnings from abc import ABC, abstractmethod -from types import MappingProxyType from typing import Any, Dict, Optional import jmespath @@ -18,95 +17,18 @@ from aws_lambda_powertools.shared.json_encoder import Encoder from aws_lambda_powertools.utilities.idempotency.config import IdempotencyConfig from aws_lambda_powertools.utilities.idempotency.exceptions import ( - IdempotencyInvalidStatusError, IdempotencyItemAlreadyExistsError, IdempotencyKeyError, IdempotencyValidationError, ) +from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import ( + STATUS_CONSTANTS, + DataRecord, +) from aws_lambda_powertools.utilities.jmespath_utils import PowertoolsFunctions logger = logging.getLogger(__name__) -STATUS_CONSTANTS = MappingProxyType({"INPROGRESS": "INPROGRESS", "COMPLETED": "COMPLETED", "EXPIRED": "EXPIRED"}) - - -class DataRecord: - """ - Data Class for idempotency records. - """ - - def __init__( - self, - idempotency_key: str, - status: str = "", - expiry_timestamp: Optional[int] = None, - in_progress_expiry_timestamp: Optional[int] = None, - response_data: str = "", - payload_hash: str = "", - ) -> None: - """ - - Parameters - ---------- - idempotency_key: str - hashed representation of the idempotent data - status: str, optional - status of the idempotent record - expiry_timestamp: int, optional - time before the record should expire, in seconds - in_progress_expiry_timestamp: int, optional - time before the record should expire while in the INPROGRESS state, in seconds - payload_hash: str, optional - hashed representation of payload - response_data: str, optional - response data from previous executions using the record - """ - self.idempotency_key = idempotency_key - self.payload_hash = payload_hash - self.expiry_timestamp = expiry_timestamp - self.in_progress_expiry_timestamp = in_progress_expiry_timestamp - self._status = status - self.response_data = response_data - - @property - def is_expired(self) -> bool: - """ - Check if data record is expired - - Returns - ------- - bool - Whether the record is currently expired or not - """ - return bool(self.expiry_timestamp and int(datetime.datetime.now().timestamp()) > self.expiry_timestamp) - - @property - def status(self) -> str: - """ - Get status of data record - - Returns - ------- - str - """ - if self.is_expired: - return STATUS_CONSTANTS["EXPIRED"] - elif self._status in STATUS_CONSTANTS.values(): - return self._status - else: - raise IdempotencyInvalidStatusError(self._status) - - def response_json_as_dict(self) -> Optional[dict]: - """ - Get response data deserialized to python dict - - Returns - ------- - Optional[dict] - previous response data deserialized - """ - return json.loads(self.response_data) if self.response_data else None - class BasePersistenceLayer(ABC): """ @@ -260,6 +182,27 @@ def _validate_payload(self, data: Dict[str, Any], data_record: DataRecord) -> No if data_record.payload_hash != data_hash: raise IdempotencyValidationError("Payload does not match stored record for this event key") + def _validate_hashed_payload(self, old_data_record: DataRecord, data_record: DataRecord) -> None: + """ + Validate that the hashed data provided matches the payload_hash stored data record + + Parameters + ---------- + old_data_record: DataRecord + DataRecord instance fetched from Dynamo + data_record: DataRecord + DataRecord instance which failed insert into Dynamo + + Raises + ---------- + IdempotencyValidationError + Payload doesn't match the stored record for the given idempotency key + + """ + if self.payload_validation_enabled: + if old_data_record.payload_hash != data_record.payload_hash: + raise IdempotencyValidationError("Hashed payload does not match stored record for this event key") + def _get_expiry_timestamp(self) -> int: """ diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py b/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py new file mode 100644 index 00000000000..607e238c3a0 --- /dev/null +++ b/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py @@ -0,0 +1,93 @@ +""" +Data Class for idempotency records. +""" + +import datetime +import json +import logging +from types import MappingProxyType +from typing import Optional + +logger = logging.getLogger(__name__) + +STATUS_CONSTANTS = MappingProxyType({"INPROGRESS": "INPROGRESS", "COMPLETED": "COMPLETED", "EXPIRED": "EXPIRED"}) + + +class DataRecord: + """ + Data Class for idempotency records. + """ + + def __init__( + self, + idempotency_key: str, + status: str = "", + expiry_timestamp: Optional[int] = None, + in_progress_expiry_timestamp: Optional[int] = None, + response_data: str = "", + payload_hash: str = "", + ) -> None: + """ + + Parameters + ---------- + idempotency_key: str + hashed representation of the idempotent data + status: str, optional + status of the idempotent record + expiry_timestamp: int, optional + time before the record should expire, in seconds + in_progress_expiry_timestamp: int, optional + time before the record should expire while in the INPROGRESS state, in seconds + payload_hash: str, optional + hashed representation of payload + response_data: str, optional + response data from previous executions using the record + """ + self.idempotency_key = idempotency_key + self.payload_hash = payload_hash + self.expiry_timestamp = expiry_timestamp + self.in_progress_expiry_timestamp = in_progress_expiry_timestamp + self._status = status + self.response_data = response_data + + @property + def is_expired(self) -> bool: + """ + Check if data record is expired + + Returns + ------- + bool + Whether the record is currently expired or not + """ + return bool(self.expiry_timestamp and int(datetime.datetime.now().timestamp()) > self.expiry_timestamp) + + @property + def status(self) -> str: + """ + Get status of data record + + Returns + ------- + str + """ + if self.is_expired: + return STATUS_CONSTANTS["EXPIRED"] + if self._status in STATUS_CONSTANTS.values(): + return self._status + + from aws_lambda_powertools.utilities.idempotency.exceptions import IdempotencyInvalidStatusError + + raise IdempotencyInvalidStatusError(self._status) + + def response_json_as_dict(self) -> Optional[dict]: + """ + Get response data deserialized to python dict + + Returns + ------- + Optional[dict] + previous response data deserialized + """ + return json.loads(self.response_data) if self.response_data else None diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py index 295f869dc3e..31e7b81bdac 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py @@ -15,8 +15,9 @@ from aws_lambda_powertools.utilities.idempotency.exceptions import ( IdempotencyItemAlreadyExistsError, IdempotencyItemNotFoundError, + IdempotencyValidationError, ) -from aws_lambda_powertools.utilities.idempotency.persistence.base import ( +from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import ( STATUS_CONSTANTS, DataRecord, ) @@ -234,16 +235,51 @@ def _put_record(self, data_record: DataRecord) -> None: ":now_in_millis": {"N": str(int(now.timestamp() * 1000))}, ":inprogress": {"S": STATUS_CONSTANTS["INPROGRESS"]}, }, + **( + {"ReturnValuesOnConditionCheckFailure": "ALL_OLD"} # type: ignore + if self.boto3_supports_condition_check_failure(boto3.__version__) + else {} + ), ) except ClientError as exc: error_code = exc.response.get("Error", {}).get("Code") if error_code == "ConditionalCheckFailedException": + old_data_record = self._item_to_data_record(exc.response["Item"]) if "Item" in exc.response else None + if old_data_record is not None: + logger.debug( + f"Failed to put record for already existing idempotency key: " + f"{data_record.idempotency_key} with status: {old_data_record.status}, " + f"expiry_timestamp: {old_data_record.expiry_timestamp}, " + f"and in_progress_expiry_timestamp: {old_data_record.in_progress_expiry_timestamp}", + ) + self._save_to_cache(data_record=old_data_record) + + try: + self._validate_hashed_payload(old_data_record=old_data_record, data_record=data_record) + except IdempotencyValidationError as ive: + raise ive from exc + + raise IdempotencyItemAlreadyExistsError(old_data_record=old_data_record) from exc + logger.debug( f"Failed to put record for already existing idempotency key: {data_record.idempotency_key}", ) - raise IdempotencyItemAlreadyExistsError from exc - else: - raise + raise IdempotencyItemAlreadyExistsError() from exc + + raise + + @staticmethod + def boto3_supports_condition_check_failure(boto3_version: str): + version = boto3_version.split(".") + # Only supported in boto3 1.26.164 and above + if len(version) >= 3 and int(version[0]) == 1 and int(version[1]) == 26 and int(version[2]) >= 164: + return True + if len(version) >= 2 and int(version[0]) == 1 and int(version[1]) > 26: + return True + if int(version[0]) > 1: + return True + + return False def _update_record(self, data_record: DataRecord): logger.debug(f"Updating record for idempotency key: {data_record.idempotency_key}") diff --git a/docs/utilities/idempotency.md b/docs/utilities/idempotency.md index 0d79cbf092e..fee513c8592 100644 --- a/docs/utilities/idempotency.md +++ b/docs/utilities/idempotency.md @@ -100,8 +100,8 @@ If you're not [changing the default configuration for the DynamoDB persistence l ???+ info "Info: DynamoDB" Each function invocation will generally make 2 requests to DynamoDB. If the - result returned by your Lambda is less than 1kb, you can expect 2 WCUs per invocation. For retried invocations, you will - see 1WCU and 1RCU. Review the [DynamoDB pricing documentation](https://aws.amazon.com/dynamodb/pricing/){target="_blank"} to + result returned by your Lambda is less than 1kb, you can expect 2 WCUs per invocation. + Review the [DynamoDB pricing documentation](https://aws.amazon.com/dynamodb/pricing/){target="_blank"} to estimate the cost. ### Idempotent decorator diff --git a/pyproject.toml b/pyproject.toml index 3fa1ed9301d..d184a4e1867 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ aws-encryption-sdk = { version = "^3.1.1", optional = true } coverage = {extras = ["toml"], version = "^7.2"} pytest = "^7.4.3" black = "^23.3" -boto3 = "^1.18" +boto3 = "^1.26.164" isort = "^5.11.5" pytest-cov = "^4.1.0" pytest-mock = "^3.11.1" diff --git a/tests/functional/idempotency/conftest.py b/tests/functional/idempotency/conftest.py index 9bacfb58779..845f20ef082 100644 --- a/tests/functional/idempotency/conftest.py +++ b/tests/functional/idempotency/conftest.py @@ -1,4 +1,5 @@ import datetime +import hashlib import json from decimal import Decimal from unittest import mock @@ -9,6 +10,7 @@ from botocore.config import Config from jmespath import functions +from aws_lambda_powertools.shared.json_encoder import Encoder from aws_lambda_powertools.utilities.idempotency import DynamoDBPersistenceLayer from aws_lambda_powertools.utilities.idempotency.idempotency import IdempotencyConfig from aws_lambda_powertools.utilities.jmespath_utils import extract_data_from_envelope @@ -131,6 +133,7 @@ def expected_params_put_item(hashed_idempotency_key): "attribute_not_exists(#id) OR #expiry < :now OR " "(#status = :inprogress AND attribute_exists(#in_progress_expiry) AND #in_progress_expiry < :now_in_millis)" ), + "ReturnValuesOnConditionCheckFailure": "ALL_OLD", "ExpressionAttributeNames": { "#id": "id", "#expiry": "expiration", @@ -159,6 +162,7 @@ def expected_params_put_item_with_validation(hashed_idempotency_key, hashed_vali "attribute_not_exists(#id) OR #expiry < :now OR " "(#status = :inprogress AND attribute_exists(#in_progress_expiry) AND #in_progress_expiry < :now_in_millis)" ), + "ReturnValuesOnConditionCheckFailure": "ALL_OLD", "ExpressionAttributeNames": { "#id": "id", "#expiry": "expiration", @@ -206,7 +210,9 @@ def hashed_idempotency_key_with_envelope(request, lambda_apigw_event): @pytest.fixture def hashed_validation_key(lambda_apigw_event): - return hash_idempotency_key(lambda_apigw_event["requestContext"]) + return hashlib.md5( + json.dumps(lambda_apigw_event["requestContext"], cls=Encoder, sort_keys=True).encode(), + ).hexdigest() @pytest.fixture diff --git a/tests/functional/idempotency/test_idempotency.py b/tests/functional/idempotency/test_idempotency.py index 24fcd76b4d5..be91871caa1 100644 --- a/tests/functional/idempotency/test_idempotency.py +++ b/tests/functional/idempotency/test_idempotency.py @@ -87,14 +87,7 @@ def test_idempotent_lambda_already_completed( "status": {"S": "COMPLETED"}, }, } - - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": hashed_idempotency_key}}, - "ConsistentRead": True, - } - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store) @@ -124,11 +117,6 @@ def test_idempotent_lambda_in_progress( stubber = stub.Stubber(persistence_store.client) - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": hashed_idempotency_key}}, - "ConsistentRead": True, - } ddb_response = { "Item": { "id": {"S": hashed_idempotency_key}, @@ -137,8 +125,7 @@ def test_idempotent_lambda_in_progress( }, } - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store) @@ -176,11 +163,6 @@ def test_idempotent_lambda_in_progress_with_cache( retrieve_from_cache_spy = mocker.spy(persistence_store, "_retrieve_from_cache") stubber = stub.Stubber(persistence_store.client) - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": hashed_idempotency_key}}, - "ConsistentRead": True, - } ddb_response = { "Item": { "id": {"S": hashed_idempotency_key}, @@ -189,14 +171,12 @@ def test_idempotent_lambda_in_progress_with_cache( }, } - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", copy.deepcopy(ddb_response), copy.deepcopy(expected_params)) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=copy.deepcopy(ddb_response)) + + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=copy.deepcopy(ddb_response)) - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", copy.deepcopy(ddb_response), copy.deepcopy(expected_params)) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store) @@ -212,7 +192,7 @@ def lambda_handler(event, context): "body=a3edd699125517bb49d562501179ecbd" ) - assert retrieve_from_cache_spy.call_count == 2 * loops + assert retrieve_from_cache_spy.call_count == loops retrieve_from_cache_spy.assert_called_with(idempotency_key=hashed_idempotency_key) save_to_cache_spy.assert_called() @@ -411,7 +391,6 @@ def lambda_handler(event, context): "idempotency_config", [ {"use_local_cache": False, "payload_validation_jmespath": "requestContext"}, - {"use_local_cache": True, "payload_validation_jmespath": "requestContext"}, ], indirect=True, ) @@ -439,11 +418,7 @@ def test_idempotent_lambda_already_completed_with_validation_bad_payload( "validation": {"S": hashed_validation_key}, }, } - - expected_params = {"TableName": TABLE_NAME, "Key": {"id": {"S": hashed_idempotency_key}}, "ConsistentRead": True} - - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store) @@ -458,56 +433,49 @@ def lambda_handler(event, context): stubber.deactivate() -@pytest.mark.parametrize("idempotency_config", [{"use_local_cache": False}, {"use_local_cache": True}], indirect=True) -def test_idempotent_lambda_expired_during_request( +@pytest.mark.parametrize( + "idempotency_config", + [{"use_local_cache": True, "payload_validation_jmespath": "requestContext"}], + indirect=True, +) +def test_idempotent_lambda_already_completed_with_validation_bad_payload_from_local_cache( idempotency_config: IdempotencyConfig, persistence_store: DynamoDBPersistenceLayer, lambda_apigw_event, - timestamp_expired, + timestamp_future, lambda_response, hashed_idempotency_key, + hashed_validation_key, lambda_context, ): """ - Test idempotent decorator when lambda is called with an event it successfully handled already. Persistence store - returns inconsistent/rapidly changing result between put_item and get_item calls. + Test idempotent decorator where event with matching event key has already been successfully processed + Fetching record from local cache """ stubber = stub.Stubber(persistence_store.client) - - ddb_response_get_item = { + ddb_response = { "Item": { "id": {"S": hashed_idempotency_key}, - "expiration": {"N": timestamp_expired}, + "expiration": {"N": timestamp_future}, "data": {"S": '{"message": "test", "statusCode": 200}'}, - "status": {"S": "INPROGRESS"}, + "status": {"S": "COMPLETED"}, + "validation": {"S": hashed_validation_key}, }, } - ddb_response_get_item_missing = {} - expected_params_get_item = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": hashed_idempotency_key}}, - "ConsistentRead": True, - } - # Simulate record repeatedly changing state between put_item and get_item - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response_get_item, expected_params_get_item) - - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response_get_item_missing) + expected_params = {"TableName": TABLE_NAME, "Key": {"id": {"S": hashed_idempotency_key}}, "ConsistentRead": True} stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", copy.deepcopy(ddb_response_get_item), copy.deepcopy(expected_params_get_item)) - + stubber.add_response("get_item", ddb_response, expected_params) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store) def lambda_handler(event, context): return lambda_response - # max retries exceeded before get_item and put_item agree on item state, so exception gets raised - with pytest.raises(IdempotencyInconsistentStateError): + with pytest.raises(IdempotencyValidationError): + lambda_apigw_event["requestContext"]["accountId"] += "1" # Alter the request payload lambda_handler(lambda_apigw_event, lambda_context) stubber.assert_no_pending_responses() @@ -675,13 +643,7 @@ def test_idempotent_lambda_with_validator_util( }, } - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": hashed_idempotency_key_with_envelope}}, - "ConsistentRead": True, - } - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @validator(envelope=envelopes.API_GATEWAY_HTTP) @@ -1791,7 +1753,6 @@ def test_idempotent_lambda_compound_already_completed( """ stubber = stub.Stubber(persistence_store_compound.client) - stubber.add_client_error("put_item", "ConditionalCheckFailedException") ddb_response = { "Item": { "id": {"S": "idempotency#"}, @@ -1801,13 +1762,7 @@ def test_idempotent_lambda_compound_already_completed( "status": {"S": "COMPLETED"}, }, } - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": "idempotency#"}, "sk": {"S": hashed_idempotency_key}}, - "ConsistentRead": True, - } - stubber.add_response("get_item", ddb_response, expected_params) - + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store_compound) diff --git a/tests/functional/idempotency/utils.py b/tests/functional/idempotency/utils.py index bf57259fe76..60f28b075b6 100644 --- a/tests/functional/idempotency/utils.py +++ b/tests/functional/idempotency/utils.py @@ -26,6 +26,7 @@ def build_idempotency_put_item_stub( "attribute_not_exists(#id) OR #expiry < :now OR " "(#status = :inprogress AND attribute_exists(#in_progress_expiry) AND #in_progress_expiry < :now_in_millis)" ), + "ReturnValuesOnConditionCheckFailure": "ALL_OLD", "ExpressionAttributeNames": { "#id": "id", "#expiry": "expiration", diff --git a/tests/unit/idempotency/test_dynamodb_persistence.py b/tests/unit/idempotency/test_dynamodb_persistence.py index 9455c41ad8d..b27ef00550c 100644 --- a/tests/unit/idempotency/test_dynamodb_persistence.py +++ b/tests/unit/idempotency/test_dynamodb_persistence.py @@ -19,3 +19,14 @@ class DummyClient: # THEN assert persistence_layer.table_name == table_name assert persistence_layer.client == fake_client + + +def test_boto3_version_supports_condition_check_failure(): + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("0.0.3") is False + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.25") is False + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.25") is False + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.26.163") is False + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.26.164") is True + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.26.165") is True + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.27.0") is True + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("2.0.0") is True From bd92f33c7837bf3f246752a153bec0947f849067 Mon Sep 17 00:00:00 2001 From: Dan Straw Date: Mon, 4 Dec 2023 12:39:17 +0000 Subject: [PATCH 02/11] feat: add ReturnValuesOnConditionCheckFailure to DynamoDB idempotency to return a copy of the item on failure and avoid a subsequent get #3327 --- .../idempotency/test_idempotency.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/functional/idempotency/test_idempotency.py b/tests/functional/idempotency/test_idempotency.py index be91871caa1..7f11230c31d 100644 --- a/tests/functional/idempotency/test_idempotency.py +++ b/tests/functional/idempotency/test_idempotency.py @@ -433,6 +433,66 @@ def lambda_handler(event, context): stubber.deactivate() +@pytest.mark.parametrize("idempotency_config", [{"use_local_cache": False}, {"use_local_cache": True}], indirect=True) +def test_idempotent_lambda_expired_during_request( + idempotency_config: IdempotencyConfig, + persistence_store: DynamoDBPersistenceLayer, + lambda_apigw_event, + timestamp_expired, + lambda_response, + hashed_idempotency_key, + mocker, + lambda_context, +): + """ + Test idempotent decorator when lambda is called with an event it successfully handled already. Persistence store + returns inconsistent/rapidly changing result between put_item and get_item calls. + """ + + stubber = stub.Stubber(persistence_store.client) + + ddb_response_get_item = { + "Item": { + "id": {"S": hashed_idempotency_key}, + "expiration": {"N": timestamp_expired}, + "data": {"S": '{"message": "test", "statusCode": 200}'}, + "status": {"S": "INPROGRESS"}, + }, + } + ddb_response_get_item_missing = {} + expected_params_get_item = { + "TableName": TABLE_NAME, + "Key": {"id": {"S": hashed_idempotency_key}}, + "ConsistentRead": True, + } + + # Simulate record repeatedly changing state between put_item and get_item + stubber.add_client_error("put_item", "ConditionalCheckFailedException") + stubber.add_response("get_item", ddb_response_get_item, expected_params_get_item) + + stubber.add_client_error("put_item", "ConditionalCheckFailedException") + stubber.add_response("get_item", ddb_response_get_item_missing) + + stubber.add_client_error("put_item", "ConditionalCheckFailedException") + stubber.add_response("get_item", copy.deepcopy(ddb_response_get_item), copy.deepcopy(expected_params_get_item)) + + stubber.activate() + + submethod_mocked = mocker.patch.object(DynamoDBPersistenceLayer, "boto3_supports_condition_check_failure") + submethod_mocked.return_value = False + + @idempotent(config=idempotency_config, persistence_store=persistence_store) + def lambda_handler(event, context): + return lambda_response + + # max retries exceeded before get_item and put_item agree on item state, so exception gets raised + with pytest.raises(IdempotencyInconsistentStateError): + lambda_handler(lambda_apigw_event, lambda_context) + + stubber.assert_no_pending_responses() + stubber.deactivate() + + @pytest.mark.parametrize( "idempotency_config", [{"use_local_cache": True, "payload_validation_jmespath": "requestContext"}], From dd3707dd631eb5a63c42439bf87a7f32622c3430 Mon Sep 17 00:00:00 2001 From: Dan Straw Date: Sun, 14 Jan 2024 18:07:43 +0000 Subject: [PATCH 03/11] feat: add ReturnValuesOnConditionCheckFailure to DynamoDB idempotency to return a copy of the item on failure and avoid a subsequent get #3327. Changes after PR comments --- .../utilities/idempotency/exceptions.py | 8 ++-- .../utilities/idempotency/persistence/base.py | 47 +++++++------------ .../idempotency/persistence/dynamodb.py | 32 ++++++++----- 3 files changed, 39 insertions(+), 48 deletions(-) diff --git a/aws_lambda_powertools/utilities/idempotency/exceptions.py b/aws_lambda_powertools/utilities/idempotency/exceptions.py index 407a218db8f..55ec662799e 100644 --- a/aws_lambda_powertools/utilities/idempotency/exceptions.py +++ b/aws_lambda_powertools/utilities/idempotency/exceptions.py @@ -33,18 +33,16 @@ class IdempotencyItemAlreadyExistsError(BaseError): """ def __init__(self, *args: Optional[Union[str, Exception]], old_data_record: Optional[DataRecord] = None): - self.message = str(args[0]) if args else "" - self.details = "".join(str(arg) for arg in args[1:]) if args[1:] else None self.old_data_record = old_data_record + super().__init__(*args) def __str__(self): """ Return all arguments formatted or original message """ old_data_record = f" from [{(str(self.old_data_record))}]" if self.old_data_record else "" - details = f" - ({self.details})" if self.details else "" - - return f"{self.message}{details}{old_data_record}" + message = super().__str__() + return f"{message}{old_data_record}" class IdempotencyItemNotFoundError(BaseError): diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/base.py b/aws_lambda_powertools/utilities/idempotency/persistence/base.py index c658715a926..335c7ecc9fb 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/base.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/base.py @@ -8,7 +8,7 @@ import os import warnings from abc import ABC, abstractmethod -from typing import Any, Dict, Optional +from typing import Any, Dict, Optional, Union import jmespath @@ -160,16 +160,20 @@ def _generate_hash(self, data: Any) -> str: hashed_data = self.hash_function(json.dumps(data, cls=Encoder, sort_keys=True).encode()) return hashed_data.hexdigest() - def _validate_payload(self, data: Dict[str, Any], data_record: DataRecord) -> None: + def _validate_payload( + self, + data_payload: Union[Dict[str, Any], DataRecord], + stored_data_record: DataRecord, + ) -> None: """ Validate that the hashed payload matches data provided and stored data record Parameters ---------- - data: Dict[str, Any] + data_payload: Union[Dict[str, Any], DataRecord] Payload - data_record: DataRecord - DataRecord instance + stored_data_record: DataRecord + DataRecord fetched from Dynamo or cache Raises ---------- @@ -178,30 +182,13 @@ def _validate_payload(self, data: Dict[str, Any], data_record: DataRecord) -> No """ if self.payload_validation_enabled: - data_hash = self._get_hashed_payload(data=data) - if data_record.payload_hash != data_hash: - raise IdempotencyValidationError("Payload does not match stored record for this event key") - - def _validate_hashed_payload(self, old_data_record: DataRecord, data_record: DataRecord) -> None: - """ - Validate that the hashed data provided matches the payload_hash stored data record - - Parameters - ---------- - old_data_record: DataRecord - DataRecord instance fetched from Dynamo - data_record: DataRecord - DataRecord instance which failed insert into Dynamo + if isinstance(data_payload, DataRecord): + data_hash = data_payload.payload_hash + else: + data_hash = self._get_hashed_payload(data=data_payload) - Raises - ---------- - IdempotencyValidationError - Payload doesn't match the stored record for the given idempotency key - - """ - if self.payload_validation_enabled: - if old_data_record.payload_hash != data_record.payload_hash: - raise IdempotencyValidationError("Hashed payload does not match stored record for this event key") + if stored_data_record.payload_hash != data_hash: + raise IdempotencyValidationError("Payload does not match stored record for this event key") def _get_expiry_timestamp(self) -> int: """ @@ -391,14 +378,14 @@ def get_record(self, data: Dict[str, Any]) -> Optional[DataRecord]: cached_record = self._retrieve_from_cache(idempotency_key=idempotency_key) if cached_record: logger.debug(f"Idempotency record found in cache with idempotency key: {idempotency_key}") - self._validate_payload(data=data, data_record=cached_record) + self._validate_payload(data_payload=data, stored_data_record=cached_record) return cached_record record = self._get_record(idempotency_key=idempotency_key) self._save_to_cache(data_record=record) - self._validate_payload(data=data, data_record=record) + self._validate_payload(data_payload=data, stored_data_record=record) return record @abstractmethod diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py index 548e8c7def0..49127277579 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py @@ -257,9 +257,9 @@ def _put_record(self, data_record: DataRecord) -> None: self._save_to_cache(data_record=old_data_record) try: - self._validate_hashed_payload(old_data_record=old_data_record, data_record=data_record) - except IdempotencyValidationError as ive: - raise ive from exc + self._validate_payload(data_payload=data_record, stored_data_record=old_data_record) + except IdempotencyValidationError as idempotency_validation_error: + raise idempotency_validation_error from exc raise IdempotencyItemAlreadyExistsError(old_data_record=old_data_record) from exc @@ -271,17 +271,23 @@ def _put_record(self, data_record: DataRecord) -> None: raise @staticmethod - def boto3_supports_condition_check_failure(boto3_version: str): - version = boto3_version.split(".") + def boto3_supports_condition_check_failure(boto3_version: str) -> bool: + """ + Check if the installed boto3 version supports condition check failure. + + Params + ------ + boto3_version: str + The boto3 version + + Returns + ------- + bool + True if the boto3 version supports condition check failure, False otherwise. + """ # Only supported in boto3 1.26.164 and above - if len(version) >= 3 and int(version[0]) == 1 and int(version[1]) == 26 and int(version[2]) >= 164: - return True - if len(version) >= 2 and int(version[0]) == 1 and int(version[1]) > 26: - return True - if int(version[0]) > 1: - return True - - return False + major, minor, *patch = map(int, boto3_version.split(".")) + return (major, minor, *patch) >= (1, 26, 164) def _update_record(self, data_record: DataRecord): logger.debug(f"Updating record for idempotency key: {data_record.idempotency_key}") From 887e2e951409a1f2defc50d8d001f4b9f7c9bdbd Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Mon, 15 Jan 2024 13:01:59 +0000 Subject: [PATCH 04/11] Improving code readability --- .../utilities/idempotency/persistence/dynamodb.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py index 49127277579..43cf520a8f8 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py @@ -222,6 +222,15 @@ def _put_record(self, data_record: DataRecord) -> None: condition_expression = ( f"{idempotency_key_not_exist} OR {idempotency_expiry_expired} OR ({inprogress_expiry_expired})" ) + + # Use DynamoDB's ReturnValuesOnConditionCheckFailure to optimize put and get operations and optimize costs. + # This feature is supported in boto3 versions 1.26.164 and later. + support_return_on_check_failure = ( + {"ReturnValuesOnConditionCheckFailure": "ALL_OLD"} + if self.boto3_supports_condition_check_failure(boto3.__version__) + else {} + ) + self.client.put_item( TableName=self.table_name, Item=item, @@ -237,11 +246,7 @@ def _put_record(self, data_record: DataRecord) -> None: ":now_in_millis": {"N": str(int(now.timestamp() * 1000))}, ":inprogress": {"S": STATUS_CONSTANTS["INPROGRESS"]}, }, - **( - {"ReturnValuesOnConditionCheckFailure": "ALL_OLD"} # type: ignore - if self.boto3_supports_condition_check_failure(boto3.__version__) - else {} - ), + **support_return_on_check_failure, # type: ignore ) except ClientError as exc: error_code = exc.response.get("Error", {}).get("Code") From 88ed83cdb04ed134ab26192f5a2a60438fd92e3a Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Mon, 15 Jan 2024 13:06:57 +0000 Subject: [PATCH 05/11] Reverting function --- tests/functional/idempotency/conftest.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/functional/idempotency/conftest.py b/tests/functional/idempotency/conftest.py index 845f20ef082..f8d48cd7da2 100644 --- a/tests/functional/idempotency/conftest.py +++ b/tests/functional/idempotency/conftest.py @@ -1,5 +1,4 @@ import datetime -import hashlib import json from decimal import Decimal from unittest import mock @@ -10,7 +9,6 @@ from botocore.config import Config from jmespath import functions -from aws_lambda_powertools.shared.json_encoder import Encoder from aws_lambda_powertools.utilities.idempotency import DynamoDBPersistenceLayer from aws_lambda_powertools.utilities.idempotency.idempotency import IdempotencyConfig from aws_lambda_powertools.utilities.jmespath_utils import extract_data_from_envelope @@ -210,9 +208,7 @@ def hashed_idempotency_key_with_envelope(request, lambda_apigw_event): @pytest.fixture def hashed_validation_key(lambda_apigw_event): - return hashlib.md5( - json.dumps(lambda_apigw_event["requestContext"], cls=Encoder, sort_keys=True).encode(), - ).hexdigest() + return hash_idempotency_key(lambda_apigw_event["requestContext"]) @pytest.fixture From 7cb1b2cc981fdcaf723d1f1fb942024bd0c14791 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Mon, 15 Jan 2024 17:12:27 +0000 Subject: [PATCH 06/11] Adding comments about some logic decisions --- .../utilities/idempotency/base.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/aws_lambda_powertools/utilities/idempotency/base.py b/aws_lambda_powertools/utilities/idempotency/base.py index ed9fe4da0eb..771547fe33c 100644 --- a/aws_lambda_powertools/utilities/idempotency/base.py +++ b/aws_lambda_powertools/utilities/idempotency/base.py @@ -123,13 +123,14 @@ def _process_idempotency(self): except (IdempotencyKeyError, IdempotencyValidationError): raise except IdempotencyItemAlreadyExistsError as exc: - # We now know the item exists - # Attempt to retrieve the record from the exception where ReturnValuesOnConditionCheckFailure is supported - record = exc.old_data_record - if record is None: - # Perform a GET on the record - record = self._get_idempotency_record() - if record is not None: + # Attempt to retrieve the existing record, either from the exception ReturnValuesOnConditionCheckFailure + # or perform a GET operation if the information is not available. + # We give preference to ReturnValuesOnConditionCheckFailure because it is a faster and more cost-effective + # way of retrieving the existing record after a failed conditional write operation. + record = exc.old_data_record or self._get_idempotency_record() + + # If a record is found, handle it for status + if record: return self._handle_for_status(record) except Exception as exc: raise IdempotencyPersistenceLayerError( From d2798adfbbf6556436698086795eb401f159f7ce Mon Sep 17 00:00:00 2001 From: Dan Straw Date: Tue, 16 Jan 2024 09:03:42 +0000 Subject: [PATCH 07/11] Use DynamoDBPersistenceLayer passed in for test_idempotent_lambda_expired_during_request Co-authored-by: Leandro Damascena Signed-off-by: Dan Straw --- tests/functional/idempotency/test_idempotency.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/idempotency/test_idempotency.py b/tests/functional/idempotency/test_idempotency.py index 7f11230c31d..905248011e6 100644 --- a/tests/functional/idempotency/test_idempotency.py +++ b/tests/functional/idempotency/test_idempotency.py @@ -478,7 +478,7 @@ def test_idempotent_lambda_expired_during_request( stubber.activate() - submethod_mocked = mocker.patch.object(DynamoDBPersistenceLayer, "boto3_supports_condition_check_failure") + submethod_mocked = mocker.patch.object(persistence_store, "boto3_supports_condition_check_failure") submethod_mocked.return_value = False @idempotent(config=idempotency_config, persistence_store=persistence_store) From a9a598cb4fd204d5035bb9bb0c24ebc463811801 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Wed, 17 Jan 2024 14:06:03 +0000 Subject: [PATCH 08/11] Adding docs --- docs/media/idempotency_first_execution.png | Bin 0 -> 95197 bytes docs/media/idempotency_second_execution.png | Bin 0 -> 90457 bytes docs/utilities/idempotency.md | 29 +++++++++++++++++--- 3 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 docs/media/idempotency_first_execution.png create mode 100644 docs/media/idempotency_second_execution.png diff --git a/docs/media/idempotency_first_execution.png b/docs/media/idempotency_first_execution.png new file mode 100644 index 0000000000000000000000000000000000000000..23d185bbf6f3dab97cea2c1b8c60711c2bbdb576 GIT binary patch literal 95197 zcmeFZ2UOF|);Agz5fDVG0)hew5FjX_N%a9jAfcI1giw5d5Fm5}6tFxhy$A^*5UM}| zgeHWJU_nZNAT5AYr7F#W9Yw$Rp7%V@`M&QxXWjRH_pWvCT4!hF|NmuX{xh@pOlJ1% z+4KMT?B@%>Q6wAz2khGi0PN#@06&-ZJwuq9UObPsg(IxY{uaRmaER*+01y}y9)>nI zIpySxId$m8-=6pt=izlJb(kIM@9+900IW4gd%^0{|i;005uMf5dSv|DliSd{_TxrQ?h>4Gf6?Dd=G^z~=Q?nZ z6J;RutEByh4j%f&_J5?=w_ivEb%0A)R-N!x)YzkVR1R$ydXu<#Q0y_Z{++yuX9*Cb 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 A0ssI2 literal 0 HcmV?d00001 diff --git a/docs/media/idempotency_second_execution.png b/docs/media/idempotency_second_execution.png new file mode 100644 index 0000000000000000000000000000000000000000..32ecb13ef0ff68fca43e68c6431239292547f141 GIT binary patch literal 90457 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 y;R1fgLXt1K0pdufr%ScXxZ2Me-i*421`@` literal 0 HcmV?d00001 diff --git a/docs/utilities/idempotency.md b/docs/utilities/idempotency.md index 7de0d576ce5..edd0bfb16a1 100644 --- a/docs/utilities/idempotency.md +++ b/docs/utilities/idempotency.md @@ -103,10 +103,13 @@ If you're not [changing the default configuration for the DynamoDB persistence l Larger items cannot be written to DynamoDB and will cause exceptions. If your response exceeds 400kb, consider using Redis as your persistence layer. ???+ info "Info: DynamoDB" - Each function invocation will generally make 2 requests to DynamoDB. If the - result returned by your Lambda is less than 1kb, you can expect 2 WCUs per invocation. - Review the [DynamoDB pricing documentation](https://aws.amazon.com/dynamodb/pricing/){target="_blank"} to - estimate the cost. + + During the first invocation with a payload, the Lambda function executes both a `PutItem` and an `UpdateItem` operations to store the data in DynamoDB. If the result returned by your Lambda is less than 1kb, you can expect 2 WCUs per Lambda invocation. + + On subsequent invocations with the same payload, you can expect just 1 `PutItem` request to DynamoDB. + + + **Note:** While we try to minimize requests to DynamoDB to 1 per invocation, if your boto3 version is lower than `1.26.194`, you may experience 2 requests in every invocation. Ensure to check your boto3 version and review the [DynamoDB pricing documentation](https://aws.amazon.com/dynamodb/pricing/){target="_blank"} to estimate the cost. ### Idempotent decorator @@ -936,6 +939,24 @@ The idempotency utility can be used with the `validator` decorator. Ensure that ???+ tip "Tip: JMESPath Powertools for AWS Lambda (Python) functions are also available" Built-in functions known in the validation utility like `powertools_json`, `powertools_base64`, `powertools_base64_gzip` are also available to use in this utility. +### Tracer + +The idempotency utility can be used with the `tracer` decorator. Ensure that idempotency is the innermost decorator. + +#### First execution + +During the first execution with a payload, Lambda performs a `PutItem` followed by an `UpdateItem` operation to persist the record in DynamoDB. + +![Tracer showcase](../media/idempotency_first_execution.png) + +#### Second execution + +In the second execution with the same payload, Lambda optimistically attempts to save the record to DynamoDB. If the record already exists, DynamoDB returns the item. + +Explore how to handle conditional write errors in high-concurrency scenarios with DynamoDB in this [blog post](https://aws.amazon.com/pt/blogs/database/handle-conditional-write-errors-in-high-concurrency-scenarios-with-amazon-dynamodb/){target="_blank"}. + +![Tracer showcase](../media/idempotency_second_execution.png) + ## Testing your code The idempotency utility provides several routes to test your code. From 296e9eea4c43bb4f065da5f60715344e1a190118 Mon Sep 17 00:00:00 2001 From: Cavalcante Damascena Date: Wed, 17 Jan 2024 15:31:00 +0000 Subject: [PATCH 09/11] wording --- docs/utilities/idempotency.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/utilities/idempotency.md b/docs/utilities/idempotency.md index edd0bfb16a1..c7859862e62 100644 --- a/docs/utilities/idempotency.md +++ b/docs/utilities/idempotency.md @@ -949,9 +949,9 @@ During the first execution with a payload, Lambda performs a `PutItem` followed ![Tracer showcase](../media/idempotency_first_execution.png) -#### Second execution +#### Subsequent executions -In the second execution with the same payload, Lambda optimistically attempts to save the record to DynamoDB. If the record already exists, DynamoDB returns the item. +On subsequent executions with the same payload, Lambda optimistically tries to save the record in DynamoDB. If the record already exists, DynamoDB returns the item. Explore how to handle conditional write errors in high-concurrency scenarios with DynamoDB in this [blog post](https://aws.amazon.com/pt/blogs/database/handle-conditional-write-errors-in-high-concurrency-scenarios-with-amazon-dynamodb/){target="_blank"}. From 488fc01bd92ca5868e74ca6bfb2240090fefbc2a Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Thu, 18 Jan 2024 19:01:05 +0000 Subject: [PATCH 10/11] Adressing Ruben's feedback --- .../idempotency/persistence/dynamodb.py | 18 +++++++++--------- docs/utilities/idempotency.md | 3 ++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py index 43cf520a8f8..696c19fb905 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py @@ -115,6 +115,14 @@ def __init__( self.data_attr = data_attr self.validation_key_attr = validation_key_attr + # Use DynamoDB's ReturnValuesOnConditionCheckFailure to optimize put and get operations and optimize costs. + # This feature is supported in boto3 versions 1.26.164 and later. + self.support_return_on_check_failure = ( + {"ReturnValuesOnConditionCheckFailure": "ALL_OLD"} + if self.boto3_supports_condition_check_failure(boto3.__version__) + else {} + ) + self._deserializer = TypeDeserializer() super(DynamoDBPersistenceLayer, self).__init__() @@ -223,14 +231,6 @@ def _put_record(self, data_record: DataRecord) -> None: f"{idempotency_key_not_exist} OR {idempotency_expiry_expired} OR ({inprogress_expiry_expired})" ) - # Use DynamoDB's ReturnValuesOnConditionCheckFailure to optimize put and get operations and optimize costs. - # This feature is supported in boto3 versions 1.26.164 and later. - support_return_on_check_failure = ( - {"ReturnValuesOnConditionCheckFailure": "ALL_OLD"} - if self.boto3_supports_condition_check_failure(boto3.__version__) - else {} - ) - self.client.put_item( TableName=self.table_name, Item=item, @@ -246,7 +246,7 @@ def _put_record(self, data_record: DataRecord) -> None: ":now_in_millis": {"N": str(int(now.timestamp() * 1000))}, ":inprogress": {"S": STATUS_CONSTANTS["INPROGRESS"]}, }, - **support_return_on_check_failure, # type: ignore + **self.support_return_on_check_failure, # type: ignore ) except ClientError as exc: error_code = exc.response.get("Error", {}).get("Code") diff --git a/docs/utilities/idempotency.md b/docs/utilities/idempotency.md index c7859862e62..bc355580935 100644 --- a/docs/utilities/idempotency.md +++ b/docs/utilities/idempotency.md @@ -102,15 +102,16 @@ If you're not [changing the default configuration for the DynamoDB persistence l Larger items cannot be written to DynamoDB and will cause exceptions. If your response exceeds 400kb, consider using Redis as your persistence layer. + ???+ info "Info: DynamoDB" During the first invocation with a payload, the Lambda function executes both a `PutItem` and an `UpdateItem` operations to store the data in DynamoDB. If the result returned by your Lambda is less than 1kb, you can expect 2 WCUs per Lambda invocation. On subsequent invocations with the same payload, you can expect just 1 `PutItem` request to DynamoDB. - **Note:** While we try to minimize requests to DynamoDB to 1 per invocation, if your boto3 version is lower than `1.26.194`, you may experience 2 requests in every invocation. Ensure to check your boto3 version and review the [DynamoDB pricing documentation](https://aws.amazon.com/dynamodb/pricing/){target="_blank"} to estimate the cost. + ### Idempotent decorator You can quickly start by initializing the `DynamoDBPersistenceLayer` class and using it with the `idempotent` decorator on your lambda handler. From 85b829c26d0c5d95c7767b4dca756df64d52e370 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Fri, 19 Jan 2024 09:20:45 +0000 Subject: [PATCH 11/11] Adressing Ruben's feedback --- .../utilities/idempotency/persistence/dynamodb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py index 696c19fb905..6cb86121092 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py @@ -117,7 +117,7 @@ def __init__( # Use DynamoDB's ReturnValuesOnConditionCheckFailure to optimize put and get operations and optimize costs. # This feature is supported in boto3 versions 1.26.164 and later. - self.support_return_on_check_failure = ( + self.return_value_on_condition = ( {"ReturnValuesOnConditionCheckFailure": "ALL_OLD"} if self.boto3_supports_condition_check_failure(boto3.__version__) else {} @@ -246,7 +246,7 @@ def _put_record(self, data_record: DataRecord) -> None: ":now_in_millis": {"N": str(int(now.timestamp() * 1000))}, ":inprogress": {"S": STATUS_CONSTANTS["INPROGRESS"]}, }, - **self.support_return_on_check_failure, # type: ignore + **self.return_value_on_condition, # type: ignore ) except ClientError as exc: error_code = exc.response.get("Error", {}).get("Code")