Cloud Functions
トリガ
実行モデル
再利用される条件や timeout 時の挙動など
時刻
TZ 環境変数を設定したら日本時間になる
デプロイ時に --set-env-vars TZ=Asia/Tokyo など、Node & Go Runtime で確認
プロジェクト名は firebase と共通
プロジェクト名は共通の名前空間にある、firebase と gcp 一方で取ったプロジェクト名は共通して使えない
$ gcloud --project {project} functions deploy ... で firebase function 下にデプロイされる
これで Go で書いた function も firebase 下にデプロイできる、firebase hosting で叩けるかは未確認(たぶんいけるだろ)
Go で書く時
http トリガなら type HandlerFunc func(ResponseWriter, *Request) を公開する
そうでない場合(PubSub, CloudStroage) func(ctx context.Context, e イベント) error の interface
code:event.go
type GCSEvent struct {
Bucket string json:"bucket"
Name string json:"name"
}
type PubSubMessage struct {
Data []byte json:"data"
}
単に kick するだけなら e interface{} で受け取って捨ててもよい
global は使い回されることもあるし
Cloud Function の状態は、将来の呼び出しのために必ずしも保持されるわけではありません。しかし、Cloud Functions が以前の呼び出しの実行環境をリサイクルすることはよくあります。変数をグローバル スコープで宣言すると、その値は再計算せずに後続の呼び出しで再利用できるようになります。
global の変数を increment して返してる例、コールドスタートなら 0 からになるはず
Promise を返す
If a Node.js background function returns a Promise, Cloud Functions ensures that the Promise is settled before terminating.
あとでやってみる
background function とは pubsub や Cloud Storage イベントによって起動されるやつ
http functions は別に promise を待たない
--entry-point など function 設定として記憶されるオプション
--region など初回デプロイ時に渡すと以降省略しても同じリージョンにデプロイされるように
一度 --entry-point=app としてデプロイすると app が export されることを期待するようになる
その後 app を export しない実装をデプロイするとエラーになる
Deploying function (may take a while - up to 2 minutes)...
..............................................................................................................................................failed.
ERROR: (gcloud.functions.deploy) OperationError: code=13, message=Error setting up the execution environment for your function. Please try deploying again after a few minutes.
middleware
export.app = middeware(req, res, () => { ... })
req.rawBody がある
rawBody プロパティには、リクエスト本文の未解析バイト数が組み込まれています。
ふつう express.json() ミドルウェアを有効にしたらその後のハンドラでは req.body がパースされた状態になる
アプリケーションの外でやってくれているのはありがたい(なぜか rawBody が入ってて正しく動いた)
@google-cloud/functions-framework でも入っている
環境変数
table:env
GCP_PROJECT Reserved: The current GCP project ID.
FUNCTION_NAME Reserved: The name of the function resource.
FUNCTION_TIMEOUT_SEC Reserved: The execution timeout in seconds.
FUNCTION_IDENTITY Reserved: The current identity (service account) of the function.
FUNCTION_REGION Reserved: The function region (example: us-central1).
使いそうなのはこのあたりかな?
function から外部アクセスする際の timeout も適当にセットするのでなく、FUNCTION_TIMEOUT_SEC から伸縮できると印象が良いですね
nodejs10 runtime で値が全然足りてない、process.env を出力した例
code:process.env
"NO_UPDATE_NOTIFIER":"true",
"FUNCTION_TARGET":"logWithBunyan",
"NODE_OPTIONS":"--max-old-space-size=256",
"NODE_ENV":"production",
"PWD":"/srv/functions",
"HOME":"/root",
"DEBIAN_FRONTEND":"noninteractive",
"PORT":"8080",
"K_REVISION":"6",
"K_SERVICE":"logWithBunyan",
"SHLVL":"1",
"FUNCTION_SIGNATURE_TYPE":"http",
"PATH":"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"OLDPWD":"/srv",
"_":"../start-functions-framework"d
@google-cloud/logging でも K_SERVICE 見たりしている
(これでも nodejs10 では region 取れてない)
node8js & nodejs10 runtime の環境変数やリクエストヘッダ
app.enable('trust proxy') 済み
req.ip は X-Forwarded-For の左を返す
例外が出たときの状態
node10 では module が再読み込みされリセットされる
リクエストするたびカウントアップ
?throw=1 で例外投げる
カウントがゼロに戻る
コールドスタートから
クラッシュすると再利用されない
"正しく" エラーを返す(HTTP 関数で 500 をレスポンスする)場合は再利用されうる
Provided code is not a loadable module.
Provided code is not a loadable module.
Could not load the function, shutting down.
なにが悪いのか情報が足りないエラー、コンソールから zip でアップロードしたファイルをダウンロードできるので、落としてきてデバッグする
僕がこれを見る場合、1回目はデプロイできたのに2回目は失敗する! とハマっている
初回のデプロイでは .gcloudignore を置いてなくて作られる
#!include:.gitignore が含まれており、.gitignore しているファイルはアップロードしなくなる
その後に TypeScript プロジェクトなので、build/ 以下 ignore し忘れてたわ、と .gitignore に追加する 2回目のデプロイであれさっきできてたのにできねーぞ!!
となる