最近クラウドワークスでのお仕事でいくつか Google Apps Script を使用したのだけど、なかなか使える良い子であると同時に癖もある奴なのでいつも使うパターンをメモするなど。
スクリプトの実行時間は1回あたり6分
仕様的には Quotas for Google Services を参照。
細かい処理をちょいちょいとこなす程度であれば気にする必要はないのだけど、大量のファイルとかを扱い始めるとハマる。というかハマッた。
対策としては「6分以内に終わらせる」もしくは「6分超えそうだったら一度中断し、改めて再開させる(中断・再開が可能なつくりにする)」の2パターン。ただこの制限値に引っかかるような処理をさせると結構動きがトロいのも分かるので、第3のパターンとして「Googleの外でやる(普通のサーバー上でGoogle APIを呼び出す)」を考えに入れておくべきなのかと思った。
処理を一度中断し、自動で再開させるのは Properties + Trigger 、ところにより JSON
いくつかググって、最終的には Google Apps Scriptで5分の壁(タイムアウト)を突破するを参考にしつつ自分なりのパターンを作ることにしました。
スクリプトの処理開始時刻を保存しておき、開始後何分経ったかを随時チェック
開始後6分を超過する前に十分な余裕をもって中断処理に入る
スクリプトの処理に必要なデータは Properties Service に格納する
ただし Properties はString value しか扱えないので、構造化データなどを格納したい場合は JSONフォーマットに変換して格納する
- Propertiesへ格納する際は JSON.stringify()
- Propertiesから復帰する際はJSON.parse()
なお当初Base64を使おうとしていたのは秘密だ(待て)
スクリプトを終了後自動的に再開させるのは Script Service の ClockTriggerBuilder クラス。
前述のBlogでも言及されていたし実際うまくいかなかったのだけど、Triggerで「after(durationMilliseconds)」があるくせにセットしてもちゃんと発動しない。…というか発動するのかもしれないけど「(plus or minus 15 minutes)」などとのんびりしたことを言われてしまっては使うわけにはいかんがな。せめて単位をsecondsにしてくれ…。
everyMinutes(n) で毎分起動→起動後に多重起動防止のためトリガーを削除 のパターンでいきませぅ。
ただ、ここはむしろトリガー追加+削除を繰り返すより、別途キューを用意しておき、毎分キュー確認→なにかあれば実行、何もなければ休眠、のほうがスマートな予感。
参考資料など。まー私が使ってるのはオライリーが販売しているPDF版ですがねハハハ(これはこれでよりによって「String」の項にしおりが設定されていないという痛恨のバグがある)。