在工作流入门代码中需要工作流类

时间:2014-11-11 04:06:53

标签: ruby-on-rails ruby amazon-web-services aws-opsworks amazon-swf

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

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-flow Ruby 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,或者我做错了什么?我已经仔细检查了文档,但未能找到明确的答案。我能找到的所有样本确实都包含工作流入门代码中包含的工作流程类,但我不确定它是否因为它们被捆绑为一个简单的样本或者它是否因为这是它应该的样子。我之所以不采用面值的原因是因为要求工作流入门代码中的工作流类对我没有任何意义。它根据我的口味将这两个应用程序绑定得太紧。

1 个答案:

答案 0 :(得分: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或控制台启动工作流程。