

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# 失敗したアクティビティを再試行する
<a name="features-retry"></a>

一時的な接続の切断など、一過性の理由でアクティビティが失敗することがあります。アクティビティが成功するかどうかは場合によって異なるため、アクティビティが失敗した場合は、そのアクティビティを何度かやり直します。

アクティビティを再試行する戦略はさまざまです。最適な方法は、ワークフローの詳細によって異なります。この戦略は、3 つの基本カテゴリーに分類されます。
+ 成功するまで再試行する戦略では、完了するまでアクティビティを再試行します。
+ 指数的な再試行戦略では、アクティビティが完了するまで、またはプロセスが指定の停止ポイント (最大試行回数など) に達するまで、再試行の間隔を指数的に大きくします。
+ カスタムの再試行戦略では、試行が失敗する度にアクティビティを再試行するかどうか、またはその方法を決定します。

次のセクションでは、このような戦略を実装する方法について説明します。ワークフローワーカーの例ではすべて、1 つのアクティビティ `unreliableActivity` を使用します。これにより、以下のいずれかがランダムに実行されます。
+ ただちに完了する
+ タイムアウト値の超過により、意図的に失敗する
+ `IllegalStateException` をスローして、意図的に失敗する 

## 成功するまで再試行する戦略
<a name="features-retry-success"></a>

最もシンプルな再試行戦略は、最終的に成功するまで、失敗する度にアクティビティを再試行し続けることです。基本的なパターンは次のとおりです。

1. ワークフローのエントリポイントメソッドで、ネステッドクラス (`TryCatch` または `TryCatchFinally`) を実装する

1. `doTry` でアクティビティを実行する

1. アクティビティに失敗すると、フレームワークは `doCatch` を呼び出します。これにより、エントリポイントメソッドが再度実行されます。

1. アクティビティメソッドが正常に完了するまで、ステップ 2～3 を繰り返します。

次のワークフロー実装では、成功するまで再試行する戦略が実装されます。このワークフローインターフェイスは、`RetryActivityRecipeWorkflow` で実装されており、1 つのメソッド `runUnreliableActivityTillSuccess` が含まれます。これが、ワークフローのエンドポイントです。ワークフローワーカーは、次のように `RetryActivityRecipeWorkflowImpl` で実装されます。

```
public class RetryActivityRecipeWorkflowImpl
    implements RetryActivityRecipeWorkflow {

    @Override
    public void runUnreliableActivityTillSuccess() {
        final Settable<Boolean> retryActivity = new Settable<Boolean>();

        new TryCatch() {
            @Override
            protected void doTry() throws Throwable {
                Promise<Void> activityRanSuccessfully
                    = client.unreliableActivity();
                setRetryActivityToFalse(activityRanSuccessfully, retryActivity);
            }

            @Override
            protected void doCatch(Throwable e) throws Throwable {
                retryActivity.set(true);
            }
        };
        restartRunUnreliableActivityTillSuccess(retryActivity);
    }

    @Asynchronous
    private void setRetryActivityToFalse(
            Promise<Void> activityRanSuccessfully,
            @NoWait Settable<Boolean> retryActivity) {
        retryActivity.set(false);
    }

    @Asynchronous
    private void restartRunUnreliableActivityTillSuccess(
            Settable<Boolean> retryActivity) {
        if (retryActivity.get()) {
            runUnreliableActivityTillSuccess();
        }
    }
}
```

ワークフローの動作は次のとおりです。

1. `runUnreliableActivityTillSuccess` は、アクティビティが失敗し、再試行する必要があるかどうかを示すために使用される、`retryActivity` という名前の `Settable<Boolean>` オブジェクトを作成します。`Settable<T>` は `Promise<T>` から派生し、同じように動作しますが、`Settable<T>` オブジェクトの値は手動で設定します。

1. `runUnreliableActivityTillSuccess` は、匿名のネステッドクラス `TryCatch` を実装して、`unreliableActivity` アクティビティによってスローされるすべての例外に対処します。非同期コードでスローされる例外の対処方法の詳細については、「[エラー処理](errorhandling.md)」を参照してください。

1. `doTry` では、`unreliableActivity` アクティビティが実行され、`activityRanSuccessfully` という名前の `Promise<Void>` オブジェクトが返ります。

1. `doTry` は非同期メソッド `setRetryActivityToFalse` を呼び出します。このメソッドには、次の 2 つのパラメータが含まれます。
   + `activityRanSuccessfully` は、`unreliableActivity` アクティビティによって返る `Promise<Void>` オブジェクトを取得します。
   + `retryActivity` は、`retryActivity` オブジェクトを取得します。

   `unreliableActivity` が完了すると、`activityRanSuccessfully` は準備状態になり、`setRetryActivityToFalse` によって、`retryActivity` が FALSE に設定されます。それ以外の場合、`activityRanSuccessfully` は準備状態になり、`setRetryActivityToFalse` は実行されません。

1. `unreliableActivity` によって例外がスローされると、フレームワークは `doCatch` を呼び出し、例外オブジェクトを渡します。`doCatch` は `retryActivity` を true に設定します。

1. `runUnreliableActivityTillSuccess` は、非同期メソッド `restartRunUnreliableActivityTillSuccess` を呼び出し、`retryActivity` オブジェクトに渡します。`retryActivity` は `Promise<T>` タイプのため、`restartRunUnreliableActivityTillSuccess` は、`retryActivity` が準備状態になるまで実行を延期します。そのため、`TryCatch` が完了すると実行されます。

1. `retryActivity` が準備状態になると、`restartRunUnreliableActivityTillSuccess` によって値が抽出されます。
   + 値が `false` の場合、再試行は成功です。`restartRunUnreliableActivityTillSuccess` は問題ではないため、再試行シーケンスは終了します。
   + 値が true の場合、再試行は失敗です。アクティビティを再度実行するには、`restartRunUnreliableActivityTillSuccess` で `runUnreliableActivityTillSuccess` を呼び出します。

1. `unreliableActivity` が完了するまで、ステップ 1～7 を繰り返します。

**注記**  
`doCatch` では、例外は処理されません。`retryActivity` オブジェクトは、アクティビティが失敗したことを示す true に設定されます。この再試行は、非同期メソッド `restartRunUnreliableActivityTillSuccess` で処理されます。これにより、`TryCatch` が完了するまで、実行は延期されます。このアプローチの理由は、`doCatch` でアクティビティを再試行する場合はキャンセルできないことです。`restartRunUnreliableActivityTillSuccess` でアクティビティを再試行すると、キャンセル可能なアクティビティを実行できます。

## 指数的再試行戦略
<a name="features-retry-exponential"></a>

指数的再試行戦略を使用して、フレームワークは、指定された時間 (N 秒) が経過すると、失敗したアクティビティを実行します。再試行が失敗した場合、フレームワークは 2N 秒、4N 秒と経過すると、再度アクティビティを実行します。待機時間は大きくなる可能性があるため、通常は無期限に続けずに、再試行を一定のポイントで停止します。

フレームワークには、指数的再試行戦略を実装する 3 つの方法があります。
+ `@ExponentialRetry` 注釈は、最もシンプルなアプローチですが、コンパイル時に再試行設定オプションを設定する必要があります。
+ `RetryDecorator` クラスでは、実行時の再試行を設定し、必要に応じて変更することができます。
+ `AsyncRetryingExecutor` クラスでは、実行時の再試行を設定し、必要に応じて変更することができます。また、フレームワークは、ユーザー実装の `AsyncRunnable.run` メソッドを呼び出して、ひとつずつ再試行を行います。

次の設定オプションはすべてのアプローチでサポートされており、時刻値は秒単位で計測されます。
+ 最初の再試行待機時間。
+ バックオフ係数。次のように、再試行間隔の計算に使用されます。

  ```
  retryInterval = initialRetryIntervalSeconds * Math.pow(backoffCoefficient, numberOfTries - 2)
  ```

  デフォルト値は 2.0 です。
+ 再試行の最大数。デフォルト値の制限はありません。
+ 最大再試行間隔。デフォルト値の制限はありません。
+ 有効期限。再試行は、プロセスの合計期間がこの値を超過すると停止します。デフォルト値の制限はありません。
+ 再試行プロセスをトリガーする例外。デフォルトでは、例外ごとに再試行プロセスがトリガーされます。
+ 再試行プロセスをトリガーしない例外。デフォルトでは、除外される例外はありません。

次のセクションでは、指数的再試行戦略を実装するさまざまな方法について説明します。

### @ExponentialRetry を使用した指数的再試行
<a name="features-retry-exponential-annotation"></a>

アクティビティの指数的再試行戦略を実装する最もシンプルな方法は、`@ExponentialRetry ` 注釈をインターフェイスの定義のアクティビティに適用することです。アクティビティが失敗すると、フレームワークは、特定のオプション値に基づき、自動的に再試行プロセスに対処します。基本的なパターンは次のとおりです。

1. `@ExponentialRetry` を適切なアクティビティに適用し、再試行設定を指定します。

1. 注釈されたアクティビティが失敗した場合、フレームワークは、注釈の引数で指定された設定に従って、自動的にアクティビティを再試行します。

`ExponentialRetryAnnotationWorkflow` ワークフローワーカーは、`@ExponentialRetry` 注釈を使用して、再試行戦略を実装します。次のように、インターフェイス定義が `ExponentialRetryAnnotationActivities` に実装されている `unreliableActivity` アクティビティを使用します。

```
@Activities(version = "1.0")
@ActivityRegistrationOptions(
    defaultTaskScheduleToStartTimeoutSeconds = 30,
    defaultTaskStartToCloseTimeoutSeconds = 30)
public interface ExponentialRetryAnnotationActivities {
    @ExponentialRetry(
        initialRetryIntervalSeconds = 5,
        maximumAttempts = 5,
        exceptionsToRetry = IllegalStateException.class)
    public void unreliableActivity();
}
```

`@ExponentialRetry` オプションでは、以下の戦略を指定します。
+ アクティビティで `IllegalStateException` がスローされる場合のみ、再試行します。
+ 最初の待機時間として 5 秒を使用します。
+ 6 回以上再試行することはできません。

このワークフローインターフェイスは、`RetryWorkflow` で実装されており、1 つのメソッド `process` が含まれます。これが、ワークフローのエンドポイントです。ワークフローワーカーは、次のように `ExponentialRetryAnnotationWorkflowImpl` で実装されます。

```
public class ExponentialRetryAnnotationWorkflowImpl implements RetryWorkflow {
    public void process() {
        handleUnreliableActivity();
    }

    public void handleUnreliableActivity() {
        client.unreliableActivity();
    }
}
```

ワークフローの動作は次のとおりです。

1. `process` では、非同期メソッド `handleUnreliableActivity` が実行されます。

1. `handleUnreliableActivity` は、`unreliableActivity` アクティビティを実行します。

`IllegalStateException` のスローによりアクティビティが失敗した場合、フレームワークは、`ExponentialRetryAnnotationActivities` で指定されている再試行戦略を自動的に実行します。

### RetryDecorator クラスを使用した指数的再試行
<a name="features-retry-exponential-decorator"></a>

`@ExponentialRetry` の使用は簡単です。ただし、設定は静的で、コンパイル時に設定されるため、フレームワークは、アクティビティが失敗する度に、同じ再試行戦略を使用します。より複雑な再試行戦略を実装するには、`RetryDecorator` クラスを使用します。これにより、実行時に設定を指定し、必要に応じて変更することができます。基本的なパターンは次のとおりです。

1. 再試行設定を指定する `ExponentialRetryPolicy` オブジェクトを作成し、設定します。

1. `RetryDecorator` オブジェクトを作成し、ステップ 1 の `ExponentialRetryPolicy` オブジェクトをコンストラクタに渡します。

1. アクティビティクライアントのクラス名を `RetryDecorator` オブジェクトのデコレートメソッドに渡し、デコレーターオブジェクトをアクティビティに適用します。

1. アクティビティを実行します。

アクティビティが失敗した場合、フレームワークは、`ExponentialRetryPolicy` オブジェクトの設定に従って、アクティビティを再試行します。必要に応じて、設定を変更して再試行するには、このオブジェクトを変更します。

**注記**  
`@ExponentialRetry` 注釈および `RetryDecorator` クラスは、相互に排他的です。`@ExponentialRetry` 注釈で指定されている再試行ポリシーを動的に上書きするために `RetryDecorator` を使用することはできません。

以下のワークフロー実装では、指数的再試行戦略を実装するために `RetryDecorator` クラスの使用方法を示します。`@ExponentialRetry` 注釈を含まない `unreliableActivity` アクティビティを使用します。このワークフローインターフェイスは、`RetryWorkflow` で実装されており、1 つのメソッド `process` が含まれます。これが、ワークフローのエンドポイントです。ワークフローワーカーは、次のように `DecoratorRetryWorkflowImpl` で実装されます。

```
public class DecoratorRetryWorkflowImpl implements RetryWorkflow {
   ...
  public void process() {
      long initialRetryIntervalSeconds = 5;
      int maximumAttempts = 5;
      ExponentialRetryPolicy retryPolicy = new ExponentialRetryPolicy(
              initialRetryIntervalSeconds).withMaximumAttempts(maximumAttempts);

      Decorator retryDecorator = new RetryDecorator(retryPolicy);
      client = retryDecorator.decorate(RetryActivitiesClient.class, client);
      handleUnreliableActivity();
  }

  public void handleUnreliableActivity() {
      client.unreliableActivity();
  }
}
```

ワークフローの動作は次のとおりです。

1. `process` は、次の方法で、`ExponentialRetryPolicy` オブジェクトを作成し設定します。
   + 最初の再試行間隔をコンストラクタに渡します。
   + オブジェクトの `withMaximumAttempts` メソッドの呼び出し試行回数の上限を 5 に設定します。`ExponentialRetryPolicy` は、他の設定オプションを指定するために使用できる他の `with` オブジェクトを公開します。

1. `process` は、`retryDecorator` という名前の `RetryDecorator` オブジェクトを作成し、ステップ 1 の `ExponentialRetryPolicy` オブジェクトをコンストラクタに渡します。

1. `process` は、`retryDecorator.decorate` メソッドを呼び出して、アクティビティクライアントのクラス名を渡すことで、デコレーターをアクティビティに適用します。

1. `handleUnreliableActivity` は、アクティビティを実行します。

アクティビティが失敗した場合、フレームワークは、ステップ 1 で指定した設定に従って、アクティビティを再試行します。

**注記**  
`ExponentialRetryPolicy` クラスの `with` メソッドの中には、`set` メソッドが含まれる場合があります。このメソッドを呼び出して、次の設定オプションをいつでも変更することができます: `setBackoffCoefficient`、`setMaximumAttempts`、`setMaximumRetryIntervalSeconds`、`setMaximumRetryExpirationIntervalSeconds`。

### AsyncRetryingExecutor クラスを使用した指数的再試行
<a name="features-retry-exponential-async"></a>

`RetryDecorator` クラスを使用して、再試行プロセスを設定すると、`@ExponentialRetry` よりも柔軟性は高くなりますが、フレームワークは、`ExponentialRetryPolicy` オブジェクトの現在の設定に基づき、自動的に再試行を行います。`AsyncRetryingExecutor` クラスを使用するアプローチの方が柔軟性は高くなります。フレームワークは、実行時の再試行プロセスの設定を可能にするだけでなく、ユーザー実装の `AsyncRunnable.run` メソッドを呼び出して、アクティビティを単純に実行せずに、再試行ごとに実行します。

基本的なパターンは次のとおりです。

1. `ExponentialRetryPolicy` オブジェクトを作成、設定して、再試行設定を指定します。

1. `AsyncRetryingExecutor` オブジェクトを作成し、`ExponentialRetryPolicy` オブジェクトと、ワークフロークロックのインスタンスを渡します。

1.  匿名のネステッドクラス (`TryCatch` または `TryCatchFinally`) を実装します。

1. 匿名のクラス (`AsyncRunnable`) を実装して、`run` メソッドを上書きし、アクティビティの実行に使用するカスタムコードを実装します。

1.  `doTry` を上書きして `AsyncRetryingExecutor` オブジェクトの `execute` メソッドを呼び出し、ステップ 4 の `AsyncRunnable` クラスを渡します。`AsyncRetryingExecutor` オブジェクトは、`AsyncRunnable.run` を呼び出してこのアクティビティを実行します。

1. アクティビティが失敗した場合、`AsyncRetryingExecutor` オブジェクトは、ステップ 1 の再試行ポリシーに従って、`AsyncRunnable.run` メソッドを再度呼び出します。

以下のワークフローでは、指数的再試行戦略を実装するために `AsyncRetryingExecutor` クラスの使用方法を示します。このクラスでは、先ほどの `DecoratorRetryWorkflow` ワークフローと同じ `unreliableActivity` アクティビティが使用されます。このワークフローインターフェイスは、`RetryWorkflow` で実装されており、1 つのメソッド `process` が含まれます。これが、ワークフローのエンドポイントです。ワークフローワーカーは、次のように `AsyncExecutorRetryWorkflowImpl` で実装されます。

```
public class AsyncExecutorRetryWorkflowImpl implements RetryWorkflow {
  private final RetryActivitiesClient client = new RetryActivitiesClientImpl();
  private final DecisionContextProvider contextProvider = new DecisionContextProviderImpl();
  private final WorkflowClock clock = contextProvider.getDecisionContext().getWorkflowClock();

  public void process() {
      long initialRetryIntervalSeconds = 5;
      int maximumAttempts = 5;
      handleUnreliableActivity(initialRetryIntervalSeconds, maximumAttempts);
  }
  public void handleUnreliableActivity(long initialRetryIntervalSeconds, int maximumAttempts) {

      ExponentialRetryPolicy retryPolicy = new ExponentialRetryPolicy(initialRetryIntervalSeconds).withMaximumAttempts(maximumAttempts);
      final AsyncExecutor executor = new AsyncRetryingExecutor(retryPolicy, clock);

      new TryCatch() {
          @Override
          protected void doTry() throws Throwable {
              executor.execute(new AsyncRunnable() {
                  @Override
                  public void run() throws Throwable {
                      client.unreliableActivity();
                  }
              });
          }
          @Override
          protected void doCatch(Throwable e) throws Throwable {
          }
      };
  }
}
```

ワークフローの動作は次のとおりです。

1. `process` は、`handleUnreliableActivity` メソッドを呼び出し、構成設定を渡します。

1. `handleUnreliableActivity` では、ステップ 1 の設定を使用して、`ExponentialRetryPolicy` オブジェクト、`retryPolicy` を作成します。

1. `handleUnreliableActivity` は、`AsyncRetryExecutor` オブジェクト、`executor` を作成し、ステップ 2 の`ExponentialRetryPolicy` オブジェクトと、ワークフロークロックのインスタンスをコンストラクタに渡します。

1.  `handleUnreliableActivity` は、非同期のネステッドクラス `TryCatch` を実装し、`doTry` および `doCatch` メソッドを上書きして、再試行を実行し、例外に対処します。

1. `doTry` は匿名の `AsyncRunnable` クラスを作成して、`run` メソッドを上書きし、`unreliableActivity` を実行するためのカスタムコードを実装します。分かりやすいように、`run` ではアクティビティを実行しますが、必要に応じて、洗練されたアプローチを実装することもできます。

1. `doTry` は `executor.execute` を呼び出して、`AsyncRunnable` オブジェクトに渡します。`execute` は、`AsyncRunnable` オブジェクトの `run` メソッドを呼び出して、アクティビティを実行します。

1. アクティビティが実行した場合、エグゼキューターは、`retryPolicy` オブジェクトの設定に従って、再度 `run` を呼び出します。

`TryCatch` クラスを使用して、エラーに対応する詳細な方法については、「[AWS Flow Framework for Java の例外](errorhandling.exceptions.md)」を参照してください。

## カスタムの再試行戦略
<a name="custom-retry-strategy"></a>

失敗したアクティビティを再試行する最も柔軟な方法はカスタム戦略です。この方法では、成功するまで再試行する戦略とほとんど同じように、再試行を実行する非同期メソッドを再帰的に呼び出します。ただし、アクティビティを再度実行するだけではなく、連続的な再試行それぞれの実行有無および実行方法を決めるカスタムロジックを実装します。基本的なパターンは次のとおりです。

1. `Settable<T>` ステータスオブジェクトを作成します。このオブジェクトは、アクティビティが失敗したかどうかを示します。

1. ネステッドクラス (`TryCatch` または `TryCatchFinally`) クラスを実装します。

1. `doTry` は、アクティビティを実行します。

1. アクティビティが失敗した場合、`doCatch` は、アクティビティが失敗したことを示すステータスオブジェクトを設定します。

1. 非同期障害処理メソッドを呼び出し、それにステータスオブジェクトを渡します。このメソッドでは、`TryCatch` または `TryCatchFinally` が完了するまで、実行が延期されます。

1. 障害処理メソッドは、アクティビティの再試行有無を判断し、再試行する場合は再試行日時を決定します。

以下のワークフローは、カスタムの再試行戦略を実行する方法を示します。この戦略では、`DecoratorRetryWorkflow` および `AsyncExecutorRetryWorkflow` ワークフローと同じ `unreliableActivity` が使用されます。このワークフローインターフェイスは、`RetryWorkflow` で実装されており、1 つのメソッド `process` が含まれます。これが、ワークフローのエンドポイントです。ワークフローワーカーは、次のように `CustomLogicRetryWorkflowImpl` で実装されます。

```
public class CustomLogicRetryWorkflowImpl implements RetryWorkflow {
  ...
  public void process() {
      callActivityWithRetry();
  }
  @Asynchronous
  public void callActivityWithRetry() {
      final Settable<Throwable> failure = new Settable<Throwable>();
      new TryCatchFinally() {
          protected void doTry() throws Throwable {
              client.unreliableActivity();
          }
          protected void doCatch(Throwable e) {
              failure.set(e);
          }
          protected void doFinally() throws Throwable {
              if (!failure.isReady()) {
                  failure.set(null);
              }
          }
      };
      retryOnFailure(failure);
  }
  @Asynchronous
  private void retryOnFailure(Promise<Throwable> failureP) {
      Throwable failure = failureP.get();
      if (failure != null && shouldRetry(failure)) {
          callActivityWithRetry();
      }
  }
  protected Boolean shouldRetry(Throwable e) {
      //custom logic to decide to retry the activity or not
      return true;
  }
}
```

ワークフローの動作は次のとおりです。

1. `process` は、非同期メソッド `callActivityWithRetry` を呼び出します。

1. `callActivityWithRetry` は、アクティビティが失敗したかどうかを示すために使用される failure という名前の `Settable<Throwable>` オブジェクトを作成します。`Settable<T>` は `Promise<T>` から派生して同じように動作しますが、`Settable<T>` オブジェクトの値は手動で設定します。

1. `callActivityWithRetry` では、非同期のネステッドクラス `TryCatchFinally` を実装して、`unreliableActivity` によってスローされるすべての例外に対処します。非同期コードでスローされる例外の対処方法の詳細については、「[AWS Flow Framework for Java の例外](errorhandling.exceptions.md)」を参照してください。

1. `doTry` は、`unreliableActivity` を実行します。

1. `unreliableActivity` によって例外がスローされると、フレームワークは `doCatch` を呼び出し、例外オブジェクトに渡します。`doCatch` は `failure` を例外オブジェクトに設定します。これは、アクティビティが失敗し、オブジェクトが準備状態になったことを表します。

1. `doFinally` は、`failure` が準備状態かどうかを確認します。`failure` が `doCatch` で設定されている場合のみ、true になります。
   + `failure` の準備ができたら、 `doFinally`は何もしません。
   + `failure` の準備ができていない場合、アクティビティは完了し、`doFinally` によってエラーが `null` に設定されます。

1. `callActivityWithRetry` は、非同期メソッド `retryOnFailure` を呼び出し、障害に渡します。障害は `Settable<T>` タイプのため、`callActivityWithRetry` は、障害が準備状態になるまで実行を延期します。そのため、`TryCatchFinally` が完了すると実行されます。

1. `retryOnFailure` は、障害から値を取得します。
   + failure が null に設定されると、再試行は成功です。`retryOnFailure` では何も行われないため、再試行プロセスは終了します。
   + 障害が例外オブジェクトに設定されており、`shouldRetry` より true が返る場合、`retryOnFailure` は `callActivityWithRetry` を呼び出して、そのアクティビティを再試行します。

     `shouldRetry` はカスタムロジックを実装して、失敗したアクティビティを再試行するかどうかを決定します。分かりやすいように、`shouldRetry` は、常に `true` を返し、`retryOnFailure` はアクティビティをただちに実行しますが、必要に応じて洗練されたロジックを実装することができます。

1. `unreliableActivity` が完了するか、 `shouldRetry`でプロセスの停止が決定するまで、ステップ 2～8 を繰り返します。

**注記**  
`doCatch` では、再試行プロセスは処理されません。この場合は、アクティビティが失敗したことを示す障害に設定されます。この再試行プロセスは、非同期メソッド `retryOnFailure` で処理されます。これにより、`TryCatch` が完了するまで、実行は延期されます。このアプローチの理由は、`doCatch` でアクティビティを再試行する場合はキャンセルできないことです。`retryOnFailure` でアクティビティを再試行すると、キャンセル可能なアクティビティを実行できます。