以前の記事で「GASの実行制限(6分)対策でトリガー再起動を行う際、二重起動に悩まされている」とお伝えしました。当時は排他制御(LockService)などの対応が必要だと考えていましたが、最近になって真の原因が判明しました。
ScriptApp.newTrigger("SAKUSEI")
結論から言うと、原因はトリガーの作成コードにありました。
誤っていたコード(重複の原因)
これまで、再起動のために以下のコードを使用していました。
ScriptApp.newTrigger("SAKUSEI")
.timeBased()
.everyMinutes(1) // 1分ごとに実行
.create();
ScriptApp.newTrigger("SAKUSEI")
実は .everyMinutes(1) という指定は、「1分おきに、永続的に実行し続ける」というトリガーを作成してしまいます。実行のたびにこれが発行されるため、「1分おきに動くトリガー」が雪だるま式に増えてしまい、結果として二重・三重に起動していたのです。
正しいコード(1回だけ実行)
私が本来やりたかったのは「1分後に、1回だけ実行する」ことでした。その場合は、以下のように after() を使うのが正解です。
.timeBased()
.after(60 * 1000) // 60秒後に「1回だけ」実行
.create();
まとめ
after() を使うことで、余計なトリガーが残らず、排他制御などの複雑な処理を入れずともスマートに実行継続ができるようになりました。