Skip to content

Feature: Idempotency calculate remaining invocation available time as part of the idempotency record #362

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

Closed
1 of 2 tasks
hjgraca opened this issue Jul 25, 2023 · 0 comments · Fixed by #363
Closed
1 of 2 tasks
Labels
feature-request New or enhancements to existing features

Comments

@hjgraca
Copy link
Contributor

hjgraca commented Jul 25, 2023

Use case

In the current implementation of Idempotency we don't have the InProgressExpiration timestamp. So currently if a lambda invocation expired there would be no way to retry it, when using the Idempotent attribute in the lambda handler or Idempotent attribute on another method

This field is required to prevent against extended failed retries when a Lambda function times out, Powertools for AWS Lambda (.NET) calculates and includes the remaining invocation available time as part of the idempotency record.

If a second invocation happens after this timestamp, and the record is marked as INPROGRESS, we will execute the invocation again as if it was in the EXPIRED state (e.g, expire_seconds field elapsed).

This means that if an invocation expired during execution, it will be quickly executed again on the next retry.

Solution/User Experience

When decorating the handler with Idempotent attribute we will do it automatically by getting the RemainingTime value from the ILambdaContext that is passed to the handler.
RemainingTime is the remaining execution time till the function will be terminated. At the time you create the Lambda function you set maximum time limit, at which time AWS Lambda will terminate the function execution.
Information about the remaining time of function execution can be used to specify function behavior when nearing the timeout.

When using Idempotent attribute on another method to guard isolated parts of your code, you must use RegisterLambdaContext available in the Idempotency static class to benefit from this protection.

Here is an example on how you register the Lambda context in your handler:

public class Function
{
    public Function()
    {
        Idempotency.Configure(builder => builder.UseDynamoDb("idempotency_table"));
    }
    
    public Task<string> FunctionHandler(string input, ILambdaContext context)
    {
        Idempotency.RegisterLambdaContext(context);

        MyInternalMethod("hello", "world")
        return Task.FromResult(input.ToUpper());
    }

    [Idempotent]
    private string MyInternalMethod(string argOne, [IdempotencyKey] string argTwo) {
        return "something";
    }
}

Lambda request timeout diagram

sequenceDiagram
    participant Client
    participant Lambda
    participant Persistence Layer
    alt initial request
        Client->>Lambda: Invoke (event)
        Lambda->>Persistence Layer: Get or set idempotency_key=hash(payload)
        activate Persistence Layer
        Note over Lambda,Persistence Layer: Set record status to INPROGRESS. <br> Prevents concurrent invocations <br> with the same payload
        Lambda-->>Lambda: Call your function
        Note right of Lambda: Time out
        Lambda--xLambda: Time out error
        Lambda-->>Client: Return error response
        deactivate Persistence Layer
    else retry after Lambda timeout elapses
        Client->>Lambda: Invoke (event)
        Lambda->>Persistence Layer: Get or set idempotency_key=hash(payload)
        activate Persistence Layer
        Note over Lambda,Persistence Layer: Set record status to INPROGRESS. <br> Reset in_progress_expiry attribute
        Lambda-->>Lambda: Call your function
        Lambda->>Persistence Layer: Update record with result
        deactivate Persistence Layer
        Persistence Layer-->>Persistence Layer: Update record
        Lambda-->>Client: Response sent to client
    end
Loading

Alternative solutions

No response

Acknowledgment

@hjgraca hjgraca added feature-request New or enhancements to existing features triage Pending triage from maintainers labels Jul 25, 2023
@hjgraca hjgraca moved this to 🏗 In progress in Powertools for AWS Lambda (.NET) Jul 25, 2023
@hjgraca hjgraca removed the triage Pending triage from maintainers label Aug 23, 2023
@github-actions github-actions bot added the pending-release Fix or implementation already in dev waiting to be released label Aug 25, 2023
@hjgraca hjgraca removed the pending-release Fix or implementation already in dev waiting to be released label Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request New or enhancements to existing features
Projects
Status: 🏗 In progress
1 participant