はじめに
AWS を触り始めたばかりの頃にやらかした初歩的なミスをまとめたアドベントカレンダー、題して「AWS初歩ミス図鑑」の 12 日目です。
今回は 考慮不足で Lambda が無限に実行されてしまった話 を書いていきます。
やっていたこと
AWS を使って勉強がてら何か作りたいなあと考えていたある日、Slack のメッセージを Lambda で分析し、自動で応答する Bot を作ってみようと思い立ちました。「こんにちは!」と投稿したら「こんにちは!今日も一日頑張りましょう!」みたいなメッセージを返してくれるようなものです。
Lambda 関数は Slack と連携し、投稿されたメッセージの内容を分析して特定の単語が含まれていたら応答を作成、それを Slack へ投稿するという処理になっています。
今回は完全に趣味の開発でしたが、弊社では学習目的での検証環境利用が許可されていたので、業務の空いた時間にのんびりと実装を進めていました。
そうしてようやく Lambda と Slack の連携が完了し、ためしにメッセージを送ってみようかな…と考えたところで、先輩社員からお昼に誘っていただいたため、作業を中断して離席しました。ただしくは、中断したと思っていました。
結果
お昼休みを終えて席へ戻ると、Slack の通知が大変なことになっていました。何事だろうと詳細を確認してみると、Lambda と連携していたチャンネルに無限とも思えるメッセージが投稿され続けています。
離席をする前、私は作業を中止したと思い込んでいたのですが、実際には Lambda のテストイベントを一度実行して、その処理がまだ終わっていなかったことを忘れて しまっていました。
テストイベントには Lambda が処理をしてくれるようにトリガーとなる単語が含まれており、発火させると Slack にメッセージを投稿するようになっています。しかしながら、Lambda の応答に対する処理をまったく考慮していなかったため、処理をした結果のメッセージにも Lambda の関数が適応され、さらにそのメッセージにも……と、関数が無限ループをしていたのです。
つまり、
- テストイベントから飛んだ「こんにちは」という文章が Lambda に処理をされ「こんにちは!今日も一日頑張りましょう!」というような文章が Slack へ投稿される
- Slack へ投稿された「こんにちは!今日も一日頑張りましょう!」の「こんにちは」に反応し、Lambda 関数が処理を始める
- 上記の処理により再び「こんにちは!今日も一日頑張りましょう!」という文章が Slack へ投稿される
- Slack へ投稿された「こんにちは!今日も一日頑張りましょう!」の「こんにちは」に反応し、Lambda 関数が処理を始める
- そして無限ループへ……
こういうことです。
何を考えていたのか
Bot 自身の投稿を除外する処理を入れる必要があるということを考慮できていませんでした。 あとから考えたらそらそうやろ…という感じなのですが、作っている当時は本当に気が付きませんでした。
この時は即座に Lambda を停止し、関数へ Bot 投稿に対する処理を追加することで解決をすることができました。幸い無限ループに陥っていた時間も短かったため、請求額もそこまで膨大にはなりませんでしたが、もっと大掛かりなアプリを作って同じことをしていたらと思うと、体温が一気に下がる思いです。
まとめ
Bot を作成するときは、Bot の投稿に関する処理を必ず記載するようにしましょう。そもそもテスト中はうかつに離席しないということも大切です。私のように……。
また、当時はありませんでしたが、現在は 再帰ループ検出 という機能があるので、この記事のようなことは早々起こらないんじゃないかな、と思っております。(特定のリソースに限りますが…)