aws-flow 2.3.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/aws-flow.gemspec +3 -2
- data/bin/aws-flow-ruby +1 -1
- data/bin/aws-flow-utils +5 -0
- data/lib/aws/decider.rb +7 -0
- data/lib/aws/decider/async_retrying_executor.rb +1 -1
- data/lib/aws/decider/data_converter.rb +161 -0
- data/lib/aws/decider/decider.rb +27 -14
- data/lib/aws/decider/flow_defaults.rb +28 -0
- data/lib/aws/decider/implementation.rb +0 -1
- data/lib/aws/decider/options.rb +2 -2
- data/lib/aws/decider/starter.rb +207 -0
- data/lib/aws/decider/task_poller.rb +4 -4
- data/lib/aws/decider/utilities.rb +38 -0
- data/lib/aws/decider/version.rb +1 -1
- data/lib/aws/decider/worker.rb +8 -7
- data/lib/aws/decider/workflow_definition_factory.rb +1 -1
- data/lib/aws/runner.rb +146 -65
- data/lib/aws/templates.rb +4 -0
- data/lib/aws/templates/activity.rb +69 -0
- data/lib/aws/templates/base.rb +87 -0
- data/lib/aws/templates/default.rb +146 -0
- data/lib/aws/templates/starter.rb +256 -0
- data/lib/aws/utils.rb +270 -0
- data/spec/aws/decider/integration/activity_spec.rb +7 -1
- data/spec/aws/decider/integration/data_converter_spec.rb +39 -0
- data/spec/aws/decider/integration/integration_spec.rb +12 -5
- data/spec/aws/decider/integration/options_spec.rb +23 -9
- data/spec/aws/decider/integration/starter_spec.rb +209 -0
- data/spec/aws/decider/unit/data_converter_spec.rb +276 -0
- data/spec/aws/decider/unit/decider_spec.rb +1360 -1386
- data/spec/aws/decider/unit/options_spec.rb +21 -22
- data/spec/aws/decider/unit/retry_spec.rb +8 -0
- data/spec/aws/decider/unit/starter_spec.rb +159 -0
- data/spec/aws/runner/integration/runner_integration_spec.rb +2 -3
- data/spec/aws/runner/unit/runner_unit_spec.rb +128 -38
- data/spec/aws/templates/unit/activity_spec.rb +89 -0
- data/spec/aws/templates/unit/base_spec.rb +72 -0
- data/spec/aws/templates/unit/default_spec.rb +141 -0
- data/spec/aws/templates/unit/starter_spec.rb +271 -0
- data/spec/spec_helper.rb +9 -11
- metadata +41 -4
@@ -0,0 +1,69 @@
|
|
1
|
+
module AWS
|
2
|
+
module Flow
|
3
|
+
module Templates
|
4
|
+
|
5
|
+
# This template represents an Activity in SWF. It holds the name and
|
6
|
+
# scheduling options for the activity
|
7
|
+
class ActivityTemplate < TemplateBase
|
8
|
+
attr_reader :name, :options
|
9
|
+
|
10
|
+
def initialize(name, opts = {})
|
11
|
+
options = opts.dup
|
12
|
+
# Split the name into prefix name and activity method
|
13
|
+
prefix_name, @name = name.split(".")
|
14
|
+
|
15
|
+
# Raise if we don't have a fully qualified name for the activity
|
16
|
+
raise ArgumentError, "Activity name should be fully qualified: "\
|
17
|
+
"<prefix_name>.<activity_method>" unless @name
|
18
|
+
|
19
|
+
# Get all the property keys from the ActivityOptions class
|
20
|
+
keys = ActivityOptions.held_properties.push(:exponential_retry)
|
21
|
+
|
22
|
+
# Only select the options that are needed
|
23
|
+
options.select!{ |x| keys.include?(x) }
|
24
|
+
|
25
|
+
# Merge in default values for the activity in case they are not passed
|
26
|
+
# by the user
|
27
|
+
options = {
|
28
|
+
version: FlowConstants.defaults[:version],
|
29
|
+
prefix_name: "#{prefix_name}",
|
30
|
+
data_converter: FlowConstants.defaults[:data_converter],
|
31
|
+
exponential_retry: FlowConstants.defaults[:retry_policy]
|
32
|
+
}.merge(options)
|
33
|
+
|
34
|
+
@options = options
|
35
|
+
end
|
36
|
+
|
37
|
+
# Uses the ActivityClient given in the context (workflow class) passed
|
38
|
+
# in by the calling template to schedule this activity
|
39
|
+
def run(input, context)
|
40
|
+
# Get a duplicate of the options hash so as not to change what's
|
41
|
+
# stored in this object
|
42
|
+
options = @options.dup
|
43
|
+
# If a :tasklist key is passed as input to this template, then schedule
|
44
|
+
# this activity on that tasklist
|
45
|
+
if input.is_a?(Hash) && input[:task_list]
|
46
|
+
options.merge!(task_list: input[:task_list])
|
47
|
+
end
|
48
|
+
# Schedule the activity using the ActivityClient in the context
|
49
|
+
context.act_client.send(@name, input) { options }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Initializes an activity template
|
54
|
+
# @param {String} name
|
55
|
+
# @param {Hash} options
|
56
|
+
def activity(name, opts = {})
|
57
|
+
AWS::Flow::Templates.send(:activity, name, opts)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Initializes an activity template
|
61
|
+
# @param {String} name
|
62
|
+
# @param {Hash} options
|
63
|
+
def self.activity(name, opts = {})
|
64
|
+
ActivityTemplate.new(name, opts)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module AWS
|
2
|
+
module Flow
|
3
|
+
module Templates
|
4
|
+
|
5
|
+
# A Template is a precanned workflow definition that can be combined with
|
6
|
+
# other templates to construct a workflow body. TemplateBase is a class
|
7
|
+
# that must be inherited by all templates. It provides the 'abstract'
|
8
|
+
# method #run that needs to be implemented by subclasses.
|
9
|
+
class TemplateBase
|
10
|
+
|
11
|
+
# This method needs to be implemented by the sub classes.
|
12
|
+
# @param {Hash} input
|
13
|
+
# This is the input to the template
|
14
|
+
# @param {AWS::Flow::Workflows} context
|
15
|
+
# A class that extends AWS::Flow::Workflows. The workflow that runs a
|
16
|
+
# template passes itself as an argument to provide the template with
|
17
|
+
# the right context to execute in.
|
18
|
+
def run(input, context)
|
19
|
+
raise NotImplementedError, "Please implement the #run method of your template."
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
# Root template is the top level template that is sent to a workflow to
|
25
|
+
# run. It contains a step (which is another template) that it passes the
|
26
|
+
# input and the context to. It also contains a result_step that it uses to
|
27
|
+
# report the result of the workflow.
|
28
|
+
class RootTemplate < TemplateBase
|
29
|
+
attr_reader :step, :input
|
30
|
+
attr_accessor :result_step
|
31
|
+
|
32
|
+
def initialize(step, result_step)
|
33
|
+
@step = step
|
34
|
+
@result_step = result_step
|
35
|
+
end
|
36
|
+
|
37
|
+
# Calls the run method on the step (top level template). Manages overall
|
38
|
+
# error handling and reporting of results for the workflow
|
39
|
+
def run(input, context)
|
40
|
+
result = nil
|
41
|
+
failure = nil
|
42
|
+
begin
|
43
|
+
result = @step.run(input, context)
|
44
|
+
rescue Exception => e
|
45
|
+
failure = e
|
46
|
+
ensure
|
47
|
+
if failure
|
48
|
+
# If there is a result_step, pass the failure as an input to it.
|
49
|
+
@result_step.run({failure: failure}, context) if @result_step
|
50
|
+
# Now fail the workflow
|
51
|
+
raise e
|
52
|
+
else
|
53
|
+
# Pass the result as an input to the result_step
|
54
|
+
@result_step.run(result, context) if @result_step
|
55
|
+
# Complete the workflow by returning the result
|
56
|
+
result
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Initializes a root template
|
63
|
+
# @param {TemplateBase} step
|
64
|
+
# An AWS Flow Framework Template class that inherits TemplateBase. It
|
65
|
+
# contains the actual orchestration of workflow logic inside it.
|
66
|
+
# @param {ActivityTemplate} result_step
|
67
|
+
# An optional ActivityTemplate that can be used to report the result
|
68
|
+
# of the 'step'
|
69
|
+
def root(step, result_step = nil)
|
70
|
+
AWS::Flow::Templates.send(:root, step, result_step)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Initializes a root template
|
74
|
+
# @param {TemplateBase} step
|
75
|
+
# An AWS Flow Framework Template class that inherits TemplateBase. It
|
76
|
+
# contains the actual orchestration of workflow logic inside it.
|
77
|
+
# @param {ActivityTemplate} result_step
|
78
|
+
# An optional ActivityTemplate that can be used to report the result
|
79
|
+
# of the 'step'
|
80
|
+
def self.root(step, result_step = nil)
|
81
|
+
RootTemplate.new(step, result_step)
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module AWS
|
2
|
+
module Flow
|
3
|
+
module Templates
|
4
|
+
|
5
|
+
# Default workflow class for the AWS Flow Framework for Ruby. It
|
6
|
+
# can run workflows defined by WorkflowTemplates.
|
7
|
+
class FlowDefaultWorkflowRuby
|
8
|
+
extend AWS::Flow::Workflows
|
9
|
+
|
10
|
+
# Create activity client and child workflow client
|
11
|
+
activity_client :act_client
|
12
|
+
child_workflow_client :child_client
|
13
|
+
|
14
|
+
# Create the workflow type with default options
|
15
|
+
workflow FlowConstants.defaults[:execution_method] do
|
16
|
+
{
|
17
|
+
version: FlowConstants.defaults[:version],
|
18
|
+
prefix_name: FlowConstants.defaults[:prefix_name],
|
19
|
+
default_task_list: FlowConstants.defaults[:task_list],
|
20
|
+
default_execution_start_to_close_timeout: FlowConstants.defaults[:execution_start_to_close_timeout]
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Define the workflow method :start. It will take in an input hash
|
25
|
+
# that contains the root template (:definition) and the arguments to the
|
26
|
+
# template (:args).
|
27
|
+
# @param input Hash
|
28
|
+
# A hash containing the following keys -
|
29
|
+
# definition: An object of type AWS::Flow::Templates::RootTemplate
|
30
|
+
# args: Hash of arguments to be passed to the definition
|
31
|
+
#
|
32
|
+
def start(input)
|
33
|
+
|
34
|
+
raise ArgumentError, "Workflow input must be a Hash" unless input.is_a?(Hash)
|
35
|
+
raise ArgumentError, "Input hash must contain key :definition" if input[:definition].nil?
|
36
|
+
raise ArgumentError, "Input hash must contain key :args" if input[:args].nil?
|
37
|
+
|
38
|
+
definition = input[:definition]
|
39
|
+
args = input[:args]
|
40
|
+
|
41
|
+
unless definition.is_a?(AWS::Flow::Templates::RootTemplate)
|
42
|
+
raise "Workflow Definition must be a AWS::Flow::Templates::RootTemplate"
|
43
|
+
end
|
44
|
+
raise "Input must be a Hash" unless args.is_a?(Hash)
|
45
|
+
|
46
|
+
# Run the root workflow template
|
47
|
+
definition.run(args, self)
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
# Proxy classes for user activities are created in this module
|
54
|
+
module ActivityProxies; end
|
55
|
+
|
56
|
+
# Used to convert a regular ruby class into a Ruby Flow Activity class,
|
57
|
+
# i.e. extends the AWS::Flow::Activities module. It converts all user
|
58
|
+
# defined instance methods into activities and assigns the following
|
59
|
+
# defaults to the ActivityType - version: "1.0"
|
60
|
+
def self.make_activity_class(klass)
|
61
|
+
return klass if klass.nil?
|
62
|
+
|
63
|
+
name = klass.name.split(":").last
|
64
|
+
|
65
|
+
proxy_name = name + "Proxy"
|
66
|
+
# Create a proxy activity class that will define activities for all
|
67
|
+
# instance methods of the class.
|
68
|
+
new_klass = self::ActivityProxies.const_set(proxy_name.to_sym, Class.new(Object))
|
69
|
+
|
70
|
+
# Extend the AWS::Flow::Activities module and create activities for all
|
71
|
+
# instance methods
|
72
|
+
new_klass.class_exec do
|
73
|
+
extend AWS::Flow::Activities
|
74
|
+
|
75
|
+
attr_reader :instance
|
76
|
+
|
77
|
+
@@klass = klass
|
78
|
+
|
79
|
+
def initialize
|
80
|
+
@instance = @@klass.new
|
81
|
+
end
|
82
|
+
|
83
|
+
# Creates activities for all instance methods of the held klass
|
84
|
+
@@klass.instance_methods(false).each do |method|
|
85
|
+
activity(method) do
|
86
|
+
{
|
87
|
+
version: "1.0",
|
88
|
+
prefix_name: name
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Redirect all method calls to the held instance
|
94
|
+
def method_missing(method, *args, &block)
|
95
|
+
@instance.send(method, *args, &block)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
new_klass
|
100
|
+
end
|
101
|
+
|
102
|
+
# Default result reporting activity class for the AWS Flow Framework for
|
103
|
+
# Ruby
|
104
|
+
class FlowDefaultResultActivityRuby
|
105
|
+
extend AWS::Flow::Activities
|
106
|
+
|
107
|
+
attr_reader :result
|
108
|
+
|
109
|
+
# Create the activity type with default options
|
110
|
+
activity FlowConstants.defaults[:result_activity_method] do
|
111
|
+
{
|
112
|
+
version: FlowConstants.defaults[:result_activity_version],
|
113
|
+
prefix_name: FlowConstants.defaults[:result_activity_prefix],
|
114
|
+
default_task_list: FlowConstants.defaults[:task_list],
|
115
|
+
exponential_retry: FlowConstants.defaults[:retry_policy]
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
119
|
+
# Initialize the future upon instantiation
|
120
|
+
def initialize
|
121
|
+
@result = Future.new
|
122
|
+
end
|
123
|
+
|
124
|
+
# Set the future when the activity is run
|
125
|
+
def run(input)
|
126
|
+
@result.set(input)
|
127
|
+
input
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns the default result activity class
|
133
|
+
# @api private
|
134
|
+
def self.result_activity
|
135
|
+
return AWS::Flow::Templates.const_get(FlowConstants.defaults[:result_activity_prefix])
|
136
|
+
end
|
137
|
+
|
138
|
+
# Returns the default workflow class
|
139
|
+
# @api private
|
140
|
+
def self.default_workflow
|
141
|
+
return AWS::Flow::Templates.const_get(FlowConstants.defaults[:prefix_name])
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
module AWS
|
2
|
+
module Flow
|
3
|
+
|
4
|
+
# @api private
|
5
|
+
module Templates
|
6
|
+
|
7
|
+
# Starts an Activity or a Workflow Template execution using the default
|
8
|
+
# workflow class FlowDefaultWorkflowRuby
|
9
|
+
#
|
10
|
+
# @param [String or AWS::Flow::Templates::TemplateBase] name_or_klass
|
11
|
+
# The Activity or the Workflow Template that needs to be scheduled via
|
12
|
+
# the default workflow. This argument can either be a string that
|
13
|
+
# represents a fully qualified activity name - <ActivityClass>.<method_name>
|
14
|
+
# or it can be an instance of AWS::Flow::Templates::TemplateBase
|
15
|
+
#
|
16
|
+
# @param [Hash] input
|
17
|
+
# Input hash for the workflow execution
|
18
|
+
#
|
19
|
+
# @param [Hash] opts
|
20
|
+
# Additional options to configure the workflow or activity execution.
|
21
|
+
#
|
22
|
+
# @option opts [true, false] :wait
|
23
|
+
# *Optional* This boolean flag can be set to true if the result of the
|
24
|
+
# task is required. Default value is false.
|
25
|
+
#
|
26
|
+
# @option opts [Integer] :wait_timeout
|
27
|
+
# *Optional* This sets the timeout value for :wait. Default value is
|
28
|
+
# nil.
|
29
|
+
#
|
30
|
+
# @option opts [Hash] :exponential_retry
|
31
|
+
# A hash of {AWS::Flow::ExponentialRetryOptions}. Default value is -
|
32
|
+
# { maximum_attempts: 3 }
|
33
|
+
#
|
34
|
+
# @option opts [String] *Optional* :domain
|
35
|
+
# Default value is FlowDefault
|
36
|
+
#
|
37
|
+
# @option opts [Integer] *Optional* :execution_start_to_close_timeout
|
38
|
+
# Default value is 3600 seconds (1 hour)
|
39
|
+
#
|
40
|
+
# @option opts [Integer] *Optional* :retention_in_days
|
41
|
+
# Default value is 7 days
|
42
|
+
#
|
43
|
+
# @option opts [String] *Optional* :workflow_id
|
44
|
+
#
|
45
|
+
# @option opts [Integer] *Optional* :task_priority
|
46
|
+
# Default value is 0
|
47
|
+
#
|
48
|
+
# @option opts [String] *Optional* :tag_list
|
49
|
+
# By default, the name of the activity task gets added to the workflow's
|
50
|
+
# tag_list
|
51
|
+
#
|
52
|
+
# @option opts *Optional* :data_converter
|
53
|
+
# Default value is {AWS::Flow::YAMLDataConverter}. To use the
|
54
|
+
# {AWS::Flow::S3DataConverter}, set the AWS_SWF_BUCKET_NAME environment
|
55
|
+
# variable name with a valid AWS S3 bucket name.
|
56
|
+
#
|
57
|
+
# @option opts *Optional* A hash of {AWS::Flow::ActivityOptions}
|
58
|
+
#
|
59
|
+
# Usage -
|
60
|
+
#
|
61
|
+
# AWS::Flow::start("<ActivityClassName>.<method_name>", <input_hash>,
|
62
|
+
# <options_hash> )
|
63
|
+
#
|
64
|
+
# Example -
|
65
|
+
#
|
66
|
+
# 1) Start an activity execution -
|
67
|
+
# AWS::Flow::start("HelloWorldActivity.say_hello", { name: "World" })
|
68
|
+
#
|
69
|
+
# 2) Start an activity execution with overriden options -
|
70
|
+
# AWS::Flow::start("HelloWorldActivity.say_hello", { name: "World" }, {
|
71
|
+
# exponential_retry: { maximum_attempts: 10 } }
|
72
|
+
# )
|
73
|
+
#
|
74
|
+
def self.start(name_or_klass, input, opts = {})
|
75
|
+
|
76
|
+
options = opts.dup
|
77
|
+
|
78
|
+
if name_or_klass.is_a?(String)
|
79
|
+
# Add activity name as a tag to the workflow execution
|
80
|
+
(options[:tag_list] ||= []) << name_or_klass
|
81
|
+
|
82
|
+
# If name_or_klass passed in is a string, we are assuming the user is
|
83
|
+
# trying to start a single activity task. Wrap the activity information
|
84
|
+
# in the activity template
|
85
|
+
name_or_klass = AWS::Flow::Templates.activity(name_or_klass, options)
|
86
|
+
|
87
|
+
# Keep only the required options in the hash
|
88
|
+
keys = [
|
89
|
+
:domain,
|
90
|
+
:retention_in_days,
|
91
|
+
:execution_start_to_close_timeout,
|
92
|
+
:task_priority,
|
93
|
+
:wait,
|
94
|
+
:wait_timeout,
|
95
|
+
:workflow_id,
|
96
|
+
:data_converter,
|
97
|
+
:tag_list
|
98
|
+
]
|
99
|
+
options.select! { |x| keys.include?(x) }
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
# Wrap the template in a root template
|
104
|
+
root = AWS::Flow::Templates.root(name_or_klass)
|
105
|
+
|
106
|
+
# Get the default options and merge them with the options passed in. The
|
107
|
+
# order of the two hashes 'defaults' and 'options' is important here.
|
108
|
+
defaults = FlowConstants.defaults.select do |key|
|
109
|
+
[
|
110
|
+
:domain,
|
111
|
+
:prefix_name,
|
112
|
+
:execution_method,
|
113
|
+
:version,
|
114
|
+
:execution_start_to_close_timeout,
|
115
|
+
:data_converter,
|
116
|
+
:task_list
|
117
|
+
].include?(key)
|
118
|
+
end
|
119
|
+
options = defaults.merge(options)
|
120
|
+
|
121
|
+
raise "input needs to be a Hash" unless input.is_a?(Hash)
|
122
|
+
|
123
|
+
# Set the input for the default workflow
|
124
|
+
workflow_input = {
|
125
|
+
definition: root,
|
126
|
+
args: input,
|
127
|
+
}
|
128
|
+
|
129
|
+
# Set the result_step for the root template if wait flag is
|
130
|
+
# set.
|
131
|
+
wait = options.delete(:wait)
|
132
|
+
wait_timeout = options.delete(:wait_timeout)
|
133
|
+
result_tasklist = set_result_activity(root) if wait
|
134
|
+
|
135
|
+
# Call #start_workflow with the correct options to start the workflow
|
136
|
+
# execution
|
137
|
+
begin
|
138
|
+
AWS::Flow::start_workflow(workflow_input, options)
|
139
|
+
rescue AWS::SimpleWorkflow::Errors::UnknownResourceFault => e
|
140
|
+
register_defaults(options[:domain])
|
141
|
+
AWS::Flow::start_workflow(workflow_input, options)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Wait for result
|
145
|
+
get_result(result_tasklist, options[:domain], wait_timeout) if wait
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
# Sets the result activity with a unique tasklist name for the root template.
|
150
|
+
# @api private
|
151
|
+
def self.set_result_activity(root)
|
152
|
+
# We want the result to be sent to a specific tasklist so that no other
|
153
|
+
# worker gets the result of this workflow.
|
154
|
+
result_tasklist = "result_tasklist: #{SecureRandom.uuid}"
|
155
|
+
|
156
|
+
name = "#{FlowConstants.defaults[:result_activity_prefix]}."\
|
157
|
+
"#{FlowConstants.defaults[:result_activity_method]}"
|
158
|
+
|
159
|
+
# Set the result_step of the root template to the result activity and
|
160
|
+
# override the tasklist and timeouts.
|
161
|
+
root.result_step = activity(name, {
|
162
|
+
task_list: result_tasklist,
|
163
|
+
schedule_to_start_timeout: FlowConstants.defaults[:schedule_to_start_timeout],
|
164
|
+
start_to_close_timeout: FlowConstants.defaults[:start_to_close_timeout]
|
165
|
+
}
|
166
|
+
)
|
167
|
+
result_tasklist
|
168
|
+
end
|
169
|
+
|
170
|
+
# Gets the result of the workflow execution by starting an ActivityWorker
|
171
|
+
# on the FlowDefaultResultActivityRuby class. The result activity will set
|
172
|
+
# the instance variable future :result with the result of the template.
|
173
|
+
# It will block till either the result future is set or till the timeout
|
174
|
+
# expires - whichever comes first.
|
175
|
+
# @api private
|
176
|
+
def self.get_result(tasklist, domain, timeout=nil)
|
177
|
+
|
178
|
+
swf = AWS::SimpleWorkflow.new
|
179
|
+
domain = swf.domains[domain]
|
180
|
+
|
181
|
+
# Create a new instance of the FlowDefaultResultActivityRuby class and
|
182
|
+
# add it to the ActivityWorker. We pass in the instance instead of the
|
183
|
+
# class itself, so that we can locally access the instance variable set
|
184
|
+
# by the activity method.
|
185
|
+
activity = FlowDefaultResultActivityRuby.new
|
186
|
+
|
187
|
+
# Create the activity worker to poll on the result tasklist
|
188
|
+
worker = AWS::Flow::ActivityWorker.new(domain.client, domain, tasklist, activity) {{ use_forking: false }}
|
189
|
+
|
190
|
+
# Keep polling till we get the result or timeout. A 0 or nil timeout
|
191
|
+
# will let the loop run to completion.
|
192
|
+
begin
|
193
|
+
Timeout::timeout(timeout) do
|
194
|
+
until activity.result.set?
|
195
|
+
worker.run_once(false)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
rescue Timeout::Error => e
|
199
|
+
activity.result.set
|
200
|
+
return
|
201
|
+
end
|
202
|
+
|
203
|
+
# Get the result from the future
|
204
|
+
result = activity.result.get
|
205
|
+
if result.is_a?(Hash) && result[:failure] && result[:failure].is_a?(Exception)
|
206
|
+
raise result[:failure]
|
207
|
+
end
|
208
|
+
|
209
|
+
result
|
210
|
+
end
|
211
|
+
|
212
|
+
# Registers the relevant defaults with the Simple Workflow Service
|
213
|
+
# @api private
|
214
|
+
def self.register_defaults(name=nil)
|
215
|
+
domain = name.nil? ? register_default_domain : AWS::SimpleWorkflow.new.domains[name]
|
216
|
+
|
217
|
+
register_default_workflow(domain)
|
218
|
+
register_default_result_activity(domain)
|
219
|
+
end
|
220
|
+
|
221
|
+
# Registers the default domain FlowDefault with the Simple Workflow
|
222
|
+
# Service
|
223
|
+
# @api private
|
224
|
+
def self.register_default_domain
|
225
|
+
AWS::Flow::Utilities.register_domain(FlowConstants.defaults[:domain])
|
226
|
+
end
|
227
|
+
|
228
|
+
# Registers the default workflow type FlowDefaultWorkflowRuby with the
|
229
|
+
# Simple Workflow Service
|
230
|
+
# @api private
|
231
|
+
def self.register_default_workflow(domain)
|
232
|
+
AWS::Flow::WorkflowWorker.new(
|
233
|
+
domain.client,
|
234
|
+
domain,
|
235
|
+
nil,
|
236
|
+
AWS::Flow::Templates.default_workflow
|
237
|
+
).register
|
238
|
+
end
|
239
|
+
|
240
|
+
# Registers the default result activity type FlowDefaultResultActivityRuby
|
241
|
+
# with the Simple Workflow Service
|
242
|
+
# @api private
|
243
|
+
def self.register_default_result_activity(domain)
|
244
|
+
worker = AWS::Flow::ActivityWorker.new(
|
245
|
+
domain.client,
|
246
|
+
domain,
|
247
|
+
nil,
|
248
|
+
AWS::Flow::Templates.result_activity
|
249
|
+
) {{ use_forking: false }}
|
250
|
+
worker.register
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
end
|