Replies: 7 comments
-
Thanks for opening your first issue here! We'll come back to you as soon as we can. |
Beta Was this translation helpful? Give feedback.
-
If you wrap any function with the The idempotency of the specific operations contained within the function (like updating a counter) should not be relevant here. Take the below example: @idempotent_function(data_keyword_argument="data", config=config, persistence_store=dynamodb)
def dummy(arg_one, arg_two, data: dict, **kwargs):
# make an "unsafe" update to dynamodb counter
get_counter_value_from_dynamodb(Key=data)
increment_counter_value()
set_counter_to_new_value_in_dynamodb(Key=data)
#############################################
return {"data": counter} In this case, the idempotent utility will not allow any of the code in this function to be called more than once within the idempotent expiry period. If you call the function a second (and third, fourth, and so on...) time after the first execution has completed, the idempotency util will deliver the same response as the first execution, without running the function code again. Assuming there's a separate counter for each Disclaimer: the example is very much a contrived one, there are better ways to do this with DynamoDB alone that don't require the idempotent utility. Does that answer your question? |
Beta Was this translation helpful? Give feedback.
-
Thank you for your answer @cakepietoast!
It seems that powertool only considers the retry happening after a function has completed. I am wondering what will happen if the function fails after |
Beta Was this translation helpful? Give feedback.
-
This is correct, though you do have control over this as a user of the library. If you don't want the function to be retried in its entirety, you can catch any exceptions and return a valid response from your Lambda function instead of allowing the Exception to bubble up. Example: @idempotent_function(data_keyword_argument="data", config=config, persistence_store=dynamodb)
def dummy(arg_one, arg_two, data: dict, **kwargs):
# make an "unsafe" update to dynamodb counter
get_counter_value_from_dynamodb(Key=data)
increment_counter_value()
set_counter_to_new_value_in_dynamodb(Key=data)
try:
some_other_call_that_raises_an_exception()
except Exception as err:
logger.error(err)
return {"data": None, "error": str(err)}
return {"data": counter} This is mentioned in the handling exceptions section of the docs. Having said that, it is a good idea to make your idempotent functions as small as you possibly can, with any code that doesn't need to be executed as idempotent outside the function. To continue with my (increasingly contrived) example from above: def lambda_handler(event, context):
do_some_stuff()
result = dummy("one", "two", {"foo": "bar", "baz": "qux"})
some_other_call_that_raises_an_exception()
@idempotent_function(data_keyword_argument="data", config=config, persistence_store=dynamodb)
def dummy(arg_one, arg_two, data: dict, **kwargs):
# make an "unsafe" update to dynamodb counter
get_counter_value_from_dynamodb(Key=data["foo"])
increment_counter_value()
set_counter_to_new_value_in_dynamodb(Key=data["foo"])
return {"data": counter} In this case, the code that can cause an exception - but is unrelated to the code that needs to be idempotent - is outside of the idempotent function. Now, when an exception is raised, it will be outside of the context of the function and not cause the record to be deleted. I can see that the exception handling part of the document needs updating to reflect this. It was written before we implemented the |
Beta Was this translation helpful? Give feedback.
-
Thank you for your detailed explanation @cakepietoast !
For example, when the machine running the function crashes after executing I am wondering how the powertool addresses this kind of failure. |
Beta Was this translation helpful? Give feedback.
-
It is important to remember that Powertools is "just" a library that executes within the scope of your Lambda Function. It "wraps" your decorated python function, injecting its idempotency logic before and after your decorated python function is executed. In the case of underlying hardware failure during execution of your decorated python function, no more code execution can happen - including any Powertools/idempotency logic. Specifically in the scenario you describe, when your python function is executed, the following will happen:
As a side note: you can replace step 3. above with "the Lambda Function times out" as the behaviour there is the same. |
Beta Was this translation helpful? Give feedback.
-
Ok, I see. Thank you very much! |
Beta Was this translation helpful? Give feedback.
-
When reading the document about idempotency, I am wondering whether the powertool can convert all functions to be idempotent.
For example, if a function tries to increase the value of a variable in DynamoDB or other databases, I think it cannot be idempotent unless writing the functional return value and increasing the variable are completed atomically.
I suggest that the document should describe which kinds of functions can achieve the idempotence via powertools in detail.
Please let me know if my understanding is correct.
Beta Was this translation helpful? Give feedback.
All reactions