Appengine (GAE) はリクエストのイベントでインスタンスが起動されるので、通常のアプリケーションを実装した際に初回1回だけ実行する処理というのが普通に実装するとなかなか難しい。
特にDB(Datastore)アクセスなどが必要な場合にはrequestが無いとappengineのcontextを作成することができないのでそもそもDB(Datastore)へのアクセスができない。
そんなときに利用するのがwarmupリクエスト。
warmupリクエストとは
最初に書いたとおりでappengineはリクエスト駆動で動くため、warmupのリクエストがappengineの環境から実行される。
appengineはよしなにスケールするため、スピンアップのタイミングでそのリクエストがそのインスタンスに対して、1度だけやってくるというイメージ。
設定方法
app.yamlへwarmupの設定を追加する
Github にサンプルファイルをおいているが、以下のようにwarmupを実行するという設定を入力する必要がある。
ポイントは2箇所
まずは、warmupリクエストを使用しますよ。という設定が以下。
inbound_services: - warmup
もう一つは、warmupリクエストは /_ah/warmup
のパスへリクエストが送られるため、
- url: /_ah/warmup script: _go_app login: admin
という設定が必要となる。
_ah
ってどういう意味?って思うかもしれないが、 app handler
とかって意味とどこかで見たけど忘れたw
また、 login:admin
と書かれている場合には外部からのアクセスが行えないため、外からいたずらされないためには忘れずに付けましょう。
Application側の設定
こちらも Githug にサンプルを置いていますが、
特に難しいことはなく、handlerの設定として
http.HandleFunc("/_ah/warmup", warmup)
のような実装を行い、warmup functionの中で初期化を行いたい処理を書くと良いです。
先程も書いたように通常のハンドラと同様に実装できますので、requestを使ってappengine contextの生成も問題なく行えます。
参考
追記 : 落とし穴
warmupはどうやら絶対に実行してもらえるという感じのものでもないらしい。
Note that warmup requests are not guaranteed to be called. In some situations loading requests are sent instead: for example, if the instance is the first one being started up, or if there is a steep ramp-up in traffic. However, there will be a "best effort" attempt to send requests to already warmed-up instances if warmup requests are enabled
意訳 : warmupの実行は保証してないよー、ベストエフォートだよー
つまり、warmupが実行される前にリクエストを受け取った際には、初期化がされているか判別して初期化する、のような制御が必要
こちらの資料の p.12 - p.13 あたりに特に詳しく説明が載っています。(ありがたい)
www.slideshare.net
enjoy GAE/go!