Lambda の再帰ループ検出されないパターンを試してみた
Lambda 再帰ループ検出を使用した無限ループの防止 - AWS Lambda
Amazon DynamoDB などの別の AWS のサービス がループの一部を形成してる場合、現時点では Lambda はそのループを検出して停止することはできません。
現時点では、Lambda は Amazon SQS、Amazon S3、および Amazon SNS に関連する再帰ループのみを検出するため、他の AWS のサービス が関与するループによって Lambda 関数が意図しない形で使用される可能性があります。
本ブログ執筆時点では上記のサポート状況であるため、サポートされていないサービスがループに含まれている場合には再帰ループは検出されません。
今回は以下の構成で再帰ループが検出されないことを確認してみました。
Starting a Step Functions workflow in response to events - AWS Step Functions
Lambda
以下のコードで S3 にテキストファイルをアップロードします。
なお、test.txt は index.js と同じディレクトリに作成済みです。
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3");
const fs = require("fs").promises;
const path = require("path");
const s3 = new S3Client({ region: REGION });
exports.handler = async function (event) {
try {
const filePath = path.join(__dirname, "test.txt");
const fileContent = await fs.readFile(filePath);
const uploadParams = {
Bucket: my-bucket-name,
Key: "test.txt",
Body: fileContent,
ContentType: "text/plain"
};
await s3.send(new PutObjectCommand(uploadParams));
console.log("File uploaded successfully.");
return {
statusCode: 200,
body: JSON.stringify({ message: "File uploaded successfully." })
};
} catch (error) {
console.error("Error uploading file:", error);
return {
statusCode: 500,
body: JSON.stringify({ error: "Failed to upload file." })
};
}
};
Step Functions
以下の定義で作成しました。
上記 Lambda を呼び出すだけです。
{
"Comment": "A description of my state machine",
"StartAt": "Lambda Invoke",
"States": {
"Lambda Invoke": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Output": "{% $states.result.Payload %}",
"Arguments": {
"FunctionName": "arn:aws:lambda:ap-northeast-1:012345678901:function:test:$LATEST",
"Payload": "{% $states.input %}"
},
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2,
"JitterStrategy": "FULL"
}
],
"End": true
}
},
"QueryLanguage": "JSONata"
}
EventBridge ルール
以下のイベントパターンを定義しました。
{
"source": ["aws.s3"],
"detail-type": ["Object Created"],
"detail": {
"bucket": {
"name": ["my-bucket-name"]
}
}
}
ターゲットは上記 Step Functions ステートマシンです。
S3 バケット
Amazon EventBridge を有効にします - Amazon Simple Storage Service
EventBridge への通知の送信を許可します。
動作確認
Lambda 再帰ループ検出を使用した無限ループの防止 - AWS Lambda
同じリクエストチェーンで関数が 16 回ほど呼び出された場合、Lambda はそのリクエストチェーン内の次の関数呼び出しを自動的に停止し、ユーザーに通知します。
Lambda の再帰ループ検出が機能した場合には 16 回ほどで呼び出しが停止されます。
Lambda をテスト実行後、Step Functions ステートマシンの実行履歴は 1 ~ 2 秒間隔で増えていきましたが 101 回連続で記録されていたため、再帰ループ検出は機能しませんでした。
以上より、冒頭のドキュメントの記載通り「他の AWS のサービス が関与するループ」は検出されないことを確認できました。
まとめ
今回は Lambda の再帰ループ検出されないパターンを試してみました。
どなたかの参考になれば幸いです。
Discussion