def _handle_for_status(self, event_record: DataRecord) -> Optional[Dict[Any, Any]]: """ Take appropriate action based on event_record's status Parameters ---------- event_record: DataRecord Returns ------- Optional[Dict[Any, Any] Lambda response previously used for this idempotency key, if it has successfully executed already. Raises ------ AlreadyInProgressError A lambda execution is already in progress IdempotencyInconsistentStateError The persistence store reports inconsistent states across different requests. Retryable. """ # This code path will only be triggered if the record becomes expired between the save_inprogress call and here if event_record.status == STATUS_CONSTANTS["EXPIRED"]: raise IdempotencyInconsistentStateError("save_inprogress and get_record return inconsistent results.") if event_record.status == STATUS_CONSTANTS["INPROGRESS"]: raise IdempotencyAlreadyInProgressError( f"Execution already in progress with idempotency key: " f"{self.persistence_store.event_key_jmespath}={event_record.idempotency_key}" ) return event_record.response_json_as_dict()
def test_in_progress_never_saved_to_cache( idempotency_config: IdempotencyConfig, persistence_store: DynamoDBPersistenceLayer): # GIVEN a data record with status "INPROGRESS" # and persistence_store has use_local_cache = True persistence_store.configure(idempotency_config) data_record = DataRecord("key", status="INPROGRESS") # WHEN saving to local cache persistence_store._save_to_cache(data_record) # THEN don't save to local cache assert persistence_store._cache.get("key") is None
def test_user_local_disabled(idempotency_config: IdempotencyConfig, persistence_store: DynamoDBPersistenceLayer): # GIVEN a persistence_store with use_local_cache = False persistence_store.configure(idempotency_config) # WHEN calling any local cache options data_record = DataRecord("key", status="COMPLETED") try: persistence_store._save_to_cache(data_record) cache_value = persistence_store._retrieve_from_cache("key") assert cache_value is None persistence_store._delete_from_cache("key") except AttributeError as e: pytest.fail(f"AttributeError should not be raised: {e}") # THEN raise AttributeError # AND don't have a _cache attribute assert not hasattr("persistence_store", "_cache")
def _item_to_data_record(self, item: Dict[str, Any]) -> DataRecord: """ Translate raw item records from DynamoDB to DataRecord Parameters ---------- item: Dict[str, Union[str, int]] Item format from dynamodb response Returns ------- DataRecord representation of item """ return DataRecord( idempotency_key=item[self.key_attr], status=item[self.status_attr], expiry_timestamp=item[self.expiry_attr], response_data=item.get(self.data_attr), payload_hash=item.get(self.validation_key_attr), )
def test_data_record_invalid_status_value(): data_record = DataRecord("key", status="UNSUPPORTED_STATUS") with pytest.raises(IdempotencyInvalidStatusError) as e: _ = data_record.status assert e.value.args[0] == "UNSUPPORTED_STATUS"