今回はUntil Successful機能を使ったリトライを伴うフローの使い方について書きたいと思います。
今回使うコンポーネント
コンポーネント | アイコン・領域 | 用途 |
---|---|---|
Until Successful | 領域内のフローを実施し、エラーが発生した場合は再度領域部分をリトライする |
使い方
Until Successfulは直訳すると「成功するまでずっと」。その言葉の通り、処理が成功するまでやり続ける機能になります。ただし、いつまでもエラーのままだと無限ループに陥ってしまうため、回数制限と再試行までの時間を決めてリトライ処理をしていく仕組みとなります。
Until Successfulはフロー上で領域を指定して、その範囲内で適用されるタイプの使い方となります。
Until Successfulを配置すると、以下のように領域が出来上がります。以下、これをUntil Successful領域と呼ぶことにします。
Until Successful領域には名前の他に、以下のリトライ情報を設定します。
項目 | 用途 |
---|---|
Max Retries | リトライの試行回数 |
Milliseconds Between Retries | 再試行する際の待機時間(ミリ秒) |
いずれも数値での入力となります。
Max Retriesはリトライを実施する最大回数となります。実施回数ではないので注意してください。例えば、Max Retriesを5に設定した場合は、初回の試行+リトライ5回分で最大計6回実施されることになります。リトライ最大試行回数を超えた場合は、エラーが起こった要因の例外ではなく、MULE:RETRY_EXHAUSTED
というリトライ回数超過のエラーで処理されます。
Until Successful領域内はロジックなどの処理を組み立てていくんですが、この時にUntil Successful領域内で発生した例外は内部に例外をキャッチしない限りはUntil Successful領域内で吸収される形になります。
では、実際にフローを作って動きを確認しましょう。
フローを以下のように作成します。今回はUntil Successful領域内でエラーが起こるよう、ゼロ除算でエラーを発生する処理を入れています。また、変数の値を確認するために、Until Successfulの外で変数 (Number=0)を定義、Until Successfulの中で変数を更新するようにしています。
Max RetriesとMilliseconds Between Retriesの値はお好み。今回はリトライ回数5回の10秒間隔(Max Retries = 5、Milliseconds Between Retries = 10000)で設定しています。
実際の実行結果(ログ)は以下のようになりました。日付やクラス名など余分な部分は削っています。
INFO 16:39:03,346 LoggerMessageProcessor: Until Successful試行中
INFO 16:39:03,472 LoggerMessageProcessor: Number = 1
ERROR 16:39:03,494 UntilSuccessfulRouter: Retrying execution of event, attempt 1 of 5.
INFO 16:39:13,508 LoggerMessageProcessor: Until Successful試行中
INFO 16:39:13,528 LoggerMessageProcessor: Number = 1
ERROR 16:39:13,541 UntilSuccessfulRouter: Retrying execution of event, attempt 2 of 5.
INFO 16:39:23,546 LoggerMessageProcessor: Until Successful試行中
INFO 16:39:23,553 LoggerMessageProcessor: Number = 1
ERROR 16:39:23,557 UntilSuccessfulRouter: Retrying execution of event, attempt 3 of 5.
INFO 16:39:33,562 LoggerMessageProcessor: Until Successful試行中
INFO 16:39:33,568 LoggerMessageProcessor: Number = 1
ERROR 16:39:33,579 UntilSuccessfulRouter: Retrying execution of event, attempt 4 of 5.
INFO 16:39:43,598 LoggerMessageProcessor: Until Successful試行中
INFO 16:39:43,636 LoggerMessageProcessor: Number = 1
ERROR 16:39:43,647 UntilSuccessfulRouter: Retrying execution of event, attempt 5 of 5.
INFO 16:39:53,656 LoggerMessageProcessor: Until Successful試行中
INFO 16:39:53,696 LoggerMessageProcessor: Number = 1
ERROR 16:39:53,700 UntilSuccessfulRouter: Retry attempts exhausted. Failing...
ERROR 16:39:53,769 OnErrorContinueHandler:
********************************************************************************
Message : 'until-successful' retries exhausted
(中略)
Error type : MULE:RETRY_EXHAUSTED
Caused by : MULE:EXPRESSION: "Division by zero
1| 1/0
^^^
Trace:
at anonymous::main (line: 1, column: 1)" evaluating expression: "1/0".
FlowStack : at untilSuccessfulFlow(untilSuccessfulFlow/processors/1 @ mulepractice:mulepractice.xml:165 (Until Successful))
(set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
INFO 16:39:53,772 LoggerMessageProcessor: Until Successfulが最大試行回数に達しました
まず、時刻から10秒おきにリトライが実施されていること、リトライ5回を含む合計6回実行されていることが分かります。
そして、Numberの値が変更されていないことから、Until Successful内で更新された変数は保持されないということが分かりました。どうやらシリアルに動いているわけではなさそうで、リトライの際はUntil Successful実施前の値で動作している模様です。
まとめ
以上がUntil Successfulの使い方なります。簡単に特徴を纏めると以下の通りです。
- 最大試行回数と再試行間隔を指定してリトライの設定をする
- 領域内でエラーが発生した場合は再試行される
- 最大試行回数をオーバーすると、Until Successful領域を抜け出し
MULE:RETRY_EXHAUSTED
の例外が発生 - Until Successful領域内で更新された変数などは、再試行時に更新前の状態に戻る
for文のような反復処理というよりは、リトライ専用での使い方になりそうですね。
コメント