質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

2回答

6050閲覧

Lambdaから別のLambdaを呼び出した時、2回同時に実行される。

yuki_90453

総合スコア326

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

1クリップ

投稿2021/10/30 06:50

編集2021/10/30 08:03

#概要
下記のように、Lambdaから別のLambda関数へ呼び出しを行っています。
呼び出し元のLambda関数Aとして、呼び出した関数をLambda関数Bとします。
Lambda関数Bが2回、ほぼ同時に実行されてしまい困っています。
#サンプル
下記が呼び出し元であるLambda関数Aです。

const invoke_AutoOrder_ = async(orderID:number):Promise<string> =>{ console.log('invoke_AutoOrderが実行されます。2回実行されていないか確認して下さい。') const lambda = new Lambda({apiVersion:'2015-03-31'}) const param:Lambda.InvocationRequest = { FunctionName: "sam-HOFGE", InvocationType:"RequestResponse", Payload: JSON.stringify({ orderID: orderID }) } return await lambda.invoke(param).promise() .then((res)=>{ const pl = res.Payload as string return `処理が完了しました#${pl}` }) .catch((error)=>{ // これは実行されない return JSON.stringify(error) });

#問題点
Lambda関数Bが2回、ほぼ同時に実行されてしまい困っています。
Lambda関数Aは、上記のCosnole.logで実行された回数を確認したところ、1度しか実行されていませんでした。
しかし、Lambda関数BのCloudwatch Logsには、2つのRequestIDが確認できます。
そのため、やはりLambda関数Bが2回実行されたのが確認できます。

また2回実行されたうち、1回目は問題なく処理が完了していますが、2回目は失敗しています。
そしてLambda関数Aには2回目の失敗した結果が戻っています
この2回の処理は、1回目の処理とほぼ同時か1〜2秒後実行されています。

InvocationTypeは同期で呼び出しているのでRetryされるはずない、そもそも1回目の処理が成功しているのに、なぜRetryするのか意味がわかりません。。。

どなたかアドバイスお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

残念ながら、Lambdaの複数回起動を防ぐ術はないと思って設計したほうがいいです。

Lambda 関数の同時実行数を1にしても冪等性の担保から逃れることは出来ない

この事を考えてもLambdaからLambdaを直接呼び出すのは良くないケースがあります。
Lambdaで依存関係を持つ複数の処理を組合せたいときはStep Functionsが一つの方法になります。
参考
AWS Step Functions をゼロからざっくり理解する

Step Functionsは最近複数のアップデートが入って格段に使いやすくなりました。
[アップデート]Step Functions Workflow Studioがリリースされて、ワークフロー作成が簡単になりました
[アップデート] AWS Step Functionsが200以上のAWSサービスと連携できるようになりました

投稿2021/10/30 11:58

yu_1985

総合スコア7471

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

#結論
InvocationTypeをEventに設定し、呼び出し先であるLambdaでtry-catchで囲んで必ず成功で終わるコードに書き換えました。

#経緯
yu1985さんの仰る通り、InvocationTypeをRequestResponseで設定した場合、2回実行されてしまうようです。
StackOverflowにも同様の質問がありました。

DynamoDBで呼び出したLambdaの実行状態を管理する方法はありましたが、今回は上述の通りInvocationTypeをEventに設定し、呼び出し先であるLambdaでtry-catchで囲んで必ず成功で終わる方法にしました。

呼び出し元

const invoke_AutoOrder_ = async(orderID:number):Promise<string> =>{ console.log('invoke_AutoOrderが実行されます。2回実行されていないか確認して下さい。') const lambda = new Lambda({apiVersion:'2015-03-31'}) const param:Lambda.InvocationRequest = { FunctionName: "sam-HOFGE", InvocationType:"Event", Payload: JSON.stringify({ orderID: orderID }) } return await lambda.invoke(param).promise()

##呼び出し先

export const handler= async(event:EVENT):Promise<any>=>{ try{ // 処理 return }catch(e){ // エラーハンドリング。SlackにログをPOST return } }

#最後
今の所、問題なく1回だけ実行されています。

投稿2021/11/02 01:33

yuki_90453

総合スコア326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問