You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/utilities/idempotency.md
+55-55Lines changed: 55 additions & 55 deletions
Original file line number
Diff line number
Diff line change
@@ -370,12 +370,12 @@ sequenceDiagram
370
370
Lambda->>Persistence Layer: Update record with Lambda handler results
371
371
deactivate Persistence Layer
372
372
Persistence Layer-->>Persistence Layer: Update record with result
373
-
Lambda--xClient: Response not received by client
373
+
Lambda-->>Client: Response sent to client
374
374
else retried request:
375
375
Client->>Lambda: Invoke (event)
376
376
Lambda->>Persistence Layer: Get or set (id=event.search(payload))
377
377
Persistence Layer-->>Lambda: Already exists in persistence layer. Return result
378
-
Lambda-->>Client: Response sent to client
378
+
Lambda-->>Client: Response sent to client
379
379
end
380
380
```
381
381
<i>Idempotent sequence</i>
@@ -386,6 +386,59 @@ The client was successful in receiving the result after the retry. Since the Lam
386
386
???+ note
387
387
Bear in mind that the entire Lambda handler is treated as a single idempotent operation. If your Lambda handler can cause multiple side effects, consider splitting it into separate functions.
Powertools doesn't have the chance to set the idempotency record to `EXPIRED`.
394
+
This means that the record would normally have been locked until `expire_seconds` have
395
+
passsed.
396
+
397
+
However, when Powertools has access to the Lambda invocation context, we are able to calculate the remaining
398
+
available time for the invocation, and save it on the idempotency record. This way, if a second invocation happens
399
+
after this timestamp, and the record is still marked `INPROGRESS`, we execute the inovcation again as if it was
400
+
already expired. This means that if an invocation expired during execution, it will be quickly executed again on the
401
+
next retry.
402
+
403
+
???+ info "Info: Calculating the remaining available time"
404
+
For now this only works with the `idempotent` decorator. At the moment we
405
+
don't have access to the Lambda context when using the
406
+
`idempotent_function` so enabling this option is a no-op in that scenario.
407
+
408
+
<center>
409
+
```mermaid
410
+
sequenceDiagram
411
+
participant Client
412
+
participant Lambda
413
+
participant Persistence Layer
414
+
alt initial request:
415
+
Client->>Lambda: Invoke (event)
416
+
Lambda->>Persistence Layer: Get or set (id=event.search(payload))
417
+
activate Persistence Layer
418
+
Note right of Persistence Layer: Locked during this time. Prevents multiple<br/>Lambda invocations with the same<br/>payload running concurrently.
419
+
Lambda--xLambda: Run Lambda handler (event).<br/>Time out
420
+
Lambda-->>Client: Return error response
421
+
deactivate Persistence Layer
422
+
else retried before the Lambda timeout:
423
+
Client->>Lambda: Invoke (event)
424
+
Lambda->>Persistence Layer: Get or set (id=event.search(payload))
425
+
Persistence Layer-->>Lambda: Already exists in persistence layer. Still in-progress
426
+
Lambda--xClient: Return Invocation Already In Progress error
427
+
else retried after the Lambda timeout:
428
+
Client->>Lambda: Invoke (event)
429
+
Lambda->>Persistence Layer: Get or set (id=event.search(payload))
430
+
activate Persistence Layer
431
+
Note right of Persistence Layer: Locked during this time. Prevents multiple<br/>Lambda invocations with the same<br/>payload running concurrently.
432
+
Lambda-->>Lambda: Run Lambda handler (event)
433
+
Lambda->>Persistence Layer: Update record with Lambda handler results
434
+
deactivate Persistence Layer
435
+
Persistence Layer-->>Persistence Layer: Update record with result
436
+
Lambda-->>Client: Response sent to client
437
+
end
438
+
```
439
+
<i>Idempotent sequence for Lambda timeouts</i>
440
+
</center>
441
+
389
442
### Handling exceptions
390
443
391
444
If you are using the `idempotent` decorator on your Lambda handler, any unhandled exceptions that are raised during the code execution will cause **the record in the persistence layer to be deleted**.
**payload_validation_jmespath**|`""`| JMESPath expression to validate whether certain parameters have changed in the event while the event payload
484
537
**raise_on_no_idempotency_key**|`False`| Raise exception if no idempotency key was found in the request
485
538
**expires_after_seconds**|3600| The number of seconds to wait before a record is expired
486
-
**expires_in_progress**|`False`| Enables expiry of invocations that time out during execution
487
539
**use_local_cache**|`False`| Whether to locally cache idempotency results
488
540
**local_cache_max_items**|256| Max number of items to store in local cache
489
541
**hash_function**|`md5`| Function to use for calculating hashes, as provided by [hashlib](https://docs.python.org/3/library/hashlib.html) in the standard library.
@@ -897,58 +949,6 @@ class DynamoDBPersistenceLayer(BasePersistenceLayer):
897
949
898
950
For example, the `_put_record` method needs to raise an exception if a non-expired record already exists in the data store with a matching key.
899
951
900
-
### Expiring in-progress invocations
901
-
902
-
The default behavior when a Lambda invocation times out isfor the event to stay locked until `expire_seconds` have passed. Powertools
903
-
has no way of knowing if it's safe to retry the operation in this scenario, so we assume the safest approach: to not
904
-
retry the operation.
905
-
906
-
However, certain types of invocation have less strict requirements, and can benefit from faster expiry of invocations. Ideally, we
907
-
can make an in-progress invocation expire as soon as the [Lambda invocation expires](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-verify-invocation-timeouts/).
908
-
909
-
When using this option, powertools will calculate the remaining available time for the invocation, and save it on the idempotency record.
910
-
This way, if a second invocation happens after this timestamp, and the record is stil marked `INPROGRESS`, we execute the invocation again
911
-
asif it was already expired. This means that if an invocation expired during execution, it will be quickly executed again on the nexttry.
912
-
913
-
This setting introduces no change on the regular behavior where if an invocation succeeds, the results are cached for`expire_seconds` seconds.
914
-
915
-
???+ warning "Warning"
916
-
Consider whenever you really want this behavior. Powertools can't make any garantee on which state your application was
917
-
when it time outed. Ensure that your business logic can be retried at any stage.
918
-
919
-
???+ info "Info: Calculating the remaining available time"
920
-
For now this only works with the `idempotent` decorator. At the moment we don't have access to the Lambda context when using
921
-
the `idempotent_function` so enabling this option is a no-op in that scenario.
922
-
923
-
To activate this behaviour, enable the `expires_in_progress` option on the configuration:
924
-
925
-
==="app.py"
926
-
927
-
```python hl_lines="8"
928
-
from aws_lambda_powertools.utilities.idempotency import (
0 commit comments