Replies: 1 comment
|
A single synchronous invocation can't send an early "still processing" and then keep working. With the Lambda proxy integration, the response is the handler's return value, and once the handler returns, the invocation is over. When API Gateway gives up at 29 s, it just returns a 504 to the client. The function keeps running until it finishes or hits its own timeout. Idempotency lets you take advantage of that: retries of the same request can get a 1. Return 202 to retries while the first invocation is running When a second request arrives with the same payload before the first one has finished, Powertools raises import json
from aws_lambda_powertools.utilities.idempotency import (
DynamoDBPersistenceLayer,
IdempotencyConfig,
idempotent_function,
)
from aws_lambda_powertools.utilities.idempotency.exceptions import (
IdempotencyAlreadyInProgressError,
)
persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
config = IdempotencyConfig()
@idempotent_function(data_keyword_argument="order", config=config, persistence_store=persistence_layer)
def process_order(order: dict) -> dict:
... # the long-running work
return {"order_id": order["order_id"], "status": "done"}
def lambda_handler(event, context):
# Lets the in-progress lock expire if this invocation times out.
config.register_lambda_context(context)
order = json.loads(event["body"])
try:
result = process_order(order=order)
except IdempotencyAlreadyInProgressError:
# Same payload, first invocation still running.
return {
"statusCode": 202,
"headers": {"Retry-After": "10"},
"body": json.dumps({"status": "processing"}),
}
return {"statusCode": 200, "body": json.dumps(result)}I ran this with Powertools 3.35.0 against a mocked DynamoDB table (moto). The first call worked for 3 s, a second call with the same body 1 s later got Two things to keep in mind:
The limit of this approach is that the first caller still gets the 504. Clients have to treat a 504 on this endpoint as "retry later". 2. If the first response has to arrive before 29 s Then the work can't stay in the synchronous invocation. The options I know of:
I tested option 1 locally only, not behind a real API Gateway. The options in part 2 come from the AWS docs linked above, not from a test. |
Uh oh!
There was an error while loading. Please reload this page.
I have a lambda behind an api gateway, which has an integration request timeout of 29000ms. The lambda uses idempotency so that subsequent requests received the cached response once the request has been processed. The lambda can take more than 29 seconds to complete, so I would like to be able to signal to the client that the request is still being proceessed before the api gateway sends a request timeout error.
All reactions