あけましておめでとうございます!だいちゃんです。
新年1発目の更新は、GAS(Google Apps Script)ネタです。ほんとに小さな小さなTipsですが、稼働時間に制限があるGASだと意外と使いどころがあるのではないでしょうか。
GASの便利な機能の1つに、トリガーと呼ばれる関数を自動実行させるものがありますが、1つ、2つならともかく、大量に設定するのはなかなか骨が折れる作業になります。
ただ、GASには トリガーを設定するモジュール? が用意されているので、それを利用することで1つずつ設定する手間を省くことができます!楽するためにコードを書くぜっ!
// 8分ごとにトリガーを設定する
function setTriggers(){
for (let i = 1; i <= 20; i++) {
ScriptApp.newTrigger(`getDataByJsonTest${i}`).timeBased().after(8 * 60 * 1000 * i).create();
}
}
今回は getDataByJsonTest1
getDataByJsonTest2
...のように関数名に連番を付与したものを用意している前提で書いています。
現在時刻から8分毎に連番で用意された関数を次々と実行するようにトリガーを設定している、非常にシンプルな関数です。
GASは無料で使えて超便利なので、もうそれだけでGoogle様様なのですが、本音を言うといくつかの制約に悩まされることがあります。それらの制約を把握して、うまく潜り抜ける術があるとワンランク上のガス屋さんになれると思います。しらんけど。
今回このコードを書く羽目になったのは「実行時間」の制約があるためで、しかもさらにそのコードは「トリガー数」の制約を受けることになってしまいました...。
まず 1関数あたりの実行時間は6分まで という制約です。
実は今回、jsonファイルのデータをスプシに取り込もうとしているのですが、jsonのパース・重複チェック・ちょっとした計算、などをしていると150件分くらい処理しきったところでタイムアウト(6分経過)してしまいました。もう少し燃費の良いコードを書くこともできそうですが、それでも3,000件を6分以内に抑えるのは厳しそうだったので、関数を100件ごとに30数回パッチ的に実行させることで捌き切ろうという魂胆です。
そこで先程のコードを見返すと、for文が1〜20までの繰り返し処理になっていることに気付くかと思います。それこそが2つめの 1アカウント/1スクリプトのトリガーは20個まで という制限の影響です。
20個までしかトリガーを設定しておけないので、一旦20個全て実行仕切ったあとに残りの10数個を再度設定し直さなくてはなりません。
それでも1つずつ設定するよりは遥かに楽なのですが...
この稼働時間の制約(6分)と、トリガー数の上限(20個)は割と引っかかりやすい制約事項かと思います。関数を実行したときに途中でコケてるなぁと思ったらだいたいこれです。特にトリガーで定期実行させてるものはコケてることにすら気付かなかったりするのでレポートメールはちゃんと読みましょう(ブーメラン)。
処理時間が膨大になっても、今回のようにパッチ的に処理できるようにしておけば回避できることもあるので、大量にぶん回す可能性のある関数を書くときには途中からも実行させられるような設計にしておくと良いかもしれないですね。毎回そうなるならそもそもGASで良いのか悩ましいところですが...。
P.S.
100件で区切ってもコケてる箇所があった...。処理重すぎたかな。
スプシに書き込む処理は重いのでホントはまとめて投げるようにした方がいいのだけど処理的に難しい気がするんだよなぁ。