

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 对 Java AWS Flow Framework 的理解
<a name="concepts"></a>

f AWS Flow Framework or Java 与 Amazon SWF 配合使用，可以轻松创建可扩展和容错的应用程序，以执行可能长时间运行、远程或两者兼而有之的异步任务。“Hello World\$1”示例 中的示例[Java 的 AWS Flow Framework 用法是什么？](welcome.md)介绍了如何使用 AWS Flow Framework 来实现基本工作流应用程序的基础知识。本节提供有关 AWS Flow Framework 应用程序工作原理的概念性信息。第一部分概述了 AWS Flow Framework 应用程序的基本结构，其余部分则进一步详细介绍了 AWS Flow Framework 应用程序的工作原理。

**Topics**
+ [应用程序结构](awsflow-basics-application-structure.md)
+ [可靠执行](awsflow-basics-reliable-execution.md)
+ [分布式执行](awsflow-basics-distributed-execution.md)
+ [任务列表和任务执行](awsflow-basics-task-lists.md)
+ [可扩展应用程序](awsflow-basics-scalable.md)
+ [活动与工作流之间的数据交换](awsflow-basics-data-exchange-activities-workflows.md)
+ [在应用程序和工作流程执行之间交换数据](awsflow-basics-data-exchange-workflows-application.md)
+ [超时类型](swf-timeout-types.md)

# AWS Flow Framework 基本概念：应用程序结构
<a name="awsflow-basics-application-structure"></a>

从概念上讲， AWS Flow Framework 应用程序由三个基本组件组成：*工作流启动器*、*工作流程工作人员*和*活动*工作者。一个或多个主机应用程序负责向 Amazon SWF 注册工作线程（工作流和活动）、启动工作线程和处理清理。工作线程处理执行工作流程的机制，可以在几个主机上实现工作线程。

下图代表了一个基本的 AWS Flow Framework 应用程序：

![\[原理图 AWS Flow Framework 应用程序\]](http://docs.aws.amazon.com/zh_cn/amazonswf/latest/awsflowguide/images/swf-application-model.png)


**注意**  
从概念上讲，在三个单独的应用程序中实现这些组件是非常方便的，但您可以通过多种方式创建应用程序以实现该功能。例如，您可以在活动和工作流程工作线程中使用单个主机应用程序，或者使用单独的活动和工作流程主机。也可以使用多个活动工作线程，每个工作线程在单独的主机上处理一组不同的的活动，等等。

这三个 AWS Flow Framework 组件通过向管理请求的 Amazon SWF 发送 HTTP 请求来间接交互。Amazon SWF 将执行以下操作：
+ 保留一个或多个决策任务列表，这些列表确定工作流程工作线程要执行的下一步骤。
+ 保留一个或多个活动任务列表，这些列表确定活动工作线程将执行的任务。
+ 维护工作流程执行的详细 step-by-step历史记录。

使用后 AWS Flow Framework，您的应用程序代码无需直接处理图中所示的许多细节，例如向 Amazon SWF 发送 HTTP 请求。你只需调用 AWS Flow Framework 方法，框架就会处理幕后的细节。

## 活动工作线程角色
<a name="aws-flow-concepts-activity-worker"></a>

活动工作线程执行工作流程必须完成的各种任务。它包含以下内容：
+ 活动实现，它包含一组为工作流程执行特定任务的活动方法。
+ 一个[ActivityWorker](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/flow/ActivityWorker.html)对象，它使用 HTTP 长轮询请求来轮询 Amazon SWF 以确定要执行的活动任务。需要执行任务时，Amazon SWF 通过发送执行任务所需的信息来响应请求。然后，该[ActivityWorker](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/flow/ActivityWorker.html)对象调用相应的活动方法，并将结果返回给 Amazon SWF。

## 工作流程工作线程角色
<a name="aws-flow-concepts-workflow-worker"></a>

工作流程工作线程协调各种活动的执行情况，管理数据流以及处理失败的活动。它包含以下内容：
+ 工作流程实现，它包含活动协调逻辑，处理失败的活动，等等。
+ 活动客户端，它作为活动工作线程的代理，并允许工作流程工作线程计划要异步执行的活动。
+ 一个[WorkflowWorker](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/flow/WorkflowWorker.html)对象，它使用 HTTP 长轮询请求轮询 Amazon SWF 以执行决策任务。如果工作流任务列表上具有任务，Amazon SWF 将通过返回执行任务所需的信息来响应请求。然后，该框架会执行工作流以执行任务，并将结果返回到 Amazon SWF。

## 工作流程启动程序角色
<a name="aws-flow-concepts-workflow-starter"></a>

工作流程启动程序启动工作流程实例 (也称为*工作流程执行*)，并且可以在执行期间与实例交互，以便将额外数据传递给工作流程工作线程或获取当前工作流程状态。

工作流程启动程序使用工作流程客户端启动工作流程执行，在执行期间根据需要与工作流程交互以及处理清理。工作流程启动器可以是本地运行的应用程序、Web 应用程序， AWS CLI 甚至. AWS 管理控制台

## Amazon SWF 如何与您的应用程序交互
<a name="aws-flow-concepts-swf-app-interaction"></a>

Amazon SWF 负责协调工作流组件之间的交互，并维护详细的工作流历史记录。Amazon SWF 不会启动与组件的通信，它会等待来自组件的 HTTP 请求，并根据需要管理这些请求。例如：
+ 如果请求来自工作线程，目的是轮询以获取可用的任务，则 Amazon SWF 会在任务可用时直接响应工作线程。有关长轮询的更多信息，请参阅 *Amazon Simple Workflow Service Developer Guide* 中的 [Long Polling](https://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dg-basic.html#swf-dev-comm-proto)。
+ 如果请求是活动工作线程发出的说明任务已完成的通知，Amazon SWF 会将该信息记录在执行历史记录中，并在决策任务列表中添加一个任务，以通知工作流工作线程任务已完成，可以继续执行下一步骤。
+ 如果请求是工作流工作线程发出的，指示执行活动，Amazon SWF 会将该信息记录在执行历史记录中，并在活动任务列表中添加一个任务，以指示活动工作线程执行相应的活动方法。

这种方法允许工作人员在任何有互联网连接的系统上运行，包括 Amazon EC2 实例、公司数据中心、客户端计算机等。它们甚至不必运行相同的操作系统。由于 HTTP 请求来自于工作线程，因此，不需要使用外部可见的端口；工作线程可以在防火墙后面运行。

## 了解更多信息
<a name="for-more-information"></a>

有关对 Amazon SWF 工作原理的更深入讨论，请参阅 [Amazon Simple Workflow Service Developer Guide](https://docs.aws.amazon.com/amazonswf/latest/developerguide/)。

# AWS Flow Framework 基本概念：可靠执行
<a name="awsflow-basics-reliable-execution"></a>

异步分布式应用程序必须处理常规应用程序不会遇到的可靠性问题，包括：
+ 如何在异步分布式组件之间*提供可靠通信*，如在远程系统上长时间运行的组件。
+ 如何在组件故障或断开连接时*确保结果不会丢失*，特别是长时间运行的应用程序。
+ 如何*处理故障的分布式组件*。

应用程序可以依靠 AWS Flow Framework 和 Amazon SWF 来管理这些问题。我们将探讨 Amazon SWF 如何提供一些机制来确保工作流以可靠且可预测的方式运行，即使这些工作流长时间运行并依赖通过计算和人机交互执行的异步任务。

## 提供可靠的通信
<a name="awsflow-basics-reliable-execution-communication"></a>

AWS Flow Framework 使用 Amazon SWF 向分布式活动工作人员分派任务并将结果返回给工作流程工作人员，从而在工作流程工作人员与其活动工作人员之间提供可靠的通信。Amazon SWF 使用以下方法来确保工作线程及其活动之间的可靠通信：
+ Amazon SWF 可持久存储安排的活动和工作流任务，并确保它们最多执行一次。
+ Amazon SWF 可确保活动任务要么成功完成并返回有效结果，要么通知工作流工作线程任务失败。
+ Amazon SWF 可持久存储每个已完成的活动的结果，对于失败的活动，它还将存储相关的错误信息。

 AWS Flow Framework 然后，使用来自 Amazon SWF 的活动结果来确定如何继续执行工作流程。

## 确保结果不会丢失
<a name="awsflow-basics-reliable-execution-history"></a>

### 保留工作流程历史记录
<a name="maintaining-workflow-history"></a>

对 PB 级数据执行数据挖掘操作的活动可能需要*几小时*才能完成；指示工作人员执行复杂任务的活动可能需要*几天*甚至*几周*才能完成！

为了适应此类场景， AWS Flow Framework 工作流程和活动可能需要任意长时间才能完成：工作流程*的执行上限为一年*。要可靠地执行长时间运行的进程，需要采用某种机制以持续永久存储工作流程的执行历史记录。

通过依赖 Amazon SWF 来 AWS Flow Framework 处理这个问题，Amazon SWF 会维护每个工作流程实例的运行历史记录。工作流程的历史记录提供了工作流程进度的完整且权威的记录，包括已计划并完成的所有工作流程和活动任务以及完成或失败的活动返回的信息。

AWS Flow Framework 应用程序通常不需要直接与工作流程历史进行交互，但它们可以在必要时访问它。对于大多数用途，应用程序可以直接让该框架在后台与工作流程历史记录进行交互。有关工作流历史记录的全面讨论，请参阅 *Amazon Simple Workflow Service Developer Guide* 中的 [Workflow History](https://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dg-basic.html#swf-dev-about-workflow-history)。

### 无状态执行
<a name="stateless-execution"></a>

执行历史记录允许工作流程工作线程是*无状态*的。如果具有多个工作流程或活动工作线程实例，则任何工作线程可以执行任何任务。工作线程会从 Amazon SWF 接收执行任务所需的所有状态信息。

该方法使工作流程变得更可靠。例如，如果某个活动工作线程失败，您不必重新启动工作流程。只需重新启动工作线程，它将开始轮询任务列表并处理列表上的任何任务，不受失败何时发生的影响。您可以使用两个或更多工作流程和活动工作线程 (可能在不同的系统上)，以使整个工作流程具有容错功能。然后，如果一个工作线程失败，其他工作线程继续处理计划任务，工作流程进度不会发生任何中断。

## 处理故障的分布式组件
<a name="awsflow-basics-reliable-execution-errors"></a>

活动通常由于临时原因而失败 (如短暂断开连接)，因此，处理失败活动的常见策略是重试活动。应用程序可以依赖 AWS Flow Framework，而不是通过实施复杂的消息传送策略来处理重试过程。它提供了几种机制以重试失败的活动，并提供内置异常处理机制以处理工作流程中的任务的异步分布式执行。

# AWS Flow Framework 基本概念：分布式执行
<a name="awsflow-basics-distributed-execution"></a>

*工作流实例*本质上是一个虚拟执行线程，可以跨越多台远程计算机上运行的活动和协调逻辑。Amazon SWF 以及作为操作系统的 AWS Flow Framework 功能，通过以下方式管理虚拟 CPU 上的工作流程实例：
+ 保留每个实例的执行状态。
+ 在实例之间切换。
+ 从切换位置恢复执行实例。

## 重播工作流程
<a name="replaying-workflows"></a>

由于活动可能长时间运行，最好不要在完成之前直接阻止工作流程。取而代之的是，使用*重播*机制来 AWS Flow Framework 管理工作流程的执行，该机制依靠由 Amazon SWF 维护的工作流程历史记录来分集执行工作流程。

每个阶段以某种方式重播工作流程逻辑，以便*仅执行一次每个活动*，并确保在其 [Promise](awsflow-basics-data-exchange-activities-workflows.md) 对象准备就绪后才执行活动和异步方法。

在启动工作流程执行时，工作流程启动程序启动第一个重播阶段。该框架调用工作流程的入口点方法，并且：

1. 执行所有不依赖于活动完成的工作流程任务，包括调用所有活动客户端方法。

1. 为 Amazon SWF 提供一个安排执行的活动任务列表。对于第一个阶段，该列表仅包含不依赖于 Promise 并且可立即执行的活动。

1. 通知 Amazon SWF 该阶段已完成。

Amazon SWF 会在工作流历史记录中存储活动任务，并通过将其放在活动任务列表中来安排执行。活动工作线程轮询任务列表并执行这些任务。

活动工作线程完成任务后，会将结果返回给 Amazon SWF，Amazon SWF 在工作流执行历史记录中记录该结果，并将其放在工作流任务列表中，以便为工作流工作线程安排新的工作流任务。工作流程工作线程轮询任务列表，并在收到该任务时运行下一个重播阶段，如下所示：

1. 该框架再次运行工作流程的入口点方法，并且：
   + 执行所有不依赖于活动完成的工作流程任务，包括调用所有活动客户端方法。不过，该框架检查执行历史记录，并且不会计划重复的活动任务。
   + 检查历史记录以查看哪些活动任务已完成，并执行依赖于这些活动的任何异步工作流程方法。

1. 在所有可执行的工作流任务都已完成后，该框架会向 Amazon SWF 报告：
   + 它会向 Amazon SWF 提供一份清单，列出自上一阶段以来输入 `Promise<T>` 对象已准备就绪并可安排执行的所有活动。
   + 如果该阶段没有生成任何额外的活动任务，但仍有未完成的活动，则框架会通知 Amazon SWF 该阶段已完成。然后，它等待另一个活动完成，从而启动下一个重播阶段。
   + 如果该阶段没有生成任何额外的活动任务，且所有活动都已完成，则框架会通知 Amazon SWF 工作流执行已完成。

有关重播行为的示例，请参阅[AWS Flow Framework 适用于 Java 重播行为](programming-replay.md)。

## 重播和异步工作流程方法
<a name="awsflow-basics-distributed-execution-async"></a>

异步工作流程方法的使用方式通常与活动非常相似，因为方法推迟执行，直到所有输入 `Promise<T>` 对象准备就绪。不过，重播机制处理异步方法的方式与活动不同。
+ 重播不保证异步方法仅执行一次。它推迟异步方法执行，直到其输入 Promise 对象准备就绪，但它为所有后续阶段执行该方法。
+ 在异步方法完成时，它不会启动新的阶段。

在[AWS Flow Framework 适用于 Java 重播行为](programming-replay.md)中提供了重播异步工作流程的示例。

## 重播和工作流程实现
<a name="awsflow-basics-distributed-execution-impl"></a>

在很大程度上，您不需要关注重播机制的细节。它基本上是在后台执行的操作。不过，重播对您的工作流程实现有两个重大影响。
+ 不要使用工作流程方法执行长时间运行的任务，因为重播将重复执行多次该任务。甚至异步工作流程方法通常也会运行多次。应使用活动执行长时间运行的任务；重播仅执行一次活动。
+ 您的工作流程逻辑必须是完全确定性的；每个阶段必须采用相同的控制流程路径。例如，控制流程路径不应依赖于当前时间。有关重播和确定性要求的详细说明，请参阅[不确定性](details.md#details.non)。

# AWS Flow Framework 基本概念：任务列表和任务执行
<a name="awsflow-basics-task-lists"></a>

 Amazon SWF 通过将工作流和活动任务发布到指定列表来管理它们。Amazon SWF 维护至少两个任务列表，一个用于工作流工作线程，另一个用于活动工作线程。

**注意**  
您可以根据需要指定任意数量的任务列表，将为每个列表分配不同的工作线程。对任务列表的数量没有任何限制。您通常在创建工作线程对象时在工作线程主机应用程序中指定工作线程的任务列表。

以下来自 `HelloWorldWorkflow` 主机应用程序的摘录创建新的活动工作线程并将其分配给 `HelloWorldList` 活动任务列表。

```
public class GreeterWorker  {
    public static void main(String[] args) throws Exception {
    ...
    String domain = " helloWorldExamples";
    String taskListToPoll = "HelloWorldList";

    ActivityWorker aw = new ActivityWorker(service, domain, taskListToPoll);
    aw.addActivitiesImplementation(new GreeterActivitiesImpl());
    aw.start();
    ...
  }
}
```

默认情况下，Amazon SWF 在 `HelloWorldList` 列表中安排工作线程的任务。然后工作线程轮询该列表中的任务。您可以向任务列表分配任何名称。您甚至可以对工作流和活动列表使用相同的名称。在内部，Amazon SWF 将工作流和活动任务列表的名称放在不同的命名空间中，因此这两个列表是不同的。

如果您未指定任务列表，则会 AWS Flow Framework 指定工作人员向 Amazon SWF 注册该类型时的默认列表。有关更多信息，请参阅 [工作流程和活动类型注册](features.registration.md)。

有时让一个特定工作线程或一组工作线程执行某些任务非常有用。例如，图像处理工作流可能使用一个活动来下载图像并使用另一个活动来处理该图像。在同一个系统上执行这两个任务会更高效，并可避免通过网络传输大型文件的开销。

要支持此类情况，您可以在调用活动客户端方法时使用包括 `schedulingOptions` 参数的重载显式指定任务列表。您可以通过向方法传递一个经过适当配置的`ActivitySchedulingOptions`对象来指定任务列表。

例如，假设 `HelloWorldWorkflow` 应用程序的 `say` 活动由不同于 `getName` 和 `getGreeting` 的活动工作线程托管。以下示例演示如何确保 `say` 使用与 `getName` 和 `getGreeting` 相同的任务列表，即使它们最初分配到了不同的列表。

```
public class GreeterWorkflowImpl implements GreeterWorkflow {
  private GreeterActivitiesClient operations1 = new GreeterActivitiesClientImpl1(); //getGreeting and getName
  private GreeterActivitiesClient operations2 = new GreeterActivitiesClientImpl2(); //say
  @Override
  public void greet() {
    Promise<String> name = operations1.getName();
    Promise<String> greeting = operations1.getGreeting(name);
    runSay(greeting);
  }
  @Asynchronous
  private void runSay(Promise<String> greeting){
    String taskList = operations1.getSchedulingOptions().getTaskList();
    ActivitySchedulingOptions schedulingOptions = new ActivitySchedulingOptions();
    schedulingOptions.setTaskList(taskList);
    operations2.say(greeting, schedulingOptions);
  }
}
```

异步 `runSay` 方法从其客户端对象获取 `getGreeting` 任务列表。然后它创建并配置 `ActivitySchedulingOptions` 对象，该对象确保 `say` 轮询与 `getGreeting` 相同的任务列表。

**注意**  
当您将 `schedulingOptions` 参数传递给活动客户端方法时，它会仅针对该活动执行覆盖原始任务列表。如果您在未指定任务列表的情况下再次调用活动客户端方法，Amazon SWF 会将任务分配给原始列表，且活动工作线程将轮询该列表。

# AWS Flow Framework 基本概念：可扩展应用程序
<a name="awsflow-basics-scalable"></a>

Amazon SWF 具有两项重要功能，可以轻松扩展工作流应用程序以处理当前负载：
+ 完整的工作流程执行历史记录；您可以实现无状态的应用程序。
+ 松散耦合到任务执行的任务计划；可以轻松扩展应用程序以满足当前需求。

Amazon SWF 通过将任务发布到动态分配的任务列表（而不是直接与工作流和活动工作线程通信）来安排任务。相反，工作线程使用 HTTP 请求轮询相应的列表以查找任务。这种方法将任务调度与任务执行松散地结合在一起，并允许工作人员在任何合适的系统上运行，包括 Amazon EC2 实例、公司数据中心、客户端计算机等。由于 HTTP 请求来自工作程序，因此不需要外部可见的端口，这使得工作人员甚至可以在防火墙后面运行。

工作线程用于轮询任务的长轮询机制确保工作线程不会过载。即使在计划任务中出现峰值，工作线程也会按自己的频率提取任务。不过，由于工作线程是无状态的，您可以启动额外的工作线程实例，以便动态扩展应用程序以满足增加的负载要求。即使它们在不同的系统上运行，每个实例也会轮询相同的任务列表，并且第一个可用的工作线程实例执行每个任务，而无论工作线程位于何处或何时启动。在负载下降时，您可以相应地降低工作线程数。

# AWS Flow Framework 基本概念：活动和工作流之间的数据交换
<a name="awsflow-basics-data-exchange-activities-workflows"></a>

在您调用异步活动客户端方法时，它会立即返回 *Promise* (又称为 *Future*) 对象，这表示活动方法的返回值。最初，Promise 处于未就绪状态，并且未定义返回值。在活动方法完成其任务并返回后，框架跨网络将返回值封送给工作流工作线程，后者为 Promise 分配一个值并将对象置于就绪状态。

即使活动方法没有返回值，您仍可以使用 Promise 来管理工作流执行。如果您将返回的 Promise 传递给活动客户端方法或异步工作流方法，则会推迟执行，直至对象准备就绪。

如果您将一个或多个 Promise 传递给活动客户端方法，则框架会使任务排队，但推迟安排它，直到所有对象都准备就绪。然后，它从每个 Promise 提取数据并跨 Internet 将其封送给活动工作线程，后者将其作为标准类型传递给活动方法。

**注意**  
如果您需要在工作流与活动工作线程之间传输大量数据，首选方法是将数据存储在方便的位置，然后仅传递检索信息。例如，您可以将数据存储在 Amazon S3 存储桶中并传递关联的 URL。

## 承诺 <T> 类型
<a name="awsflow-basics-data-exchange-activities-workflows.promise"></a>

`Promise<T>` 类型在一些方面与 Java `Future<T>` 类型非常类似。这两种类型都表示异步方法返回的值，并且最初都未定义。您通过调用它的 `get` 方法来访问对象的值。除此之外，这两种类型的行为截然不同。
+ `Future<T>` 是一个异步构造，它允许应用程序等待异步方法完成。如果您调用 `get`，但对象未准备就绪，则它会阻止，直到对象已准备就绪。
+ 对于 `Promise<T>`，同步由框架处理。如果您调用 `get`，但对象未准备就绪，则 `get` 会引发异常。

`Promise<T>` 的主要用途是管理从一个活动到另一个活动的数据流。它确保直到输入数据都有效后才执行活动。在许多情况下，工作流工作线程无需直接访问 `Promise<T>` 对象；它们只需将对象从一个活动传递给另一个活动，然后让框架和活动工作线程处理详细信息。要在工作流工作线程中访问 `Promise<T>` 对象的值，您必须在调用其 `get` 方法之前确定对象已准备就绪。
+ 首选方法是将 `Promise<T>` 对象传递给异步工作流方法并在那里处理值。异步方法将推迟执行，直到其所有输入 `Promise<T>` 对象都已准备就绪，这保证您可以安全地访问它们的值。
+ `Promise<T>` 公开 `isReady` 方法，如果对象已准备就绪，则该方法会返回 `true`。不建议使用 `isReady` 来轮询 `Promise<T>` 对象，但 `isReady` 在某些情况下非常有用。

f AWS Flow Framework or Java 还包括一个`Settable<T>`类型，该类型派生自`Promise<T>`并具有相似的行为。不同之处在于，框架通常设置`Promise<T>`对象的值，而工作流程工作人员负责设置对象的值`Settable<T>`。

在一些情况下，工作流工作线程需要创建 `Promise<T>` 对象并设置其值。例如，返回 `Promise<T>` 对象的异步方法需要创建返回值。
+ 要创建表示类型化值的对象，请调用静态 `Promise.asPromise` 方法，该方法创建适当类型的 `Promise<T>` 对象，设置其值，然后将其置于就绪状态。
+ 要创建 `Promise<Void>` 对象，请调用静态 `Promise.Void` 方法。

**注意**  
`Promise<T>` 可以表示任何有效类型。但是，如果必须跨 Internet 封送数据，则类型必须与数据转换器兼容。有关详细信息，请参阅下一节。

## 数据转换器和封送
<a name="awsflow-basics-data-exchange-activities-workflows.data"></a>

使用 AWS Flow Framework 数据转换器整理互联网上的数据。默认情况下，框架使用基于 [Jackson JSON 处理器](https://github.com/codehaus/jackson)的数据转换器。但是，此转换器具有一些限制。例如，它无法封送不使用字符串作为键的映射。如果默认转换器对您的应用程序来说不合适，您可以实现自定义数据转换器。有关详细信息，请参阅[DataConverters](dataconverters.md)。

# AWS Flow Framework 基本概念：应用程序和工作流程执行之间的数据交换
<a name="awsflow-basics-data-exchange-workflows-application"></a>

工作流程入口点方法可能具有一个或多个参数，这允许工作流程启动程序将初始数据传递给工作流程。要在执行期间为工作流程提供额外数据，这也是非常有用的。例如，如果客户更改其送货地址，您可以通知订单处理工作流程，以便它可以进行相应的更改。

Amazon SWF 允许工作流实现*信号*方法，这允许应用程序（如工作流启动程序）随时将数据传递给工作流。信号方法可能具有任何方便的名称和参数。您可以将其包含在工作流程接口定义中，并将 `@Signal` 注释应用于方法声明以将其指定为信号方法。

以下示例显示一个声明信号方法 `changeOrder` 的订单处理工作流程接口，这允许工作流程启动程序在工作流程启动后更改原始订单。

```
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 300)
public interface WaitForSignalWorkflow {
    @Execute(version = "1.0")
    public void placeOrder(int amount);
    @Signal
    public void changeOrder(int amount);
}
```

该框架的注释处理器创建一个具有与信号方法相同的名称的工作流程客户端方法，并且工作流程启动程序调用该客户端方法以将数据传递给工作流程。有关示例，请参阅 [AWS Flow Framework Recipes](https://aws.amazon.com/code/2535278400103493)

# Amazon SWF 超时类型
<a name="swf-timeout-types"></a>

为确保工作流程执行正常运行，您可以使用 Amazon SWF 设置不同类型的超时。一些超时指定工作流程的总运行时长。其它超时指定活动任务在被分配给工作程序之前所花费的时间以及从排定到完成所花费的时间。Amazon SWF API 中的所有超时都以秒为单位。Amazon SWF 还支持将字符串 `NONE` 作为超时值，表示没有超时。

对于与决策任务和活动任务相关的超时，Amazon SWF 会在工作流执行历史中添加一个事件。事件的属性提供了所发生超时类型的信息以及以及受影响的决策任务或活动任务。Amazon SWF 还会计划决策任务。当决策者收到新的决策任务时，它将在历史记录中看到超时事件，并通过调用操作来采取适当的[RespondDecisionTaskCompleted](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondDecisionTaskCompleted.html)行动。

任务被视为从排定时开始到其关闭为止都处于开启状态。因此，当工作程序处理任务时，任务被报告为开启状态。当工作程序将任务状态报告为[已完成](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondActivityTaskCompleted.html)、[已取消](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondActivityTaskCanceled.html)或[失败](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondActivityTaskFailed.html)时，任务关闭。Amazon SWF 也可能会因超时而关闭任务。

## 工作流程和决策任务中的超时
<a name="swf-timeout-types-workflow"></a>

下图显示工作流程和决策超时如何与工作流程的生命周期相关：

![\[工作流程的生命周期，具有超时。\]](http://docs.aws.amazon.com/zh_cn/amazonswf/latest/awsflowguide/images/workflow_timeouts.png)


与工作流程和决策任务相关的超时类型有两个：
+ **工作流启动到关闭 (`timeoutType: START_TO_CLOSE`)** - 该超时指定了完成工作流执行所需的最长时间。工作流程注册期间，这一超时被设置为默认值，但当工作流程启动时，可用其它值覆盖该默认值。如果超过此超时时间，Amazon SWF 将关闭工作流程执行并在工作流程执行历史中[WorkflowExecutionTimedOut](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_WorkflowExecutionTimedOutEventAttributes.html)添加类型[的事件](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_HistoryEvent.html)。除了 `timeoutType` 之外，事件属性还会指定对此工作流程执行有效的 `childPolicy`。子策略指定上级工作流程执行超时或终止时子工作流程执行的处理方法。例如，如果 `childPolicy` 被设置为 TERMINATE，则子工作流程执行将被终止。一旦工作流程执行超时，则不能对其执行可视性调用之外的其他任何操作。
+ **决策任务启动到关闭 (`timeoutType: START_TO_CLOSE`)** – 该超时指定了相应决策程序完成决策任务所需的最长时间。该超时在工作流程类型注册期间设置。如果超过此超时时间，则任务将在工作流程执行历史中标记为超时，Amazon SWF 会在工作流程历史记录中添加[DecisionTaskTimedOut](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_DecisionTaskTimedOutEventAttributes.html)类型的事件。事件属性将包括与该决策任务 IDs 的计划时间 (`scheduledEventId`) 和启动时间 () 相对应的事件。`startedEventId`除了添加事件外，Amazon SWF 还会计划新决策任务以警告决策程序此决策任务已超时。此超时发生后，使用 `RespondDecisionTaskCompleted` 完成超时决策任务的尝试将失败。

## 活动任务中的超时
<a name="swf-timeout-types-activity"></a>

下图显示超时如何与活动任务的生命周期相关：

![\[任务的生命周期，具有超时\]](http://docs.aws.amazon.com/zh_cn/amazonswf/latest/awsflowguide/images/activity_timeouts.png)


与活动任务相关的超时类型有四个：
+ **活动任务启动到关闭 (`timeoutType: START_TO_CLOSE`)** – 该超时指定了活动工作线在接收到任务后处理任务所需的最长时间。尝试使用[RespondActivityTaskCanceled](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondActivityTaskCanceled.html)、[RespondActivityTaskCompleted](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondActivityTaskCompleted.html)和关闭超时活动任务[RespondActivityTaskFailed](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondActivityTaskFailed.html)将失败。
+ **活动任务检测信号 (`timeoutType: HEARTBEAT`)** – 该超时指定了任务在通过 操作提供其进程前可以运行的最长时间。
+ **活动任务计划到开始 (`timeoutType: SCHEDULE_TO_START`)** – 该超时指定了在没有工作线执行活动任务时 Amazon SWF 在活动任务超时前等待的时间。一旦超时，过期的任务就不能分配给另一工作程序。
+ **活动任务安排到关闭 (`timeoutType: SCHEDULE_TO_CLOSE`)** – 该超时指定了任务从计划到完成所需的时间。作为最佳实践，此值不应大于任务 schedule-to-start超时和任务超时之和。 start-to-close

**注意**  
每一个超时类型都有默认值，一般设置为 `NONE` (无限)。但是任何活动执行的最长时间均被限制为一年。

您在活动类型注册期间设置这些活动的默认值，但当您[排定](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_ScheduleActivityTaskDecisionAttributes.html)活动任务时您可以用新值覆盖默认值。当其中一个超时发生时，Amazon SWF 将在工作流程历史[记录中添加一个[ActivityTaskTimedOut](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_ActivityTaskTimedOutEventAttributes.html)](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_HistoryEvent.html)类型的事件。此事件的 `timeoutType` 值属性将指定发生了何种超时。对于其中每一个超时，`timeoutType` 的值都显示在括号中。事件属性还将包括与活动任务的 IDs 计划时间 (`scheduledEventId`) 和启动时间 () 相对应的事件。`startedEventId`除了添加事件外，Amazon SWF 还会计划新决策任务以警告决策程序已发生超时。