web-dev-qa-db-ja.com

Googleアプリスクリプトのタイムアウト〜5分?

私のGoogleアプリのスクリプトは、ユーザーのGoogleドライブファイルを反復処理し、ファイルを他のフォルダーにコピーして移動する場合があります。スクリプトは常に5分後に停止し、ログにエラーメッセージは表示されません。

1回の実行で数十、ときには数千のファイルをソートしています。

設定や回避策はありますか?

23
Martin V.

割り当て

1つのスクリプトの最大実行時間は6分/実行です
- https://developers.google.com/apps-script/guides/services/quotas

ただし、慣れるには他にも制限があります。たとえば、トリガーの合計実行時間は1時間/日しか許可されていないため、長い関数を12の異なる5分のブロックに分割することはできません。

最適化

とはいえ、実行に実際に6分かかる必要がある理由はほとんどありません。 JavaScriptは、数秒で数千行のデータをソートしても問題ありません。パフォーマンスを低下させている可能性があるのは、Google Apps自体へのサービス呼び出しです。

読み取りと書き込みの数を最小限に抑えることで、組み込みキャッシュを最大限に活用するスクリプトを作成できます。読み取りコマンドと書き込みコマンドを交互に実行すると時間がかかります。スクリプトを高速化するには、1つのコマンドですべてのデータを配列に読み込み、配列内のデータに対して任意の操作を実行し、1つのコマンドでデータを書き込みます。
- https://developers.google.com/apps-script/best_practices

バッチ処理

あなたができる最善のことは、サービス呼び出しの数を減らすことです。 Googleでは、ほとんどのAPI呼び出しのバッチバージョンを許可することでこれを可能にしています。

簡単な例として、これの代わりに

_for (var i = 1; i <= 100; i++) {
  SpreadsheetApp.getActiveSheet().deleteRow(i);
}
_

これを行う

_SpreadsheetApp.getActiveSheet().deleteRows(i, 100);
_

最初のループでは、シートのdeleteRowを100回呼び出すだけでなく、アクティブシートを100回取得する必要もありました。 2番目のバリエーションは、最初のバリエーションよりも数桁優れているはずです。

読み取りと書き込みを織り交ぜる

また、読み取りと書き込みを頻繁に行ったり来たりしないように注意する必要もあります。バッチ操作で潜在的な利益が失われるだけでなく、Googleは組み込みのキャッシュを使用できなくなります。

読み取りを行うたびに、まず書き込みキャッシュを空(コミット)して、最新のデータを読み取っていることを確認する必要があります(SpreadsheetApp.flush()を呼び出して、キャッシュの書き込みを強制できます)。同様に、書き込みを行うたびに、読み取りキャッシュは無効になるため破棄する必要があります。したがって、読み取りと書き込みのインターリーブを回避できる場合は、キャッシュを最大限に活用できます。
- http://googleappsscript.blogspot.com/2010/06/optimizing-spreadsheet-operations.html

たとえば、これの代わりに

_sheet.getRange("A1").setValue(1);
sheet.getRange("B1").setValue(2);
sheet.getRange("C1").setValue(3);
sheet.getRange("D1").setValue(4);
_

これを行う

_sheet.getRange("A1:D1").setValues([[1,2,3,4]]);
_

関数呼び出しの連鎖

最後の手段として、関数が実際に6分以内に完了できない場合は、呼び出しをチェーンするか、関数を分割して、より小さなデータセグメントで作業できます。

キャッシュサービス (一時的)または プロパティサービス (永続的)バケットにデータを保存して、実行全体で取得できます(Google Appsスクリプトにはステートレス実行があるため)。

別のイベントを開始したい場合は、 Trigger Builder Class を使用して独自のトリガーを作成するか、タイトなタイムテーブルで繰り返しトリガーを設定できます。

46
KyleMit

作業が6分未満になるように作業を分割する方法を考えてください。これがスクリプトの制限です。最初のパスでは、ファイルとフォルダーのリストを反復してスプレッドシートに保存し、パート2の時間駆動トリガーを追加できます。

パート2では、リストの各エントリを処理しながら削除します。リストにアイテムがない場合は、トリガーを削除します。

このようにして、約1500行のシートを処理し、約12の異なるスプレッドシートに広げます。スプレッドシートへの呼び出しの数が多いため、タイムアウトになりますが、トリガーが再度実行されると継続します。

11
Fred

UserPropertiesとプログラムによるトリガーを使用して、6分を超える範囲のバッチを実行するGoogle Appsスクリプトライブラリを開発しました。このライブラリをGASプロジェクトにインポートし、コードをAPIでラップして、FOREVERを実行できるようにすることができます(実際には、トリガーを実行できる時間数に関連する割り当ての制限があります)。

あなたはそれについてここですべて学ぶことができます: http://patt0.blogspot.in/2014/08/continuous-batch-library-update-for.html

4
patt0

G SuiteをBusiness、Enterprise、またはEDUの顧客として使用している場合、スクリプトの実行時間は次のように設定されます。

30分/実行

参照: https://developers.google.com/apps-script/guides/services/quotas

0
ScottMcC

企業顧客であれば、 フレキシブルクォータ を含む App Makerへの早期アクセス にサインアップできます。

フレキシブルクォータシステムでは、このようなハードクォータ制限が削除されます。スクリプトは、クォータ制限に達しても停止しません。むしろ、クォータが使用可能になるまで遅延され、その時点でスクリプトの実行が再開されます。クォータの使用が開始されると、通常の割合で補充されます。合理的な使用のために、スクリプトの遅延はまれです。

0
browly