AWS Lambdaで1分以上かかる処理をする

AWS Lambda、便利ですね。
サーバーレスでプログラムを実行できるのが魅力的なのですが、
実行時間が1分に制限される等、いくつかの制約で採用を見送る事もあるかと思います。

1分以上かかる処理はEC2等で実行しましょう、という事なのでしょうが、
どうしてもAWS Lambdaで処理させたい、というシチュエーションもあるかと思いますので、その制限を回避する方法を調査しました。

再帰呼び出しする

AWS Lambdaを起動するAPIが提供されているので、
LambdaスクリプトからLambdaを呼び出し、処理を引き継ぐことで、1分以上の処理を行うことができます。

var aws = require('aws-sdk')

exports.handler = function(event, context) {
  var count = event.count || 0
  count += 1
  console.log("count:" + count)
  
  // count が3を越えたら終了。
  if (3 < count) {
    console.log("count end.")
    context.succeed()
  } else {
    var lambda = new aws.Lambda()
    var params = {
      FunctionName: "recall",
      InvokeArgs: '{ "count": '+count+'}'
    }
    // countをパラメータに引き渡して自分自身のLambdaを再帰呼び出し。
    lambda.invokeAsync(params, function(err, data) {
      if (err) {
        console.log("error!")
        console.log(err)
      } else {
        console.log("next count:" + (count + 1))
      }
      context.succeed();
    })
  }
};

当然ながら、再帰実行する場合は、きちんと終了するフラグを立てるように実装しないと無限に再帰実行されます。
課金が発生するので、もしこの再帰Lambdaを実装する場合は慎重にテストしてください。
もし無限呼び出しが発生したら、Lambda関数の登録を削除する事で強制停止することは可能です。

また、Lambdaを実行するIAM Roleにlambda関係の権限を付与しておいてください。
(自動で作成されるlambda_basic_executionにはついていません。)

制約は多いものの、非常に安価にサーバーレスプログラムを実行することができるので、是非使っていきたいですね。