com.amazonaws.services.simpleworkflow.flow.core

## クラス TryCatchFinally

- java.lang.Object
- - com.amazonaws.services.simpleworkflow.flow.core.TryCatchFinally

- すべての実装されたインタフェース:
    Cancelable
  直系の既知のサブクラス:
    TryCatch, TryFinally

      public abstract class TryCatchFinally
      extends java.lang.Object
      implements Cancelable

  Asynchronous equivalent of synchronous try-catch-finally.

  ### Overview

  SWF Flow error handling relies on the idea that any asynchronous task (which includes methods annotated as `Asynchronous`) is executed in a parent context. In the case of an exception being thrown from a task, all sibling tasks that share the same parent context are canceled. After successful cancellation the exception is propagated to the parent context for handling.

  `TryCatchFinally` `doTry()`, `doFinally()` and `doCatch(Throwable)` methods serve as parent scopes for tasks created during their execution.

  For example if any `Task` (or method annotated with `Asynchronous`) that originates (possibly indirectly through parent task) in `doTry()` throws an exception all other tasks that originated in `doTry()` are canceled and only then `doCatch(Throwable)` is called. Through this cancellation mechanism it is guaranteed that `doCatch(Throwable)` is called at most once even if there are multiple parallel tasks executing in the `doTry()` scope.

  If failure happens in a task originated in `doCatch(Throwable)` then all its siblings are canceled first and then `doFinally()` is called.

  The same happens if task originated in `doFinally()` fails. All it siblings are canceled and then parent scope of the `TryCatchFinally` is given chance to handle the exception.

  ### Cancellation

  The cancellation semantic depends on the task implementation. `Task` (or method annotated with `Asynchronous`) that has not started execution is never given chance to execute after cancellation. Task which is already executing is not interrupted and completes (or fails). `ExternalTask` cancellation depends on the external resource. For example SWF activities and child workflows that are modeled as `ExternalTask`s are canceled through SWF API.

  When `TryCatchFinally` itself is canceled because of sibling task failure it handles its own cancellation in the following order:

  1. If doTry hasn't started yet then `TryCatchFinally` is considered canceled immediately.
  2. If are any outstanding task that originated in `doTry()` then cancellation of all of them is requested.
  3. After all tasks originated in doTry are canceled call `doCatch(Throwable)` with `CancellationException`.
  4. After all tasks originated in doCatch are completed call `doFinally()`.
  5. After all tasks originated in `doFinally()` are completed consider TryCathFinally canceled

  `doCatch(Throwable)` and `doFinally()` are not cancelable. It means that cancellation request always waits for completion of all tasks that originate in these methods. Special care should be taken when writing code in `doCatch(Throwable)` and in `doFinally()` to ensure that in all possible failure scenarios they don't end up in a stuck state.

  `TryCatchFinally` can be canceled explicitly through `cancel(Throwable)` method. In case of explicit cancellation any exception including `CancellationException` that is rethrown from `doCatch(Throwable)` or `doFinally()` is propagated to the parent context.

  ### Daemon Tasks

  It is pretty common to have tasks that have their lifecycle linked to some other tasks. For example notification activity that is sent out if some other activity is not completed in a specified period of time. The timer and the notification activity should be canceled as soon as the monitored activity is completed. Such use case can be supported by wrapping timer and notification activity in `TryCatchFinally` which is explicitly canceled upon monitored activity completion. The more convenient way to perform such cleanup is by marking a Task (or method annotated with `Asynchronous`) as daemon. The asynchronous scope in absence of failures is executed in the following sequence:

  1. The scope method (for example `doTry()`) is executed.
  2. All tasks that are created during its execution are executed (when Promises they are waiting on become ready) possibly creating more tasks.
  3. When all non daemon tasks originated in the scope method are completed cancellation requests are sent to all daemon siblings.
  4. The scope is completed after all daemon tasks are canceled.

  Pass `true` to the first argument of `Task.Task(boolean, Promise...)` constructor to mark a Task as daemon. Use `Asynchronous.daemon()` annotation parameter to mark an asynchronous method as daemon. Any task that is created during execution of a daemon task is marked as daemon. `TryCatchFinally` also can be marked as daemon through `TryCatchFinally(boolean, Promise...)` constructor or by by being created by a daemon task. Note that TryCatchFinally doesn't pass its daemon flag to tasks created in `doTry()`, `doCatch(Throwable)` and `doFinally()`. It is because each of these methods acts as a separate asynchronous scope and the rules of execution described above apply to them.

  ### Miscellaneous

  In case of multiple simultaneous exceptions (which is possible for external tasks) or if cancellation of a child results in any exception that is not `CancellationException` the last exception "wins". I.e. it becomes the exception delivered to `doCatch(Throwable)` method.

  Note that instances of `Promise` do not participate in error handling the way `Future` does. If method that returns Promise throws an exception the Promise state and return value are not changed. It is similar to behavior of variables in case of synchronous code.

  ### Usage Examples

  Basic error handling:

       new TryCatchFinally() {

           final List<Promise<String>> instances = new ArrayList<Promise<String>>();

           protected void doTry() throws Throwable {
               for (int i = 0; i < count; i++) {
                   Promise<String> instanceId = ec2.startInstance();
                   instances.add(instanceId);
               }
               performSimulation(instances);
           }

           protected void doCatch(Throwable e) throws Throwable {
               mail.notifySimulationFailure(e);
           }

           protected void doFinally() throws Throwable {
               for (int i = 0; i < count; i++) {
                   Promise<String> instanceId = instances.get(i);
                   if (instanceId.isReady()) {
                       ec2.stopInstance(instanceId.get());
                   }
               }
           }
       };

  Daemon example:

       protected void doTry() throws Throwable {
           for (int i = 0; i < count; i++) {
               Promise<String> instanceId = ec2.startInstance();
               instances.add(instanceId);
           }
           performSimulation(instances);
           notifyOnDelay();
       }

       @Asynchronous(daemon = true)
       public void notifyOnDelay() {
           Promise<Void> timer = clock.scheduleTimer(3600);
           mail.notifyDelay(timer);
       }

  作成者:
    fateev

- - ### ネストされたクラスの概要

    ネストされたクラス
    修飾子とタイプ | クラスと説明
    --- | ---
    `static class` | `TryCatchFinally.State`

  - ### コンストラクタの概要

    コンストラクタ
    修飾子 | コンストラクタと説明
    --- | ---
    `` | `TryCatchFinally()`
    `` | `TryCatchFinally(com.amazonaws.services.simpleworkflow.flow.core.AsyncContextAware parent, boolean daemon, Promise<?>... waitFor)`
    `protected` | `TryCatchFinally(com.amazonaws.services.simpleworkflow.flow.core.AsyncContextAware parent, java.lang.Boolean daemon, java.lang.String parentTaskMethodName, int skipStackLines, Promise<?>[] waitFor)`
    `` | `TryCatchFinally(com.amazonaws.services.simpleworkflow.flow.core.AsyncContextAware parent, Promise<?>... waitFor)`
    `` | `TryCatchFinally(boolean daemon, Promise<?>... waitFor)`
    `protected` | `TryCatchFinally(java.lang.Boolean daemon, java.lang.String parentTaskMethodName, int skipStackLines, Promise<?>[] waitFor)`
    `` | `TryCatchFinally(Promise<?>... waitFor)`

  - ### メソッドの概要

    メソッド
    修飾子とタイプ | メソッドと説明
    --- | ---
    `void` | `cancel(java.lang.Throwable cause)`
    `protected abstract void` | `doCatch(java.lang.Throwable e)`
    `protected abstract void` | `doFinally()`
    `protected abstract void` | `doTry()`
    `java.util.List<AsyncTaskInfo>` | `getAsynchronousStackTraceDump()`
    `java.lang.String` | `getAsynchronousStackTraceDumpAsString()`
    `java.lang.String` | `getName()`
    `java.lang.StackTraceElement[]` | `getStackTrace()`
    `TryCatchFinally.State` | `getState()`
    `boolean` | `isCancelRequested()`
    `protected void` | `rethrow(java.lang.Throwable e, Promise<?>... waitFor)`
    `void` | `setName(java.lang.String name)`
    `java.lang.String` | `toString()`

    - ### クラスから継承されたメソッド java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### コンストラクタの詳細

    - #### TryCatchFinally

          public TryCatchFinally()

    - #### TryCatchFinally

          public TryCatchFinally(Promise<?>... waitFor)

    - #### TryCatchFinally

          public TryCatchFinally(boolean daemon,
                         Promise<?>... waitFor)

    - #### TryCatchFinally

          public TryCatchFinally(com.amazonaws.services.simpleworkflow.flow.core.AsyncContextAware parent,
                         boolean daemon,
                         Promise<?>... waitFor)

    - #### TryCatchFinally

          public TryCatchFinally(com.amazonaws.services.simpleworkflow.flow.core.AsyncContextAware parent,
                         Promise<?>... waitFor)

    - #### TryCatchFinally

          protected TryCatchFinally(java.lang.Boolean daemon,
                         java.lang.String parentTaskMethodName,
                         int skipStackLines,
                         Promise<?>[] waitFor)

    - #### TryCatchFinally

          protected TryCatchFinally(com.amazonaws.services.simpleworkflow.flow.core.AsyncContextAware parent,
                         java.lang.Boolean daemon,
                         java.lang.String parentTaskMethodName,
                         int skipStackLines,
                         Promise<?>[] waitFor)

  - ### メソッドの詳細

    - #### getName

          public java.lang.String getName()

    - #### setName

          public void setName(java.lang.String name)

    - #### cancel

          public void cancel(java.lang.Throwable cause)

      定義:
        `cancel` インタフェース内 `Cancelable`

    - #### isCancelRequested

          public boolean isCancelRequested()

      定義:
        `isCancelRequested` インタフェース内 `Cancelable`

    - #### getStackTrace

          public java.lang.StackTraceElement[] getStackTrace()

    - #### getAsynchronousStackTraceDump

          public java.util.List<AsyncTaskInfo> getAsynchronousStackTraceDump()

    - #### getAsynchronousStackTraceDumpAsString

          public java.lang.String getAsynchronousStackTraceDumpAsString()

    - #### getState

          public TryCatchFinally.State getState()

    - #### toString

          public java.lang.String toString()

      オーバーライド:
        `toString` クラス内 `java.lang.Object`

    - #### rethrow

          protected void rethrow(java.lang.Throwable e,
                     Promise<?>... waitFor)

    - #### doTry

          protected abstract void doTry()
                                 throws java.lang.Throwable

      例外:
        `java.lang.Throwable`

    - #### doCatch

          protected abstract void doCatch(java.lang.Throwable e)
                                   throws java.lang.Throwable

      例外:
        `java.lang.Throwable`

    - #### doFinally

          protected abstract void doFinally()
                                     throws java.lang.Throwable

      例外:
        `java.lang.Throwable`