aws-flow 2.4.0 → 3.0.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 +1 -0
- data/lib/aws/decider.rb +0 -1
- data/lib/aws/decider/starter.rb +6 -8
- data/lib/aws/decider/utilities.rb +6 -0
- data/lib/aws/decider/version.rb +1 -1
- data/lib/aws/decider/worker.rb +6 -0
- data/lib/aws/flow/future.rb +86 -6
- data/lib/aws/flow/implementation.rb +84 -13
- data/lib/aws/runner.rb +1 -1
- data/lib/aws/templates.rb +2 -0
- data/lib/aws/templates/activity.rb +41 -0
- data/lib/aws/templates/default.rb +11 -8
- data/lib/aws/templates/result.rb +183 -0
- data/lib/aws/templates/starter.rb +152 -226
- data/lib/aws/templates/utilities.rb +59 -0
- data/spec/aws/decider/integration/activity_spec.rb +1 -0
- data/spec/aws/decider/integration/options_spec.rb +16 -9
- data/spec/aws/decider/integration/starter_spec.rb +6 -7
- data/spec/aws/decider/unit/starter_spec.rb +2 -2
- data/spec/aws/decider/unit/worker_spec.rb +42 -0
- data/spec/aws/flow/{async_backtrace_spec.rb → unit/async_backtrace_spec.rb} +0 -0
- data/spec/aws/flow/{async_scope_spec.rb → unit/async_scope_spec.rb} +0 -0
- data/spec/aws/flow/{begin_rescue_ensure_spec.rb → unit/begin_rescue_ensure_spec.rb} +0 -0
- data/spec/aws/flow/unit/external_condition_variable_spec.rb +59 -0
- data/spec/aws/flow/{external_task_spec.rb → unit/external_task_spec.rb} +0 -0
- data/spec/aws/flow/{factories.rb → unit/factories.rb} +0 -0
- data/spec/aws/flow/{fiber_condition_variable_spec.rb → unit/fiber_condition_variable_spec.rb} +0 -0
- data/spec/aws/flow/{fiber_spec.rb → unit/fiber_spec.rb} +0 -0
- data/spec/aws/flow/{flow_spec.rb → unit/flow_spec.rb} +0 -0
- data/spec/aws/flow/{future_spec.rb → unit/future_spec.rb} +188 -0
- data/spec/aws/flow/{simple_dfa_spec.rb → unit/simple_dfa_spec.rb} +0 -0
- data/spec/aws/runner/integration/runner_integration_spec.rb +1 -0
- data/spec/aws/runner/unit/runner_unit_spec.rb +3 -3
- data/spec/aws/templates/unit/activity_spec.rb +9 -10
- data/spec/aws/templates/unit/base_spec.rb +10 -11
- data/spec/aws/templates/unit/default_spec.rb +23 -6
- data/spec/aws/templates/unit/result_spec.rb +130 -0
- data/spec/aws/templates/unit/starter_spec.rb +32 -105
- data/spec/aws/templates/unit/utilities_spec.rb +80 -0
- metadata +19 -13
@@ -0,0 +1,183 @@
|
|
1
|
+
module AWS
|
2
|
+
module Flow
|
3
|
+
module Templates
|
4
|
+
|
5
|
+
# ResultWorker is responsible for processing the results of the background
|
6
|
+
# jobs. It starts an ActivityWorker to process the ActivityTasks for
|
7
|
+
# FlowDefaultResultActivityRuby.run activity. It either returns futures or
|
8
|
+
# or actual results themselves back to the user
|
9
|
+
class ResultWorker
|
10
|
+
|
11
|
+
# Wrapper around a ruby {Hash} to provide synchronization around making
|
12
|
+
# changes to the encapsulated hash.
|
13
|
+
class SynchronizedHash
|
14
|
+
attr_reader :hash
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@semaphore = Mutex.new
|
18
|
+
@hash = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_missing(method, *args)
|
22
|
+
# Not very efficient but ruby structures are not thread
|
23
|
+
# safe in MRI.
|
24
|
+
@semaphore.synchronize{ return @hash.send(method, *args) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class << self
|
29
|
+
attr_reader :results
|
30
|
+
end
|
31
|
+
|
32
|
+
# Controls synchronization around creation of the ActivityWorker to
|
33
|
+
# ensure singleton
|
34
|
+
@semaphore = Mutex.new
|
35
|
+
|
36
|
+
# Starts ResultWorker and ensures that a single ActivityWorker is
|
37
|
+
# started for this process. Initializes all class instance variables.
|
38
|
+
def self.start(domain)
|
39
|
+
|
40
|
+
# If already initiated, return
|
41
|
+
return @task_list if @task_list
|
42
|
+
|
43
|
+
# Acquire the lock to ensure only 1 copy of the worker is created
|
44
|
+
@semaphore.synchronize do
|
45
|
+
# If multiple threads were waiting on the lock, then we should
|
46
|
+
# return if the worker was created by the previous thread
|
47
|
+
return @task_list if @task_list
|
48
|
+
# Initiate all class instance variables. @semaphore around this
|
49
|
+
# block ensures a singleton
|
50
|
+
self.init
|
51
|
+
end
|
52
|
+
|
53
|
+
# Create pipes for IPC
|
54
|
+
reader, writer = IO.pipe
|
55
|
+
|
56
|
+
# Start the ForkingExecutor with the ActivityWorker
|
57
|
+
self.start_executor(reader, writer, domain)
|
58
|
+
|
59
|
+
# Close one end of the writer pipe
|
60
|
+
writer.close
|
61
|
+
|
62
|
+
# Start the listener thread
|
63
|
+
self.start_listener(reader)
|
64
|
+
|
65
|
+
# Register signal handlers for this process
|
66
|
+
self.handle_signals
|
67
|
+
|
68
|
+
return @task_list
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Initiates the class instance variables
|
75
|
+
# @api private
|
76
|
+
def self.init
|
77
|
+
# We want the result to be sent to a specific tasklist so that no other
|
78
|
+
# worker gets the result of this workflow.
|
79
|
+
@task_list ||= "#{Socket.gethostname}:#{Process.pid}:#{SecureRandom.uuid}"
|
80
|
+
# Results will be stored in this hash
|
81
|
+
@results ||= SynchronizedHash.new
|
82
|
+
# Create a new forking executor
|
83
|
+
@executor ||= ForkingExecutor.new
|
84
|
+
end
|
85
|
+
|
86
|
+
# Start the ActivityWorker using the ForkingExecutor
|
87
|
+
# @api private
|
88
|
+
def self.start_executor(reader, writer, domain)
|
89
|
+
# Create a child process and start an ActivityWorker
|
90
|
+
@executor.execute do
|
91
|
+
$0 = 'result-worker'
|
92
|
+
# Close one end of the reader pipe
|
93
|
+
reader.close
|
94
|
+
|
95
|
+
# Create a new instance of the FlowDefaultResultActivityRuby
|
96
|
+
# class and add it to the ActivityWorker. We instantiate the
|
97
|
+
# activity with the writer pipe so that the activity instance
|
98
|
+
# can report results back to the parent process.
|
99
|
+
activity = AWS::Flow::Templates.result_activity.new(writer)
|
100
|
+
|
101
|
+
# Start the activity worker. In case of UnknownResourceFault,
|
102
|
+
# register the types and start it again.
|
103
|
+
AWS::Flow::Templates::Utils.register_on_failure(domain) do |x|
|
104
|
+
swf = AWS::SimpleWorkflow.new
|
105
|
+
x = swf.domains[x]
|
106
|
+
AWS::Flow::ActivityWorker.new(x.client, x, @task_list, activity).start(false)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Starts a listener thread that reads data from a reader pipe and
|
112
|
+
# updates the result hash
|
113
|
+
# @api private
|
114
|
+
def self.start_listener(reader)
|
115
|
+
@listener_t = Thread.new do
|
116
|
+
Thread.current[:name] = "listener_t"
|
117
|
+
while true
|
118
|
+
data = reader.gets
|
119
|
+
result = Marshal.load(data)
|
120
|
+
# Only update the result if an unset Future is present at the
|
121
|
+
# given location in the hash.
|
122
|
+
future = @results[result[:key]]
|
123
|
+
if future && !future.set?
|
124
|
+
future.set(result[:result])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Resets all the class instance variables for ResultWorker
|
131
|
+
# @api private
|
132
|
+
def self.reset
|
133
|
+
@listener_t = nil
|
134
|
+
@results = nil
|
135
|
+
@task_list = nil
|
136
|
+
@executor = nil
|
137
|
+
end
|
138
|
+
|
139
|
+
# Stops the ResultWorker, i.e., terminates the listener thread and
|
140
|
+
# shutdowns the executor.
|
141
|
+
# @api private
|
142
|
+
def self.stop
|
143
|
+
@listener_t.terminate if @listener_t
|
144
|
+
@executor.shutdown(0) if @executor
|
145
|
+
self.reset
|
146
|
+
end
|
147
|
+
|
148
|
+
# Registers the signal handlers
|
149
|
+
# @api private
|
150
|
+
def self.handle_signals
|
151
|
+
at_exit {
|
152
|
+
self.stop
|
153
|
+
}
|
154
|
+
%w{ TERM INT }.each do |s|
|
155
|
+
Signal.trap(s) do
|
156
|
+
self.stop
|
157
|
+
Kernel.exit
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Gets the result of the background job. The job is identified by the
|
163
|
+
# unique key which was assigned to it during scheduling.
|
164
|
+
# The method returns a future which the users can wait on to get the
|
165
|
+
# result.
|
166
|
+
# @api private
|
167
|
+
def self.get_result_future(key)
|
168
|
+
|
169
|
+
# Get the future from the results hash
|
170
|
+
future = self.results[key]
|
171
|
+
|
172
|
+
# Self delete the future from the results hash when it is set
|
173
|
+
future.on_set { |x| self.results.delete(key) }
|
174
|
+
|
175
|
+
return future
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
end
|
@@ -4,250 +4,176 @@ module AWS
|
|
4
4
|
# @api private
|
5
5
|
module Templates
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
7
|
+
class Starter
|
8
|
+
|
9
|
+
# Starts an Activity or a Workflow Template execution using the default
|
10
|
+
# workflow class FlowDefaultWorkflowRuby
|
11
|
+
#
|
12
|
+
# @param [String or AWS::Flow::Templates::TemplateBase] name_or_klass
|
13
|
+
# The Activity or the Workflow Template that needs to be scheduled via
|
14
|
+
# the default workflow. This argument can either be a string that
|
15
|
+
# represents a fully qualified activity name - <ActivityClass>.<method_name>
|
16
|
+
# or it can be an instance of AWS::Flow::Templates::TemplateBase
|
17
|
+
#
|
18
|
+
# @param [Hash] input
|
19
|
+
# Input hash for the workflow execution
|
20
|
+
#
|
21
|
+
# @param [Hash] opts
|
22
|
+
# Additional options to configure the workflow or activity execution.
|
23
|
+
#
|
24
|
+
# @option opts [true, false] :get_result
|
25
|
+
# *Optional* This boolean flag can be set to true if the result future
|
26
|
+
# if required. The future can be waited on by using the
|
27
|
+
# AWS::Flow::wait_for_all, AWS::Flow::wait_for_any methods or by
|
28
|
+
# calling the ExternalFuture#get method. Default value is false.
|
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
|
+
:get_result,
|
94
|
+
:workflow_id,
|
95
|
+
:data_converter,
|
96
|
+
:tag_list
|
97
|
+
]
|
98
|
+
options.select! { |x| keys.include?(x) }
|
75
99
|
|
76
|
-
|
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
|
100
|
+
end
|
81
101
|
|
82
|
-
#
|
83
|
-
|
84
|
-
|
85
|
-
|
102
|
+
# Wrap the template in a root template
|
103
|
+
root = AWS::Flow::Templates.root(name_or_klass)
|
104
|
+
|
105
|
+
# Get the default options and merge them with the options passed in. The
|
106
|
+
# order of the two hashes 'defaults' and 'options' is important here.
|
107
|
+
defaults = FlowConstants.defaults.select do |key|
|
108
|
+
[
|
109
|
+
:domain,
|
110
|
+
:prefix_name,
|
111
|
+
:execution_method,
|
112
|
+
:version,
|
113
|
+
:execution_start_to_close_timeout,
|
114
|
+
:data_converter,
|
115
|
+
:task_list
|
116
|
+
].include?(key)
|
117
|
+
end
|
118
|
+
options = defaults.merge(options)
|
86
119
|
|
87
|
-
|
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) }
|
120
|
+
raise "input needs to be a Hash" unless input.is_a?(Hash)
|
100
121
|
|
101
|
-
|
122
|
+
# Set the input for the default workflow
|
123
|
+
workflow_input = {
|
124
|
+
definition: root,
|
125
|
+
args: input
|
126
|
+
}
|
102
127
|
|
103
|
-
|
104
|
-
|
128
|
+
# get_result specifies if we should return back a result future
|
129
|
+
# for this task
|
130
|
+
get_result = options.delete(:get_result)
|
105
131
|
|
106
|
-
|
107
|
-
|
108
|
-
|
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)
|
132
|
+
if get_result
|
133
|
+
# Start the default result activity worker
|
134
|
+
task_list = ResultWorker.start(options[:domain])
|
120
135
|
|
121
|
-
|
136
|
+
# Set the result_step for the root template. We need to pass in the
|
137
|
+
# task_list to ensure the result activity task is sent to the right
|
138
|
+
# task list. This method will return back a unique key that will
|
139
|
+
# help us locate the result of this task in ResultWorker.results hash
|
140
|
+
key = set_result_activity(task_list, root)
|
141
|
+
end
|
122
142
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
143
|
+
# Call #start_workflow with the correct options to start the workflow
|
144
|
+
# execution. If it fails with UnknownResourceFault, then regsiter the
|
145
|
+
# default types and retry.
|
146
|
+
AWS::Flow::Templates::Utils.register_on_failure(options[:domain]) do
|
147
|
+
AWS::Flow::start_workflow(workflow_input, options)
|
148
|
+
end
|
128
149
|
|
129
|
-
|
130
|
-
|
131
|
-
wait = options.delete(:wait)
|
132
|
-
wait_timeout = options.delete(:wait_timeout)
|
133
|
-
result_tasklist = set_result_activity(root) if wait
|
150
|
+
# Get the result identified by this key
|
151
|
+
ResultWorker.get_result_future(key) if get_result
|
134
152
|
|
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
153
|
end
|
143
154
|
|
144
|
-
#
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
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,
|
155
|
+
# Sets the result activity with a unique key. The key is used to match
|
156
|
+
# the task with the result of the task. It is provided as an input to
|
157
|
+
# the default result activity and is used to create a new ExternalFuture
|
158
|
+
# in the ResultWorker.results hash.
|
159
|
+
# @api private
|
160
|
+
def self.set_result_activity(task_list, root)
|
161
|
+
|
162
|
+
key = "result_key: #{SecureRandom.uuid}"
|
163
|
+
# Set the result_step of the root template to the result activity and
|
164
|
+
# override the tasklist and timeouts.
|
165
|
+
root.result_step = AWS::Flow::Templates.result(key, {
|
166
|
+
task_list: task_list,
|
163
167
|
schedule_to_start_timeout: FlowConstants.defaults[:schedule_to_start_timeout],
|
164
168
|
start_to_close_timeout: FlowConstants.defaults[:start_to_close_timeout]
|
165
|
-
}
|
166
|
-
)
|
167
|
-
result_tasklist
|
168
|
-
end
|
169
|
+
})
|
169
170
|
|
170
|
-
|
171
|
-
|
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)
|
171
|
+
# Create a new ExternalFuture in the ResultWorker.results hash.
|
172
|
+
ResultWorker.results[key] = ExternalFuture.new
|
177
173
|
|
178
|
-
|
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
|
174
|
+
key
|
201
175
|
end
|
202
176
|
|
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
177
|
end
|
252
178
|
|
253
179
|
end
|