はじめに
Go AWS lambdaでRDSに接続する処理を書く必要が出てきた際
connectionを作るのは init()
で良いのですが果たして close
をいつどこで行えば良いのか悩み、公式のリファレンスを参照しましたが肝心のライフサイクルについて具体的な記載が見当たらないため、実際に各func内の実行回数のcountを取って調査しました。
検証
init()
main()
Handler()
それぞれの実行countをグローバルに保持しその値を出力する検証コードを作成して実行してみます。
package main
import (
"fmt"
"github.com/aws/aws-lambda-go/lambda"
"log"
)
var invokeCount = 0
var initCount = 0
var mainCount = 0
func init() {
log.Print("init start")
initCount++
log.Print("init end")
}
func Handler() (string, error) {
log.Print("handler start")
invokeCount++
log.Printf("invoke=%d, main=%d, init=%d", invokeCount, mainCount, initCount)
log.Print("handler end")
return fmt.Sprintf("invoke=%d, main=%d, init=%d", invokeCount, mainCount, initCount), nil
}
func main() {
log.Print("main start")
mainCount++
lambda.Start(Handler)
log.Print("main end")
}
実行結果は以下の通り
[1st request]
2020/01/15 06:34:47 init start
2020/01/15 06:34:47 init end
2020/01/15 06:34:47 main start
2020/01/15 06:34:47 handler start
2020/01/15 06:34:47 invoke=1, main=1, init=1
2020/01/15 06:34:47 handler end
[2nd request]
2020/01/15 06:43:17 handler start
2020/01/15 06:43:17 invoke=2, main=1, init=1
2020/01/15 06:43:17 handler end
[3rd request]
2020/01/15 06:43:19 handler start
2020/01/15 06:43:19 invoke=3, main=1, init=1
2020/01/15 06:43:19 handler end
初回起動でlambda.Start(Handler)
を呼んだ際にHandler()
をreceiverとしてserverに登録して、2回目以降はHandler()
を呼ぶようになっているようです。
次にしばらく時間を置いて "main end"
が呼ばれるかどうかを確認しましたがどうも出力されていないよう。
こちらはcontainer自体がkillされたのか、呼ばれているがログが出ていないのか判断がつかず。何かいい方法がないものか。
結論
-
init()
及びmain()
が呼ばれるのは初回requestのみ
- 2回目以降は
Handler()
が直接実行される
- 一定時間経過後、container自体がkillされる?
lambda.Start()
以降の処理は実行されているかどうか不明。
Database connection の close を呼ぶタイミングがなさそう・・・
呼ばれるかどうかは不明ですが、main()
内でlambda.Start()
を呼ぶ前にdeferで定義するのが良いんだろうか。