タイムアウト
サーバースクリプトのタイムアウトは、スクリプトごとに設定できるように見えます。しかし実際には、同じ実行条件のサーバースクリプトは 1 つに結合され、その中で最も大きいタイムアウト値が全体に適用されます。画面の見た目と実際の動作が異なるので注意してください。
タイムアウトとは
サーバースクリプトは、プリザンターに組み込まれた ClearScript(V8)の実行エンジンで実行されます。実行エンジンはプリザンター本体と同じプロセスの中で動き、プリザンターはその処理の完了を待ちます。どこまで実行を続けてよいかを決めるのがサーバースクリプトのタイムアウトです。
確認したソースでは、タイムアウトは実行開始時に「打ち切る時刻」として計算され、実行エンジンの ContinuationCallback で現在時刻がその時刻を過ぎていないかを判定しています(ServerScriptModel.cs)。この判定は JavaScript の実行中に行われるものなので、httpClient.Post() のように C# 側の処理を呼び出している最中は、その呼び出しが戻るまで打ち切られません。
設定方法
タイムアウトはミリ秒で設定します。設定方法は 2 種類です。
| 設定 | 場所 | 説明 |
|---|---|---|
| 全体の既定値 | Script.json の ServerScriptTimeOut | すべてのサーバースクリプトに共通。既定は 10000(10 秒) |
| スクリプト個別 | サーバースクリプトの設定画面 | Script.json の ServerScriptTimeOutChangeable を true にすると設定できる |
{
"ServerScriptTimeOut": 60000,
"ServerScriptTimeOutChangeable": true
}変更後はプリザンターの再起動が必要です。
httpClient のタイムアウトとの関係
ServerScriptHttpClientTimeOut(既定 100000)は httpClient 側のタイムアウトです。httpClient が 100 秒待てても、それを包むサーバースクリプトが既定の 10 秒で打ち切られます。外部 API を呼ぶ場合は httpClient と外部 API 呼び出しの落とし穴 も参照してください。
実装から見た実行の流れ
サーバースクリプトを実行しているのは ServerScriptUtilities.cs の次の部分です。
次の 3 条件をすべて満たしたときに実行されます。
- パラメータでサーバースクリプトが無効化されていない
- 個別のサーバースクリプトが無効化されていない
- サーバースクリプトが入れ子で実行されたとき、実行の深さが 10 段未満である(1.5.8.1 では ServerScriptUtilities.cs)
タイムアウトは最大値がまとめて適用される
タイムアウトは GetTimeOut メソッドで決まります。
- ServerScriptUtilities.cs#L1123(
GetTimeOutの呼び出し) - ServerScriptUtilities.cs#L1208-L1225(
GetTimeOutの実装)
同じ実行条件のサーバースクリプトのタイムアウト値はすべて集められ、その中の最大値が適用されます。確認したソースでは、タイムアウトが未設定のスクリプトは ServerScriptTimeOut の値として扱われます。また、タイムアウトに 0 を設定したスクリプトが 1 つでもあると、ServerScriptTimeOutChangeable が true の場合はまとめて無制限になり、false の場合は ServerScriptTimeOut が適用されます(ServerScriptUtilities.cs)。さらに、同じ条件のスクリプト本体は文字列で結合され、1 つのスクリプトとして実行されます。
例
同じ条件にサーバースクリプト A(タイムアウト 20,000 ミリ秒)と B(30,000 ミリ秒)があるとします。
図を読み込み中…
| 見た目の想定 | 実際の動作 | |
|---|---|---|
| 実行単位 | A と B を別々に実行 | A と B を結合して 1 回で実行 |
| タイムアウト | A は 20,000、B は 30,000 | A+B 全体で 30,000(最大値) |
つまり、A に短いタイムアウトを設定しても A 単独では打ち切られず、B の処理時間と合わせて 30,000 ミリ秒以内かどうかで判定されます。更新後や作成後などに長いタイムアウトが必要な処理を入れる場合は、同じ条件の他のスクリプトにも影響する点に注意してください。
INFO
同じ実行タイミングのスクリプトが結合されてひとまとまりで実行される間、httpClient のインスタンスは使い回されます(httpClient と外部 API 呼び出しの落とし穴 を参照)。