-
Notifications
You must be signed in to change notification settings - Fork 128
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
Bug: idempotency dynamoDB cache doesn't read correct value #2517
Comments
Thanks for opening your first issue here! We'll come back to you as soon as we can. |
Hi @mrerichoffman - thank you for opening the issue & providing the example. I'm going to try to reproduce the issue on my end and will be back to you! |
Hi, I have been looking at reproducing this and I was not able to do so. Running your exact code on a function backed by a DynamoDB table using composite primary key I was able to execute the function more than once using the same payload and observe that subsequent requests are being considered idempotent (see screenshot below): In the sentence above I specifically called out that the DynamoDB table uses composite primary key, meaning the configuration provided to the This is a non standard setup, and if you have deployed a Table using the configuration suggested in our docs, then the key schema would be with a partition key named With this in mind, is there any other info that you think could be relevant in helping me reproduce the error consistently? Alternatively, I also want to call out that this error is expected when two concurrent identical in-flight requests are being handled. As the error states, if a request arrives while a previously received identical one is still in progress, any subsequent one is rejected. This flow is detailed in this diagram in the docs and is also explained here. If your first request failed to process and the idempotency record remained in an "in progress" state, subsequent requests made within what we call "in progress expiration" time are also rejected. This time is set to the remaining time in milliseconds before the invocation will timeout. In other words, if a request starts being processed while the function has 100 seconds remaining, the corresponding idempotency record will be placed as "in progress" with an This locking mechanism is necessary due to the distributed nature of Lambda, since subsequent identical requests have no way of knowing whether the first original request is still being processed (i.e. long running process) or has failed/timed out. After that After that, if a new identical request comes it will be accepted and processed accordingly. |
Sorry, I must have tested the provided sample code before I ripped out additional code to simplify testing. As it turns out the bug is reproducable when getDefaultIdempotencyConfigs is externalized into a separate npm package which is bundled to commonjs. To fix I removed the idempotency utility from the npm package and exported json configurations instead. |
Thanks for letting me know. Just to make sure I understand, could you share an example of how to reproduce the issue? I'd like to see if there's anything that we can either improve in the code or docs to avoid others experiencing the same problem. Thanks! |
Sure, I externalized the idempotency configs into an example npm package that can be installed from the attached tarball. Updated lambda handler: import { makeHandlerIdempotent } from "@aws-lambda-powertools/idempotency/middleware";
import middy from "@middy/core";
import { getDefaultIdempotencyConfigs } from "example-config-package";
export interface ProcessResult {
processResult: "processed" | "rejected";
}
const { persistenceStore, idempotencyConfig } = getDefaultIdempotencyConfigs();
const lambdaHandler = async (event: Record<"string", unknown>): Promise<ProcessResult> => {
console.info(`event`, { event });
const processResult: ProcessResult = {
processResult: "processed"
};
return processResult;
};
export const testingPowertool = middy(lambdaHandler).use(
makeHandlerIdempotent({
persistenceStore,
config: idempotencyConfig
})
); npm package example-config-package referenced in import { IdempotencyConfig } from "@aws-lambda-powertools/idempotency";
import { DynamoDBPersistenceLayer } from "@aws-lambda-powertools/idempotency/dynamodb";
export const getDefaultIdempotencyConfigs = (eventKeyJmesPath = '["correlationId"]') => {
const persistenceStore = new DynamoDBPersistenceLayer({
tableName: process.env.IDEMPOTENCY_TABLE_NAME || "IdempotencyTable",
sortKeyAttr: "sortKey"
});
const idempotencyConfig = new IdempotencyConfig({
throwOnNoIdempotencyKey: true,
eventKeyJmesPath
});
return {
persistenceStore,
idempotencyConfig
};
}; Place the tgz packed library in the root of the project. Reference the tzg file in package.json dependencies like this - |
Hi, I have been looking into this and I am able to reproduce the issue when I use the tarball you provided but not when I bundle/build the same utility on my end. When deploying my function using your Despite this, I haven't been able to pinpoint the issue yet and due to the fact that it appears only under these specific conditions I am not sure how to troubleshoot it properly. I'll still give it a try and get back to you. |
Expected Behavior
When using the Idempotency utility with ddb persistence, the utility should return the result of a previous operation from cache provided that the request is handled by the same execution environment.
Current Behavior
When using ddb persistence the utility doesn't return the correct value from the cache, but instead causes a runtime error. If I revert from v2.1.0 to v1.17.0 the bug goes away.
Code snippet
Steps to Reproduce
Then run the function with the same event payload, { "correlationId": "abc-123-def-456" }, twice and observe the error (shown below) being thrown at the second execution.
Possible Solution
No response
Powertools for AWS Lambda (TypeScript) version
latest
AWS Lambda function runtime
20.x
Packaging format used
npm
Execution logs
The text was updated successfully, but these errors were encountered: