Lambdaの無限ループ

例えばS3バケットにLambda呼び出しを設定して、以下のようなLambda関数を設定すると、

var aws = require('aws-sdk');
exports.aws=aws;

exports.handler = function(event, context) {
   var bucket = event.Records[0].s3.bucket.name;
   var key = event.Records[0].s3.object.key;
   var region = event.Records[0].awsRegion;
   var s3 = new aws.S3({params: {Bucket: bucket, Key: key}});
   s3.putObject({Body: 'Loop!'}, function(err) {
	   if(err){
		   context.done("ERROR",err);
	   }else{
		   context.done(null, 'Loop-'+new Date());
	   }
   });
};

Lambda関数がputしたイベントで再度Lambda関数が呼ばれるので、S3とLambda関数を行ったり来たりしてループが終わらなくなります。


止めるには関数自体を書き換えてputObjectしなくしたり、あとは例えば特定のファイルが入っていた場合はputObjectしないなどのコードを入れておけば良いですが、このループを利用して何か出来ないか考えてみました。

ヘルスチェック

例えば呼び出されたLambda関数から、指定のEC2にアクセスして、返事がなければAPIを使ってEC2をリブートする。もしくはEC2のstatus check failをSQSに入れておき、LambdaからSQSをチェックしてキューに入っていれば対象インスタンスをリブートする。AutoScalingを使ったオートヒーリングはインスタンスが新しく作られてしまいますが、これなら同一インスタンスを起動出来ます。

SQSのワーカー

例えばLambda関数で30秒ぐらいのsetTimeoutをすれば、おおよそ30-40秒間隔でLambdaが呼び出されるので、指定時間を過ぎたら何らかの処理をする。(というかSQSからLambdaが呼び出せればいいんですけどね)

Webクローラー

LambdaでHTMLをパースして、取り出したURLをS3バケットに入れる。そこから呼び出されたLambdaでそのURLのコンテンツを取りに行く。ループさせながら、クローリングするようなものが作れそうです。


今はまだLambda呼び出しはS3のObject作成、Dynamo Stream、KinesisとREST呼び出ししかないですが、SNSやSWF、SQSからも呼び出せるようになればもっと活用範囲は広がりそうですね。