1

关于我的 Amazon Simple Workflow / AWS Flow for Ruby 应用程序的架构,我有一个简单的问题。作为背景,我有一个简单的工作流,其中一个活动在 Opsworks 上的 AWS Flow for Ruby 层中运行。我有一个单独的 REST API 在 Opsworks 的 Rails App Server 层中运行,我想启动工作流。

启动工作流的 REST API 中的代码:

1: domain = AWS::SimpleWorkflow.new.domains['my_domain']
2: workflow_client = AWS::Flow::workflow_client(domain.client, domain) {{from_class: MyWorkflowClass}}
3: workflow_client.start_execution(input_1: @input1, input_2: @input2)

我的假设是我的工作流和 REST API 代码库可以是分开的,唯一的共同组件是aws-flowRuby gem 和require 'aws/decider'. 但是,我发现我的 REST API 也需要具有require 'PATH_TO_MY_WORKFLOW_CLASS'. 当我从启动工作流的 REST API 的代码文件中删除该行代码时,我收到以下错误:

undefined method `_options' for nil:NilClass; ["/Users/MyName/.rvm/gems/ruby-2.0.0-p247/gems/aws-flow-2.2.1/lib/aws/decider/utilities.rb:183:in `interpret_block_for_options'", "/Users/MyName/.rvm/gems/ruby-2.0.0-p247/gems/aws-flow-2.2.1/lib/aws/decider/implementation.rb:73:in `workflow_client'"
(error at line 2 above)

我弄错了吗?我真的需要在我的工作流启动应用程序(即我的 REST API)中要求 MyWorkflowClass 还是我做错了什么?我已经搜索了文档,但找不到明确的答案。我能找到的所有示例确实确实在工作流启动代码中包含了工作流类,但我不确定是因为它们被捆绑为一个简单的示例,还是因为它应该是这样的。我之所以不按面值抽取样本,是因为在工作流启动代码中要求工作流类对我来说没有任何意义。它将两个应用程序绑定得太紧,不符合我的口味。

4

1 回答 1

0

我在 aws-flow-ruby sdk 上发布了一个问题,并从亚马逊工程师那里得到了答案。简而言之,您可以将:from_class选项或:prefix_name:execution_method选项一起使用。


在代码中启动工作流有两种方式

1)直接使用aws sdk。在这种情况下,您的代码不需要了解有关工作流类的任何信息。您只需要域、工作流类型(名称和版本)和工作流 ID。它看起来像 -

require 'aws-sdk-v1'
swf = AWS::SimpleWorkflow.new.client
swf.start_workflow_execution(
  domain: "HelloWorld",
  workflow_type: {
    name: "HelloWorldWorkflow",
    version: "1.0"
  },
  workflow_id: "foo",
  input: ....,
  ....other options (optional)...
)

正如您在上面看到的,这根本不需要工作流类。

2)使用 aws-flow gem(这就是您在上面所做的)。有两种方法可以使用 aws-flow gem 提供的工作流客户端来开始执行。您可以将客户端用作通用客户端而不将其绑定到任何工作流类,也可以使用 :from_class 选项从特定工作流类中获取选项。要使用 from_class 选项,您需要在 ObjectSpace 中有类(因此您需要需要工作流文件)。

使用 from_class -

require 'aws/decider'
domain = AWS::SimpleWorkflow.new.domains['my_domain']
workflow_client = AWS::Flow::workflow_client(domain.client, domain) {{from_class: "MyWorkflowClass"}}
workflow_client.start_execution(input_1: @input1, input_2: @input2)

没有 from_class -

require 'aws/decider'
domain = AWS::SimpleWorkflow.new.domains['my_domain']
workflow_client = AWS::Flow::workflow_client(domain.client, domain) {{
  prefix_name: "YourClassName",
  execution_method: "workflow_method_name",
  version: "1.0",
  ...other options...
}}
workflow_client.start_execution(input_1: @input1, input_2: @input2)

启动工作流执行的推荐方法是使用 aws-flow WorkflowClient 而不是直接使用 SDK。


关于工作流接受的输入的附加说明:


SDK 和控制台只会将字符串作为输入。这可以是自由形式的字符串,但如果您的工作流是使用 ruby​​ 流编写的,则该字符串应该是输入的序列化形式,以便 WorkflowWorker 在接收任务并将其转换为 ruby​​ 对象时可以反序列化输入(在此大小写哈希)。

当您使用 ruby​​ 流程 WorkflowClient 时,客户端会自动将您的输入哈希(或任何其他输入)序列化为字符串,然后再将其发送到 SWF。aws-flow 默认使用基于 YAML 的数据转换器来执行此操作(它可以被覆盖)。

如果您只想查看输入哈希作为字符串的样子,您可以执行以下操作 -

AWS::Flow::FlowConstants.default_data_converter.dump(input_hash) 

然后,您可以使用此序列化输入通过 SDK 或控制台启动工作流。

于 2014-11-14T17:04:26.867 回答