確認環境情報
Personal Environment(Version 11.21.0 (Build 39357))
Service Studio(Version 11.54.15)
基本として、Timerは停止できるように作りたい
この方法は、以前にTimerを停止できるように作るで書いた。
開発標準に入れてしまうかは悩むが、実装パターンとしてはそんなに複雑ではないので、検討の余地はあると思う。
ビルトインのリトライが問題を複雑化する
Timerには、Timeoutの仕組みがあり、一定時間が立つと例外が発生して停止する。
ただし、ビルトインのリトライの仕組みがあり、例外発生時には環境ごとに固定の回数までは自動でリトライされる。
よって、開発中にTimerに無限ループを仕込んでしまったり、運用中に゙データが膨らんで実行時間が想定以上に長くなってしまうと、
- Timerが長時間動き続ける(その間見ているしかない)
- Timeout in Minutes (+α) の時間が経過するとタイムアウトになる
- 一定時間後リトライ
- 原因が解決していないのでもう一度タイムアウト→リトライ、を上限回数まで繰り返す
ということになる。
Timerがタイムアウトするとどうなるかは、以前Timer・BPTにおける未処理Exceptionの扱い - Timerで確認した。
実行中のTimeoutをService Centerで短くしてみる
動作確認用Timerの実装
以下の通り、開始時・ループ毎・終了時にログを出力し、ループ毎に1分間スリープさせる(合計約10分間実行)Timer。
TimerのTimeout in Minutes Propertyの設定値はデフォルトの20分。
Timer実行中にTimeoutを短く設定
Service Centerで問題のTimerを起動し、実行が始まったのを確認してから、Timeoutの設定を3分にしてみた。
以下はService Centerで対象のTimerのページを開き、右下に表示される現在の実行状況。
Timeoutに設定した時間が近くなると表示される警告は出た。つまりこの表示には実行中に行ったTimeoutの変更が反映されている。
ところが、実際のTimer Actionは設定した3分が立っても実行が継続する。つまりTimer起動時のTimeout設定のほうが有効になっているようだ。
以下が、上で見たのと同じUIを実行開始後約8分の段階で再度確認したときのもの。
実行は継続しているのが確認できる。実行中には表示されたままのはずのIs running since項目が空になっているが、実行開始からの時間を示すCurrent durationには想定通りの経過時間が表示されている。
ログで確認したところ、10分経過後終了ログが出力されて無事に終了した(タイム・アウトされなかった)。
結論:実行中にTimeoutを短くしても、今実行しているTimerのタイムアウト時間は変わらない
ただし、実行中には常に値が設定されているはずのIs running sinceがUI上で見られなくなるという不思議な点はあった。
実行中のTimerロジックを修正してPublishしてみる
Timerを実行中にループの先頭で強制的にTimerを終了させる分岐を入れてPublish
「実行中のTimeoutをService Centerで短くしてみる」と同じロジックを使い
- まずTimeoutは3分のままにしておく(放っておくとタイムアウト→リトライを3回繰り返すて止まるはず)
- Service CenterからTimerを開始
- Timerが終わる前に以下の修正を行いPublish
して結果をログで確認する。
- 実行中のTimerにはロジックの変更が反映されずにループの先頭での分岐が適用されない
- loop1, loop2, loop3, loop4と4回目まで表示され、タイムアウトにかかって次のTimer実行が行われている(2つ目のstartのログ)
- 1分ごとに1ログのはずなのに、最初のTimer実行で4つのループ内ログが出力されているが、これはTimerのTimeout適用には少しゆとりがあるため(3分の設定にすると3分+αくらいの時間でタイムアウトになる)
- Timeout後のリトライではstartのログ出力後、ループの先頭で、新しいロジックである分岐(常にActionを終了させる分岐)にかかって処理を終えている
結論:実行中のTimerにはPublish結果は反映されない。ただしリトライされたときには新しいロジックで動作する
よって、開発環境ならこっちの方法で止めるのもありかと思う。