aws-flow 1.3.0 → 2.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 +15 -0
- data/aws-flow.gemspec +1 -0
- data/lib/aws/decider/activity.rb +8 -6
- data/lib/aws/decider/async_decider.rb +1 -0
- data/lib/aws/decider/async_retrying_executor.rb +3 -3
- data/lib/aws/decider/decider.rb +16 -14
- data/lib/aws/decider/executor.rb +35 -22
- data/lib/aws/decider/flow_defaults.rb +28 -14
- data/lib/aws/decider/generic_client.rb +3 -4
- data/lib/aws/decider/options.rb +91 -117
- data/lib/aws/decider/state_machines.rb +1 -0
- data/lib/aws/decider/utilities.rb +15 -0
- data/lib/aws/decider/version.rb +1 -1
- data/lib/aws/decider/worker.rb +14 -8
- data/lib/aws/decider/workflow_client.rb +16 -11
- data/lib/aws/runner.rb +43 -39
- data/spec/aws/decider/integration/activity_spec.rb +345 -0
- data/spec/aws/{integration → decider/integration}/integration_spec.rb +818 -1183
- data/spec/aws/decider/integration/setup.rb +3 -0
- data/spec/aws/decider/unit/activity_spec.rb +233 -0
- data/spec/aws/decider/unit/async_retrying_executor_spec.rb +131 -0
- data/spec/aws/{unit → decider/unit}/decider_spec.rb +171 -718
- data/spec/aws/decider/unit/executor_spec.rb +123 -0
- data/spec/aws/decider/unit/flow_defaults_spec.rb +62 -0
- data/spec/aws/decider/unit/misc_spec.rb +101 -0
- data/spec/aws/decider/unit/options_spec.rb +289 -0
- data/spec/aws/decider/unit/retry_spec.rb +217 -0
- data/spec/aws/{unit → decider/unit}/rubyflow.rb +0 -0
- data/spec/aws/decider/unit/setup.rb +3 -0
- data/spec/aws/decider/unit/worker_spec.rb +325 -0
- data/spec/aws/decider/unit/workflow_client_spec.rb +83 -0
- data/spec/aws/{unit → flow}/async_backtrace_spec.rb +0 -0
- data/spec/aws/{unit → flow}/async_scope_spec.rb +0 -0
- data/spec/aws/{unit → flow}/begin_rescue_ensure_spec.rb +1 -0
- data/spec/aws/{unit → flow}/external_task_spec.rb +0 -0
- data/spec/aws/{unit → flow}/factories.rb +0 -0
- data/spec/aws/{unit → flow}/fiber_condition_variable_spec.rb +0 -0
- data/spec/aws/{unit → flow}/fiber_spec.rb +0 -0
- data/spec/aws/{unit → flow}/flow_spec.rb +0 -0
- data/spec/aws/{unit → flow}/future_spec.rb +0 -0
- data/spec/aws/{unit → flow}/simple_dfa_spec.rb +0 -0
- data/spec/aws/{integration → runner/integration}/runner_integration_spec.rb +16 -43
- data/spec/aws/{unit → runner/unit}/runner_unit_spec.rb +18 -18
- data/spec/spec_helper.rb +264 -2
- metadata +37 -28
- data/spec/aws/unit/executor_spec.rb +0 -49
- data/spec/aws/unit/options_spec.rb +0 -293
- data/spec/aws/unit/preinclude_tests.rb +0 -149
@@ -16,52 +16,7 @@
|
|
16
16
|
require 'yaml'
|
17
17
|
require 'aws-sdk'
|
18
18
|
require 'logger'
|
19
|
-
|
20
|
-
require 'aws/decider'
|
21
|
-
include AWS::Flow
|
22
|
-
|
23
|
-
$RUBYFLOW_DECIDER_TASK_LIST = 'test_task_list'
|
24
|
-
|
25
|
-
def kill_executors
|
26
|
-
return if ForkingExecutor.executors.nil?
|
27
|
-
ForkingExecutor.executors.each do |executor|
|
28
|
-
executor.shutdown(0) unless executor.is_shutdown rescue StandardError
|
29
|
-
end
|
30
|
-
#TODO Reinstate this, but it's useful to keep them around for debugging
|
31
|
-
#ForkingExecutor.executors = []
|
32
|
-
end
|
33
|
-
|
34
|
-
def setup_swf
|
35
|
-
current_date = Time.now.strftime("%d-%m-%Y")
|
36
|
-
file_name = "/tmp/" + current_date
|
37
|
-
if File.exists?(file_name)
|
38
|
-
last_run = File.open(file_name, 'r').read.to_i
|
39
|
-
else
|
40
|
-
last_run = 0
|
41
|
-
end
|
42
|
-
last_run += 1
|
43
|
-
File.open(file_name, 'w+') {|f| f.write(last_run)}
|
44
|
-
current_date = Time.now.strftime("%d-%m-%Y")
|
45
|
-
config_file = File.open('credentials.cfg') { |f| f.read }
|
46
|
-
if config_file.include? ":Primary"
|
47
|
-
yaml_config = YAML.load(config_file)
|
48
|
-
swf = AWS::SimpleWorkflow.new(yaml_config[:Primary])
|
49
|
-
secondary_swf = AWS::SimpleWorkflow.new(yaml_config[:Secondary])
|
50
|
-
else
|
51
|
-
config = YAML.load(config_file).first
|
52
|
-
AWS.config(config)
|
53
|
-
swf = AWS::SimpleWorkflow.new
|
54
|
-
secondary_swf = nil
|
55
|
-
end
|
56
|
-
$RUBYFLOW_DECIDER_DOMAIN = "rubyflow_decider_domain_#{current_date}-#{last_run}"
|
57
|
-
begin
|
58
|
-
domain = swf.domains.create($RUBYFLOW_DECIDER_DOMAIN, "10")
|
59
|
-
rescue AWS::SimpleWorkflow::Errors::DomainAlreadyExistsFault => e
|
60
|
-
domain = swf.domains[$RUBYFLOW_DECIDER_DOMAIN]
|
61
|
-
end
|
62
|
-
return swf, domain, $RUBYFLOW_DECIDER_DOMAIN, secondary_swf
|
63
|
-
end
|
64
|
-
|
19
|
+
require_relative 'setup'
|
65
20
|
|
66
21
|
|
67
22
|
class SimpleTestHistoryEvent
|
@@ -78,21 +33,12 @@ end
|
|
78
33
|
describe "RubyFlowDecider" do
|
79
34
|
before(:all) do
|
80
35
|
class MyWorkflow
|
81
|
-
extend
|
36
|
+
extend AWS::Flow::Workflows
|
82
37
|
version "1"
|
83
38
|
# TODO more of the stuff from the proposal
|
84
39
|
end
|
85
|
-
@swf, @domain, $RUBYFLOW_DECIDER_DOMAIN, @swf_secondary = setup_swf
|
86
|
-
$swf, $domain, $swf_secondary = @swf, @domain, @swf_secondary
|
87
|
-
# If there are any outstanding decision tasks before we start the test, that
|
88
|
-
# could really mess things up, and make the tests non-idempotent. So lets
|
89
|
-
# clear those out
|
90
40
|
|
91
|
-
|
92
|
-
@domain.decision_tasks.poll_for_single_task($RUBYFLOW_DECIDER_TASK_LIST) do |task|
|
93
|
-
task.complete workflow_execution
|
94
|
-
end
|
95
|
-
end
|
41
|
+
@swf, @domain = setup_swf
|
96
42
|
if @domain.workflow_executions.with_status(:open).count.count > 0
|
97
43
|
@domain.workflow_executions.with_status(:open).each { |wf| wf.terminate }
|
98
44
|
end
|
@@ -110,7 +56,7 @@ describe "RubyFlowDecider" do
|
|
110
56
|
target_workflow = @domain.workflow_types.page(:per_page => 1000).select { |x| x.name == "blank_workflow_test"}
|
111
57
|
if target_workflow.length == 0
|
112
58
|
workflow_type = @domain.workflow_types.create("blank_workflow_test", '1',
|
113
|
-
:default_task_list =>
|
59
|
+
:default_task_list => "initial_test_tasklist",
|
114
60
|
:default_child_policy => :request_cancel,
|
115
61
|
:default_task_start_to_close_timeout => 3600,
|
116
62
|
:default_execution_start_to_close_timeout => 24 * 3600)
|
@@ -121,314 +67,19 @@ describe "RubyFlowDecider" do
|
|
121
67
|
workflow_execution.terminate
|
122
68
|
end
|
123
69
|
|
124
|
-
|
125
|
-
describe WorkflowTaskPoller do
|
126
|
-
describe "Integration Tests" do
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
describe "Unit Tests" do
|
131
|
-
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
describe WorkflowWorker do
|
136
|
-
describe "Unit Tests" do
|
137
|
-
end
|
138
|
-
|
139
|
-
|
140
|
-
describe "Integration Tests" do
|
141
|
-
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
describe DecisionTaskHandler do
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
describe "interface" do
|
150
|
-
end
|
151
|
-
|
152
|
-
describe Activities do
|
153
|
-
it "ensures that a real activity will get scheduled" do
|
154
|
-
task_list = "activity_task_list"
|
155
|
-
class Blah
|
156
|
-
extend Activity
|
157
|
-
end
|
158
|
-
class BasicActivity
|
159
|
-
extend Activity
|
160
|
-
|
161
|
-
activity :run_activity1 do |o|
|
162
|
-
o.default_task_heartbeat_timeout = "3600"
|
163
|
-
o.default_task_list = "activity_task_list"
|
164
|
-
o.default_task_schedule_to_close_timeout = "3600"
|
165
|
-
o.default_task_schedule_to_start_timeout = "3600"
|
166
|
-
o.default_task_start_to_close_timeout = "3600"
|
167
|
-
o.version = "1"
|
168
|
-
end
|
169
|
-
def run_activity1
|
170
|
-
"first regular activity"
|
171
|
-
end
|
172
|
-
end
|
173
|
-
class BasicWorkflow
|
174
|
-
extend Decider
|
175
|
-
|
176
|
-
entry_point :entry_point
|
177
|
-
version "1"
|
178
|
-
activity_client :activity do |options|
|
179
|
-
options.prefix_name = "BasicActivity"
|
180
|
-
end
|
181
|
-
def entry_point
|
182
|
-
activity.run_activity1
|
183
|
-
end
|
184
|
-
end
|
185
|
-
worker = WorkflowWorker.new(@swf.client, @domain, task_list)
|
186
|
-
worker.add_workflow_implementation(BasicWorkflow)
|
187
|
-
activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
|
188
|
-
activity_worker.add_activities_implementation(BasicActivity)
|
189
|
-
workflow_type_name = "BasicWorkflow.entry_point"
|
190
|
-
worker.register
|
191
|
-
activity_worker.register
|
192
|
-
sleep 3
|
193
|
-
workflow_type, _ = @domain.workflow_types.page(:per_page => 1000).select {|x| x.name == workflow_type_name}
|
194
|
-
|
195
|
-
workflow_execution = workflow_type.start_execution(
|
196
|
-
:execution_start_to_close_timeout => 3600,
|
197
|
-
:task_list => task_list,
|
198
|
-
:task_start_to_close_timeout => 3600,
|
199
|
-
:child_policy => :request_cancel
|
200
|
-
)
|
201
|
-
worker.run_once
|
202
|
-
activity_worker.run_once
|
203
|
-
worker.run_once
|
204
|
-
workflow_execution.events.map(&:event_type).should ==
|
205
|
-
["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
|
206
|
-
end
|
207
|
-
|
208
|
-
it "tests to see what two activities look like" do
|
209
|
-
task_list = "double_activity_task_list"
|
210
|
-
class DoubleActivity
|
211
|
-
extend Activity
|
212
|
-
activity :run_activity1, :run_activity2 do |o|
|
213
|
-
o.version = "1"
|
214
|
-
o.default_task_heartbeat_timeout = "3600"
|
215
|
-
o.default_task_list = "double_activity_task_list"
|
216
|
-
o.default_task_schedule_to_close_timeout = "3600"
|
217
|
-
o.default_task_schedule_to_start_timeout = "10"
|
218
|
-
o.default_task_start_to_close_timeout = "10"
|
219
|
-
o.exponential_retry do |retry_options|
|
220
|
-
retry_options.retries_per_exception = {
|
221
|
-
ActivityTaskTimedOutException => Float::INFINITY,
|
222
|
-
}
|
223
|
-
end
|
224
|
-
end
|
225
|
-
def run_activity1
|
226
|
-
"first parallel activity"
|
227
|
-
end
|
228
|
-
def run_activity2
|
229
|
-
"second parallel activity"
|
230
|
-
end
|
231
|
-
end
|
232
|
-
class DoubleWorkflow
|
233
|
-
extend Decider
|
234
|
-
version "1"
|
235
|
-
activity_client :activity do |options|
|
236
|
-
options.prefix_name = "DoubleActivity"
|
237
|
-
end
|
238
|
-
entry_point :entry_point
|
239
|
-
def entry_point
|
240
|
-
activity.send_async(:run_activity1)
|
241
|
-
activity.run_activity2
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
worker = WorkflowWorker.new(@swf.client, @domain, task_list)
|
246
|
-
worker.add_workflow_implementation(DoubleWorkflow)
|
247
|
-
activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
|
248
|
-
activity_worker.add_activities_implementation(DoubleActivity)
|
249
|
-
workflow_type_name = "DoubleWorkflow.entry_point"
|
250
|
-
worker.register
|
251
|
-
activity_worker.register
|
252
|
-
sleep 3
|
253
|
-
workflow_id = "basic_activity_workflow"
|
254
|
-
run_id = @swf.client.start_workflow_execution(
|
255
|
-
:execution_start_to_close_timeout => "3600",
|
256
|
-
:task_list => {:name => task_list},
|
257
|
-
:task_start_to_close_timeout => "3600",
|
258
|
-
:child_policy => "REQUEST_CANCEL",
|
259
|
-
:workflow_type => {
|
260
|
-
:name => workflow_type_name,
|
261
|
-
:version => "1"
|
262
|
-
},
|
263
|
-
:workflow_id => workflow_id,
|
264
|
-
:domain => @domain.name.to_s
|
265
|
-
)
|
266
|
-
workflow_execution = AWS::SimpleWorkflow::WorkflowExecution.new(@domain, workflow_id, run_id["runId"])
|
267
|
-
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
268
|
-
@forking_executor.execute { worker.start }
|
269
|
-
sleep 5
|
270
|
-
@forking_executor.execute { activity_worker.start }
|
271
|
-
sleep 20
|
272
|
-
@forking_executor.shutdown(1)
|
273
|
-
|
274
|
-
workflow_history = workflow_execution.events.map(&:event_type)
|
275
|
-
workflow_history.count("ActivityTaskCompleted").should == 2
|
276
|
-
workflow_history.count("WorkflowExecutionCompleted").should == 1
|
277
|
-
end
|
278
|
-
|
279
|
-
it "tests to see that two subsequent activities are supported" do
|
280
|
-
task_list = "subsequent_activity_task_list"
|
281
|
-
class SubsequentActivity
|
282
|
-
extend Activity
|
283
|
-
activity :run_activity1, :run_activity2 do |o|
|
284
|
-
o.default_task_heartbeat_timeout = "3600"
|
285
|
-
o.version = "1"
|
286
|
-
o.default_task_list = "subsequent_activity_task_list"
|
287
|
-
o.default_task_schedule_to_close_timeout = "3600"
|
288
|
-
o.default_task_schedule_to_start_timeout = "20"
|
289
|
-
o.default_task_start_to_close_timeout = "20"
|
290
|
-
end
|
291
|
-
def run_activity1
|
292
|
-
"First subsequent activity"
|
293
|
-
end
|
294
|
-
def run_activity2
|
295
|
-
"Second subsequent activity"
|
296
|
-
end
|
297
|
-
end
|
298
|
-
class SubsequentWorkflow
|
299
|
-
extend Workflows
|
300
|
-
workflow :entry_point do
|
301
|
-
{
|
302
|
-
:version => "1",
|
303
|
-
}
|
304
|
-
end
|
305
|
-
version "1"
|
306
|
-
activity_client :activity do |options|
|
307
|
-
options.prefix_name = "SubsequentActivity"
|
308
|
-
end
|
309
|
-
def entry_point
|
310
|
-
activity.run_activity1
|
311
|
-
activity.run_activity2
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
worker = WorkflowWorker.new(@swf.client, @domain, task_list)
|
316
|
-
worker.add_workflow_implementation(SubsequentWorkflow)
|
317
|
-
activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
|
318
|
-
activity_worker.add_activities_implementation(SubsequentActivity)
|
319
|
-
workflow_type_name = "SubsequentWorkflow.entry_point"
|
320
|
-
worker.register
|
321
|
-
activity_worker.register
|
322
|
-
sleep 3
|
323
|
-
|
324
|
-
|
325
|
-
my_workflow_client = workflow_client(@swf.client, @domain) do
|
326
|
-
{
|
327
|
-
:from_class => "SubsequentWorkflow",
|
328
|
-
:execution_start_to_close_timeout => "3600",
|
329
|
-
:task_list => task_list,
|
330
|
-
:task_start_to_close_timeout => "3600",
|
331
|
-
:child_policy => "REQUEST_CANCEL",
|
332
|
-
}
|
333
|
-
end
|
334
|
-
workflow_execution = my_workflow_client.start_execution
|
335
|
-
worker.run_once
|
336
|
-
activity_worker.run_once
|
337
|
-
worker.run_once
|
338
|
-
activity_worker.run_once
|
339
|
-
worker.run_once
|
340
|
-
workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
|
341
|
-
end
|
342
|
-
|
343
|
-
it "tests a much larger workflow" do
|
344
|
-
task_list = "large_activity_task_list"
|
345
|
-
class LargeActivity
|
346
|
-
extend Activity
|
347
|
-
activity :run_activity1, :run_activity2, :run_activity3, :run_activity4 do |o|
|
348
|
-
o.default_task_heartbeat_timeout = "3600"
|
349
|
-
o.default_task_list = "large_activity_task_list"
|
350
|
-
o.default_task_schedule_to_close_timeout = "3600"
|
351
|
-
o.default_task_schedule_to_start_timeout = "5"
|
352
|
-
o.default_task_start_to_close_timeout = "5"
|
353
|
-
o.version = "1"
|
354
|
-
o.exponential_retry do |retry_options|
|
355
|
-
retry_options.retries_per_exception = {
|
356
|
-
ActivityTaskTimedOutException => Float::INFINITY,
|
357
|
-
}
|
358
|
-
end
|
359
|
-
end
|
360
|
-
def run_activity1
|
361
|
-
"My name is Ozymandias - 1"
|
362
|
-
end
|
363
|
-
def run_activity2
|
364
|
-
"King of Kings! - 2 "
|
365
|
-
end
|
366
|
-
def run_activity3
|
367
|
-
"Look on my works, ye mighty - 3"
|
368
|
-
end
|
369
|
-
def run_activity4
|
370
|
-
"And Despair! - 4"
|
371
|
-
end
|
372
|
-
end
|
373
|
-
class LargeWorkflow
|
374
|
-
extend Decider
|
375
|
-
version "1"
|
376
|
-
activity_client :activity do |options|
|
377
|
-
options.prefix_name = "LargeActivity"
|
378
|
-
end
|
379
|
-
entry_point :entry_point
|
380
|
-
def entry_point
|
381
|
-
activity.send_async(:run_activity1)
|
382
|
-
activity.send_async(:run_activity2)
|
383
|
-
activity.send_async(:run_activity3)
|
384
|
-
activity.run_activity4()
|
385
|
-
end
|
386
|
-
end
|
387
|
-
worker = WorkflowWorker.new(@swf.client, @domain, task_list)
|
388
|
-
worker.add_workflow_implementation(LargeWorkflow)
|
389
|
-
activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
|
390
|
-
activity_worker.add_activities_implementation(LargeActivity)
|
391
|
-
worker.register
|
392
|
-
activity_worker.register
|
393
|
-
sleep 3
|
394
|
-
|
395
|
-
workflow_type_name = "LargeWorkflow.entry_point"
|
396
|
-
workflow_type, _ = @domain.workflow_types.page(:per_page => 1000).select {|x| x.name == workflow_type_name}
|
397
|
-
|
398
|
-
workflow_execution = workflow_type.start_execution(
|
399
|
-
:execution_start_to_close_timeout => 3600,
|
400
|
-
:task_list => task_list,
|
401
|
-
:task_start_to_close_timeout => 15,
|
402
|
-
:child_policy => :request_cancel
|
403
|
-
)
|
404
|
-
@forking_executor = ForkingExecutor.new(:max_workers => 5)
|
405
|
-
@forking_executor.execute { activity_worker.start }
|
406
|
-
|
407
|
-
|
408
|
-
@forking_executor.execute { worker.start }
|
409
|
-
|
410
|
-
|
411
|
-
sleep 50
|
412
|
-
|
413
|
-
@forking_executor.shutdown(1)
|
414
|
-
workflow_history = workflow_execution.events.map(&:event_type)
|
415
|
-
workflow_history.count("WorkflowExecutionCompleted").should == 1
|
416
|
-
workflow_history.count("ActivityTaskCompleted").should == 4
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
70
|
describe WorkflowFactory do
|
421
71
|
it "makes sure that you can use the basic workflow_factory" do
|
422
72
|
task_list = "workflow_factory_task_list"
|
423
73
|
class WorkflowFactoryActivity
|
424
|
-
extend
|
425
|
-
activity :run_activity1 do
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
74
|
+
extend AWS::Flow::Activities
|
75
|
+
activity :run_activity1 do
|
76
|
+
{
|
77
|
+
version: "1.0",
|
78
|
+
default_task_list: "workflow_factory_task_list",
|
79
|
+
default_task_schedule_to_close_timeout: 60,
|
80
|
+
default_task_schedule_to_start_timeout: 30,
|
81
|
+
default_task_start_to_close_timeout: 30,
|
82
|
+
}
|
432
83
|
end
|
433
84
|
def run_activity1(arg)
|
434
85
|
"#{arg} is what the activity recieved"
|
@@ -436,51 +87,36 @@ describe "RubyFlowDecider" do
|
|
436
87
|
end
|
437
88
|
|
438
89
|
class WorkflowFactoryWorkflow
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
options.default_task_schedule_to_start_timeout = "3600"
|
449
|
-
options.default_task_start_to_close_timeout = "3600"
|
90
|
+
extend AWS::Flow::Workflows
|
91
|
+
workflow :entry_point do
|
92
|
+
{
|
93
|
+
version: "1.0",
|
94
|
+
default_execution_start_to_close_timeout: 600,
|
95
|
+
default_task_list: "workflow_factory_task_list",
|
96
|
+
default_task_start_to_close_timeout: 120,
|
97
|
+
default_child_policy: :request_cancel,
|
98
|
+
}
|
450
99
|
end
|
100
|
+
activity_client(:activity) { { from_class: "WorkflowFactoryActivity" } }
|
451
101
|
def entry_point(arg)
|
452
102
|
activity.run_activity1("#{arg} recieved as input")
|
453
103
|
end
|
454
104
|
end
|
455
105
|
|
456
|
-
worker = WorkflowWorker.new(@
|
457
|
-
|
458
|
-
activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
|
459
|
-
activity_worker.add_activities_implementation(WorkflowFactoryActivity)
|
106
|
+
worker = WorkflowWorker.new(@domain.client, @domain, task_list, WorkflowFactoryWorkflow)
|
107
|
+
activity_worker = ActivityWorker.new(@domain.client, @domain, task_list, WorkflowFactoryActivity)
|
460
108
|
worker.register
|
461
109
|
activity_worker.register
|
462
110
|
|
463
|
-
|
464
|
-
options.workflow_name = "WorkflowFactoryWorkflow"
|
465
|
-
options.execution_start_to_close_timeout = 3600
|
466
|
-
options.task_list = "workflow_factory_task_list"
|
467
|
-
options.task_start_to_close_timeout = 3600
|
468
|
-
options.task_list
|
469
|
-
options.child_policy = :request_cancel
|
470
|
-
end
|
471
|
-
my_workflow = my_workflow_factory.get_client
|
111
|
+
client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "WorkflowFactoryWorkflow" } }
|
472
112
|
|
473
|
-
workflow_execution =
|
113
|
+
workflow_execution = client.start_execution("some input")
|
474
114
|
|
475
115
|
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
476
|
-
|
477
116
|
@forking_executor.execute { worker.start }
|
478
|
-
|
479
|
-
sleep 3
|
480
|
-
|
481
117
|
@forking_executor.execute { activity_worker.start }
|
482
118
|
|
483
|
-
|
119
|
+
wait_for_execution(workflow_execution)
|
484
120
|
|
485
121
|
workflow_execution.events.map(&:event_type).should == ["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
|
486
122
|
@forking_executor.shutdown(1)
|
@@ -511,30 +147,28 @@ describe "RubyFlowDecider" do
|
|
511
147
|
class_name = attributes[:class_name] || "General"
|
512
148
|
|
513
149
|
new_activity_class = Class.new(ParentActivity) do
|
514
|
-
extend Activities
|
515
|
-
activity :run_activity1, :run_activity2 do
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
end
|
524
|
-
def run_activity1
|
525
|
-
end
|
526
|
-
def run_activity2
|
150
|
+
extend AWS::Flow::Activities
|
151
|
+
activity :run_activity1, :run_activity2 do
|
152
|
+
{
|
153
|
+
default_task_list: task_list,
|
154
|
+
default_task_schedule_to_start_timeout: "60",
|
155
|
+
default_task_start_to_close_timeout: "60",
|
156
|
+
version: "1.0",
|
157
|
+
prefix_name: "#{class_name}Activity",
|
158
|
+
}
|
527
159
|
end
|
160
|
+
def run_activity1; end
|
161
|
+
def run_activity2; end
|
528
162
|
end
|
529
163
|
@activity_class = Object.const_set("#{class_name}Activity", new_activity_class)
|
530
164
|
new_workflow_class = Class.new(ParentWorkflow) do
|
531
|
-
extend Workflows
|
165
|
+
extend AWS::Flow::Workflows
|
532
166
|
workflow(:entry_point) {
|
533
167
|
{
|
534
|
-
:
|
535
|
-
:
|
536
|
-
:
|
537
|
-
:
|
168
|
+
version: "1.0",
|
169
|
+
default_execution_start_to_close_timeout: 300,
|
170
|
+
default_task_list: task_list,
|
171
|
+
prefix_name: "#{class_name}Workflow"
|
538
172
|
}
|
539
173
|
}
|
540
174
|
def entry_point
|
@@ -547,14 +181,14 @@ describe "RubyFlowDecider" do
|
|
547
181
|
@workflow_class.task_list = task_list
|
548
182
|
@activity_class.task_list = task_list
|
549
183
|
@workflow_class.class_eval do
|
550
|
-
activity_client(:activity) { {:
|
184
|
+
activity_client(:activity) { { from_class: self.activity_class } }
|
551
185
|
end
|
552
|
-
@worker = WorkflowWorker.new(@
|
553
|
-
@activity_worker = ActivityWorker.new(@
|
186
|
+
@worker = WorkflowWorker.new(@domain.client, @domain, task_list, @workflow_class)
|
187
|
+
@activity_worker = ActivityWorker.new(@domain.client, @domain, task_list, @activity_class)
|
554
188
|
|
555
189
|
@worker.register
|
556
190
|
@activity_worker.register
|
557
|
-
@my_workflow_client = workflow_client(@
|
191
|
+
@my_workflow_client = workflow_client(@domain.client, @domain) { { from_class: @workflow_class } }
|
558
192
|
end
|
559
193
|
|
560
194
|
it "ensures that an activity returning more than 32k data fails the activity" do
|
@@ -571,6 +205,7 @@ describe "RubyFlowDecider" do
|
|
571
205
|
@worker.run_once
|
572
206
|
@activity_worker.run_once
|
573
207
|
@worker.run_once
|
208
|
+
wait_for_execution(workflow_execution)
|
574
209
|
history_events = workflow_execution.events.map(&:event_type)
|
575
210
|
# Previously, it would time out, as the failure would include the original
|
576
211
|
# large output that killed the completion and failure call. Thus, we need to
|
@@ -586,7 +221,7 @@ describe "RubyFlowDecider" do
|
|
586
221
|
extend Activities
|
587
222
|
activity :run_activity1 do
|
588
223
|
{
|
589
|
-
:default_task_heartbeat_timeout => "
|
224
|
+
:default_task_heartbeat_timeout => "600",
|
590
225
|
:default_task_list => "TwoConfigTaskList",
|
591
226
|
:default_task_schedule_to_start_timeout => 120,
|
592
227
|
:default_task_start_to_close_timeout => 120,
|
@@ -615,8 +250,7 @@ describe "RubyFlowDecider" do
|
|
615
250
|
end
|
616
251
|
worker = WorkflowWorker.new(@swf.client, @domain, "TwoConfigTaskList", TwoConfigWorkflow)
|
617
252
|
activity_worker = ActivityWorker.new(@swf.client, @domain, "TwoConfigTaskList", TwoConfigActivity) {{ :use_forking => false }}
|
618
|
-
|
619
|
-
activity_worker_different_config = ActivityWorker.new($swf_secondary.client, @domain, "other_config_task_list", TwoConfigActivity) {{ :use_forking => false }}
|
253
|
+
activity_worker_different_config = ActivityWorker.new(@swf.client, @domain, "other_config_task_list", TwoConfigActivity) {{ :use_forking => false }}
|
620
254
|
my_workflow_client = workflow_client(@swf.client, @domain) {{:from_class => TwoConfigWorkflow}}
|
621
255
|
|
622
256
|
worker.register
|
@@ -627,6 +261,7 @@ describe "RubyFlowDecider" do
|
|
627
261
|
worker.run_once
|
628
262
|
activity_worker_different_config.run_once
|
629
263
|
worker.run_once
|
264
|
+
wait_for_execution(workflow_execution)
|
630
265
|
workflow_execution.events.map(&:event_type).last == "WorkflowExecutionCompleted"
|
631
266
|
end
|
632
267
|
|
@@ -637,7 +272,7 @@ describe "RubyFlowDecider" do
|
|
637
272
|
@activity_class.class_eval do
|
638
273
|
activity :run_activityManual do
|
639
274
|
{
|
640
|
-
:default_task_heartbeat_timeout => "
|
275
|
+
:default_task_heartbeat_timeout => "600",
|
641
276
|
:default_task_list => task_list,
|
642
277
|
:default_task_schedule_to_start_timeout => 120,
|
643
278
|
:default_task_start_to_close_timeout => 120,
|
@@ -667,9 +302,10 @@ describe "RubyFlowDecider" do
|
|
667
302
|
@worker.run_once
|
668
303
|
activity_worker.run_once
|
669
304
|
|
670
|
-
|
305
|
+
@swf.client.respond_activity_task_failed(:task_token => $task_token)
|
671
306
|
|
672
307
|
@worker.run_once
|
308
|
+
wait_for_execution(workflow_execution)
|
673
309
|
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
674
310
|
end
|
675
311
|
|
@@ -687,19 +323,20 @@ describe "RubyFlowDecider" do
|
|
687
323
|
end
|
688
324
|
end
|
689
325
|
@activity_class.class_eval do
|
690
|
-
def run_activity1
|
691
|
-
raise "Error!"
|
692
|
-
end
|
326
|
+
def run_activity1; raise "Error!"; end
|
693
327
|
end
|
328
|
+
|
329
|
+
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
330
|
+
@forking_executor.execute { @worker.start }
|
331
|
+
@forking_executor.execute { @activity_worker.start }
|
332
|
+
sleep 5
|
333
|
+
|
694
334
|
workflow_execution = @my_workflow_client.start_execution
|
695
|
-
|
696
|
-
|
697
|
-
@worker.run_once
|
698
|
-
@worker.run_once
|
699
|
-
@activity_worker.run_once
|
700
|
-
@worker.run_once
|
335
|
+
|
336
|
+
wait_for_execution(workflow_execution)
|
701
337
|
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
702
338
|
workflow_execution.events.to_a[-1].attributes.result.should =~ /Error!/
|
339
|
+
|
703
340
|
end
|
704
341
|
|
705
342
|
it "ensures that backtraces are set correctly with yaml" do
|
@@ -724,6 +361,7 @@ describe "RubyFlowDecider" do
|
|
724
361
|
@worker.run_once
|
725
362
|
@activity_worker.run_once
|
726
363
|
@worker.run_once
|
364
|
+
wait_for_execution(workflow_execution)
|
727
365
|
workflow_execution.events.to_a[-1].attributes.result.should =~ /Error!/
|
728
366
|
end
|
729
367
|
describe "Handle_ tests" do
|
@@ -733,42 +371,49 @@ describe "RubyFlowDecider" do
|
|
733
371
|
it "ensures that handle_child_workflow_execution_canceled is correct" do
|
734
372
|
class OtherCancellationChildWorkflow
|
735
373
|
extend Workflows
|
736
|
-
workflow(:entry_point) { {:version => 1, :task_list => "new_child_cancelled_workflow", :
|
374
|
+
workflow(:entry_point) { {:version => 1, :task_list => "new_child_cancelled_workflow", :default_execution_start_to_close_timeout => 600} }
|
737
375
|
def entry_point(arg)
|
738
|
-
create_timer(
|
376
|
+
create_timer(20)
|
739
377
|
end
|
740
378
|
end
|
741
379
|
class BadCancellationChildWorkflow
|
742
380
|
extend Workflows
|
743
|
-
workflow(:entry_point) { {:version => 1, :task_list => "new_parent_cancelled_workflow", :
|
381
|
+
workflow(:entry_point) { {:version => 1, :task_list => "new_parent_cancelled_workflow", :default_execution_start_to_close_timeout => 600} }
|
744
382
|
|
745
383
|
def entry_point(arg)
|
746
|
-
|
384
|
+
domain = get_test_domain
|
385
|
+
client = workflow_client(domain.client, domain) { {:from_class => "OtherCancellationChildWorkflow"} }
|
747
386
|
workflow_future = client.send_async(:start_execution, 5)
|
748
387
|
client.request_cancel_workflow_execution(workflow_future)
|
749
388
|
end
|
750
389
|
end
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
390
|
+
child_worker = WorkflowWorker.new(@swf.client, @domain, "new_child_cancelled_workflow", OtherCancellationChildWorkflow)
|
391
|
+
child_worker.register
|
392
|
+
parent_worker = WorkflowWorker.new(@swf.client, @domain, "new_parent_cancelled_workflow", BadCancellationChildWorkflow)
|
393
|
+
parent_worker.register
|
755
394
|
client = workflow_client(@swf.client, @domain) { {:from_class => "BadCancellationChildWorkflow"} }
|
756
395
|
workflow_execution = client.entry_point(5)
|
757
396
|
|
758
|
-
|
759
|
-
|
760
|
-
|
397
|
+
parent_worker.run_once
|
398
|
+
child_worker.run_once
|
399
|
+
parent_worker.run_once
|
400
|
+
|
401
|
+
wait_for_decision(workflow_execution)
|
761
402
|
workflow_execution.events.map(&:event_type).should include "ExternalWorkflowExecutionCancelRequested"
|
762
|
-
|
403
|
+
child_worker.run_once
|
404
|
+
|
405
|
+
wait_for_decision(workflow_execution, "ChildWorkflowExecutionCanceled")
|
763
406
|
workflow_execution.events.map(&:event_type).should include "ChildWorkflowExecutionCanceled"
|
764
|
-
|
407
|
+
parent_worker.run_once
|
408
|
+
|
409
|
+
wait_for_execution(workflow_execution)
|
765
410
|
workflow_execution.events.to_a.last.attributes.details.should =~ /AWS::Flow::Core::Cancellation/
|
766
411
|
end
|
767
412
|
|
768
413
|
it "ensures that handle_child_workflow_terminated is handled correctly" do
|
769
414
|
class OtherTerminationChildWorkflow
|
770
415
|
extend Workflows
|
771
|
-
workflow(:entry_point) { {:version => 1, :task_list => "new_child_terminated_workflow", :
|
416
|
+
workflow(:entry_point) { {:version => 1, :task_list => "new_child_terminated_workflow", :default_execution_start_to_close_timeout => 600} }
|
772
417
|
|
773
418
|
def entry_point(arg)
|
774
419
|
create_timer(5)
|
@@ -778,12 +423,13 @@ describe "RubyFlowDecider" do
|
|
778
423
|
$workflow_id = nil
|
779
424
|
class BadTerminationChildWorkflow
|
780
425
|
extend Workflows
|
781
|
-
workflow(:entry_point) { {:version => 1, :task_list => "new_parent_terminated_workflow", :
|
426
|
+
workflow(:entry_point) { {:version => 1, :task_list => "new_parent_terminated_workflow", :default_execution_start_to_close_timeout => 600} }
|
782
427
|
def other_entry_point
|
783
428
|
end
|
784
429
|
|
785
430
|
def entry_point(arg)
|
786
|
-
|
431
|
+
domain = get_test_domain
|
432
|
+
client = workflow_client(domain.client, domain) { {:from_class => "OtherTerminationChildWorkflow"} }
|
787
433
|
workflow_future = client.send_async(:start_execution, 5)
|
788
434
|
$workflow_id = workflow_future.workflow_execution.workflow_id.get
|
789
435
|
end
|
@@ -797,15 +443,19 @@ describe "RubyFlowDecider" do
|
|
797
443
|
|
798
444
|
worker.run_once
|
799
445
|
worker2.run_once
|
800
|
-
|
446
|
+
wait_for_decision(workflow_execution)
|
447
|
+
@swf.client.terminate_workflow_execution({:workflow_id => $workflow_id, :domain => @domain.name})
|
448
|
+
wait_for_decision(workflow_execution, "ChildWorkflowExecutionTerminated")
|
801
449
|
worker.run_once
|
450
|
+
wait_for_execution(workflow_execution)
|
451
|
+
validate_execution_failed(workflow_execution)
|
802
452
|
workflow_execution.events.to_a.last.attributes.details.should =~ /AWS::Flow::ChildWorkflowTerminatedException/
|
803
453
|
end
|
804
454
|
|
805
455
|
it "ensures that handle_child_workflow_timed_out is handled correctly" do
|
806
456
|
class OtherTimedOutChildWorkflow
|
807
457
|
extend Workflows
|
808
|
-
workflow(:entry_point) { {:version => 1, :task_list => "new_child_timed_out_workflow", :
|
458
|
+
workflow(:entry_point) { {:version => 1, :task_list => "new_child_timed_out_workflow", :default_execution_start_to_close_timeout => 5} }
|
809
459
|
|
810
460
|
def entry_point(arg)
|
811
461
|
create_timer(5)
|
@@ -815,12 +465,13 @@ describe "RubyFlowDecider" do
|
|
815
465
|
$workflow_id = nil
|
816
466
|
class BadTimedOutChildWorkflow
|
817
467
|
extend Workflows
|
818
|
-
workflow(:entry_point) { {:version => 1, :task_list => "new_parent_timed_out_workflow", :
|
468
|
+
workflow(:entry_point) { {:version => 1, :task_list => "new_parent_timed_out_workflow", :default_execution_start_to_close_timeout => 600} }
|
819
469
|
def other_entry_point
|
820
470
|
end
|
821
471
|
|
822
472
|
def entry_point(arg)
|
823
|
-
|
473
|
+
domain = get_test_domain
|
474
|
+
client = workflow_client(domain.client, domain) { {:from_class => "OtherTimedOutChildWorkflow"} }
|
824
475
|
workflow_future = client.send_async(:start_execution, 5)
|
825
476
|
$workflow_id = workflow_future.workflow_execution.workflow_id.get
|
826
477
|
end
|
@@ -834,6 +485,7 @@ describe "RubyFlowDecider" do
|
|
834
485
|
worker.run_once
|
835
486
|
sleep 8
|
836
487
|
worker.run_once
|
488
|
+
wait_for_execution(workflow_execution)
|
837
489
|
workflow_execution.events.to_a.last.attributes.details.should =~ /AWS::Flow::ChildWorkflowTimedOutException/
|
838
490
|
end
|
839
491
|
|
@@ -843,9 +495,9 @@ describe "RubyFlowDecider" do
|
|
843
495
|
extend Workflows
|
844
496
|
workflow :bad_workflow do
|
845
497
|
{
|
846
|
-
:
|
847
|
-
:
|
848
|
-
:
|
498
|
+
version: "1.0",
|
499
|
+
default_execution_start_to_close_timeout: 600,
|
500
|
+
default_task_list: "handle_start_child_workflow_execution_failed_child"
|
849
501
|
}
|
850
502
|
end
|
851
503
|
def bad_workflow
|
@@ -854,125 +506,129 @@ describe "RubyFlowDecider" do
|
|
854
506
|
end
|
855
507
|
@workflow_class.class_eval do
|
856
508
|
def entry_point
|
857
|
-
|
509
|
+
domain = get_test_domain
|
510
|
+
wf = AWS::Flow.workflow_client(domain.client, domain) { { from_class: "FooBar" } }
|
858
511
|
wf.start_execution("foo")
|
859
512
|
end
|
860
513
|
end
|
861
514
|
workflow_execution = @my_workflow_client.start_execution
|
862
|
-
child_worker = WorkflowWorker.new(
|
515
|
+
child_worker = WorkflowWorker.new(@domain.client, @domain, "handle_start_child_workflow_execution_failed_child", FooBar)
|
863
516
|
child_worker.register
|
864
517
|
@worker.run_once
|
865
518
|
child_worker.run_once
|
866
519
|
@worker.run_once
|
520
|
+
wait_for_execution(workflow_execution)
|
867
521
|
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
|
868
522
|
# Make sure this is actually caused by a child workflow failed
|
869
523
|
workflow_execution.events.to_a.last.attributes.details.should =~ /ChildWorkflowFailed/
|
870
524
|
end
|
871
525
|
|
872
526
|
it "ensures that handle_timer_canceled is fine" do
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
end
|
880
|
-
t.rescue(CancellationException) {}
|
527
|
+
general_test(:task_list => "handle_timer_canceled", :class_name => "HandleTimerCanceled")
|
528
|
+
@workflow_class.class_eval do
|
529
|
+
def entry_point
|
530
|
+
bre = error_handler do |t|
|
531
|
+
t.begin do
|
532
|
+
create_timer(100)
|
881
533
|
end
|
882
|
-
|
883
|
-
bre.cancel(CancellationException.new)
|
534
|
+
t.rescue(CancellationException) {}
|
884
535
|
end
|
536
|
+
create_timer(1)
|
537
|
+
bre.cancel(CancellationException.new)
|
885
538
|
end
|
886
|
-
workflow_execution = @my_workflow_client.start_execution
|
887
|
-
@worker.run_once
|
888
|
-
@worker.run_once
|
889
|
-
workflow_history = workflow_execution.events.map(&:event_type)
|
890
|
-
workflow_history.count("TimerCanceled").should == 1
|
891
|
-
workflow_history.count("WorkflowExecutionCompleted").should == 1
|
892
539
|
end
|
540
|
+
workflow_execution = @my_workflow_client.start_execution
|
541
|
+
@worker.run_once
|
542
|
+
@worker.run_once
|
543
|
+
wait_for_execution(workflow_execution)
|
544
|
+
workflow_history = workflow_execution.events.map(&:event_type)
|
545
|
+
workflow_history.count("TimerCanceled").should == 1
|
546
|
+
workflow_history.count("WorkflowExecutionCompleted").should == 1
|
547
|
+
end
|
893
548
|
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
end
|
901
|
-
create_timer(1)
|
902
|
-
bre.cancel(CancellationException.new)
|
549
|
+
it "ensures that activities under a bre get cancelled" do
|
550
|
+
general_test(:task_list => "activite under bre", :class_name => "ActivitiesUnderBRE")
|
551
|
+
@workflow_class.class_eval do
|
552
|
+
def entry_point
|
553
|
+
bre = error_handler do |t|
|
554
|
+
t.begin { activity.send_async(:run_activity1) }
|
903
555
|
end
|
556
|
+
create_timer(1)
|
557
|
+
bre.cancel(CancellationException.new)
|
904
558
|
end
|
905
|
-
workflow_execution = @my_workflow_client.start_execution
|
906
|
-
@worker.run_once
|
907
|
-
@worker.run_once
|
908
|
-
workflow_execution.events.map(&:event_type).count("ActivityTaskCancelRequested").should == 1
|
909
|
-
@worker.run_once
|
910
|
-
workflow_execution.events.to_a.last.attributes.reason.should == "AWS::Flow::Core::CancellationException"
|
911
559
|
end
|
560
|
+
workflow_execution = @my_workflow_client.start_execution
|
561
|
+
@worker.run_once
|
562
|
+
@worker.run_once
|
563
|
+
workflow_execution.events.map(&:event_type).count("ActivityTaskCancelRequested").should == 1
|
564
|
+
@worker.run_once
|
565
|
+
wait_for_execution(workflow_execution)
|
566
|
+
workflow_execution.events.to_a.last.attributes.reason.should == "AWS::Flow::Core::CancellationException"
|
567
|
+
end
|
912
568
|
|
913
|
-
|
914
|
-
|
915
|
-
|
569
|
+
it "ensures that start_timer_failed is handled correctly" do
|
570
|
+
general_test(:task_list => "start_timer_failed", :class_name => "StartTimerFailed")
|
571
|
+
end
|
916
572
|
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
end
|
573
|
+
it "ensures that get_state_method works fine" do
|
574
|
+
general_test(:task_list => "get_state_method", :class_name => "GetStateTest")
|
575
|
+
@workflow_class.class_eval do
|
576
|
+
get_state_method :get_state_test
|
577
|
+
def get_state_test
|
578
|
+
"This is the workflow state!"
|
924
579
|
end
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
580
|
+
end
|
581
|
+
workflow_execution = @my_workflow_client.start_execution
|
582
|
+
worker = WorkflowWorker.new(@swf.client, @domain, "get_state_method", @workflow_class)
|
583
|
+
worker.run_once
|
584
|
+
workflow_execution.events.to_a[3].attributes.execution_context.should =~ /This is the workflow state!/
|
585
|
+
end
|
586
|
+
|
587
|
+
it "ensures that handle_request_cancel_activity_task_failed works" do
|
588
|
+
general_test(:task_list => "handle_request_cancel_activity_task_failed", :class_name => "HandleRCActivityTaskFailed")
|
589
|
+
class AsyncDecider
|
590
|
+
alias_method :old_handle_request_cancel_activity_task_failed, :handle_request_cancel_activity_task_failed
|
591
|
+
# We have to replace this method, otherwise we'd fail on handling the
|
592
|
+
# error because we can't find the decision in the decision_map. There
|
593
|
+
# is similar behavior in javaflow
|
594
|
+
def handle_request_cancel_activity_task_failed(event)
|
595
|
+
event_double = SimpleTestHistoryEvent.new("Activity1")
|
596
|
+
self.send(:old_handle_request_cancel_activity_task_failed, event_double)
|
942
597
|
end
|
598
|
+
end
|
943
599
|
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
end
|
600
|
+
class ActivityDecisionStateMachine
|
601
|
+
alias_method :old_create_request_cancel_activity_task_decision, :create_request_cancel_activity_task_decision
|
602
|
+
def create_request_cancel_activity_task_decision
|
603
|
+
{ :decision_type => "RequestCancelActivityTask",
|
604
|
+
:request_cancel_activity_task_decision_attributes => {:activity_id => "bad_id"} }
|
950
605
|
end
|
606
|
+
end
|
951
607
|
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
end
|
608
|
+
@workflow_class.class_eval do
|
609
|
+
def entry_point
|
610
|
+
future = activity.send_async(:run_activity1)
|
611
|
+
create_timer(1)
|
612
|
+
activity.request_cancel_activity_task(future)
|
958
613
|
end
|
614
|
+
end
|
959
615
|
|
960
616
|
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
617
|
+
workflow_execution = @my_workflow_client.start_execution
|
618
|
+
@worker.run_once
|
619
|
+
@worker.run_once
|
620
|
+
@worker.run_once
|
965
621
|
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
end
|
972
|
-
class ActivityDecisionStateMachine
|
973
|
-
alias_method :create_request_cancel_activity_task_decision,:old_create_request_cancel_activity_task_decision
|
974
|
-
end
|
622
|
+
# In the future, we might want to verify that it transitions the state
|
623
|
+
# machine properly, but at a base, it should not fail the workflow.
|
624
|
+
workflow_execution.events.map(&:event_type).last.should == "DecisionTaskCompleted"
|
625
|
+
class AsyncDecider
|
626
|
+
alias_method :handle_request_cancel_activity_task_failed, :old_handle_request_cancel_activity_task_failed
|
975
627
|
end
|
628
|
+
class ActivityDecisionStateMachine
|
629
|
+
alias_method :create_request_cancel_activity_task_decision,:old_create_request_cancel_activity_task_decision
|
630
|
+
end
|
631
|
+
end
|
976
632
|
end
|
977
633
|
|
978
634
|
|
@@ -1016,6 +672,7 @@ describe "RubyFlowDecider" do
|
|
1016
672
|
@worker.run_once
|
1017
673
|
@activity_worker.run_once
|
1018
674
|
@worker.run_once
|
675
|
+
wait_for_execution(workflow_execution)
|
1019
676
|
# TODO Kinda hacky, we should be using the workflow_class's data_converter
|
1020
677
|
workflow_execution.events.to_a.last.attributes[:result].include? "false"
|
1021
678
|
end
|
@@ -1038,21 +695,37 @@ describe "RubyFlowDecider" do
|
|
1038
695
|
|
1039
696
|
end
|
1040
697
|
end
|
698
|
+
|
699
|
+
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
700
|
+
@forking_executor.execute { @worker.start }
|
701
|
+
@forking_executor.execute { @activity_worker.start }
|
702
|
+
|
1041
703
|
workflow_execution = @my_workflow_client.start_execution
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
@worker.run_once
|
704
|
+
|
705
|
+
wait_for_execution(workflow_execution)
|
706
|
+
|
1046
707
|
history = workflow_execution.events.map(&:event_type)
|
1047
708
|
history.last.should == "WorkflowExecutionFailed"
|
1048
|
-
|
709
|
+
|
710
|
+
history.should include "ActivityTaskCancelRequested"
|
711
|
+
#@worker.run_once
|
712
|
+
#@activity_worker.run_once
|
713
|
+
#wait_for_decision(workflow_execution)
|
714
|
+
#@worker.run_once
|
715
|
+
#wait_for_decision(workflow_execution)
|
716
|
+
#@worker.run_once
|
717
|
+
|
718
|
+
#wait_for_execution(workflow_execution)
|
719
|
+
#history = workflow_execution.events.map(&:event_type)
|
720
|
+
#history.last.should == "WorkflowExecutionFailed"
|
721
|
+
## Should look something like: ["WorkflowExecutionStarted",
|
1049
722
|
# "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted",
|
1050
723
|
# "ActivityTaskScheduled", "ActivityTaskScheduled", "ActivityTaskStarted",
|
1051
724
|
# "ActivityTaskFailed", "DecisionTaskScheduled", "DecisionTaskStarted",
|
1052
725
|
# "DecisionTaskCompleted", "ActivityTaskCancelRequested",
|
1053
726
|
# "ActivityTaskCanceled", "DecisionTaskScheduled", "DecisionTaskStarted",
|
1054
727
|
# "DecisionTaskCompleted", "WorkflowExecutionFailed"]
|
1055
|
-
history.should include "ActivityTaskCancelRequested"
|
728
|
+
#history.should include "ActivityTaskCancelRequested"
|
1056
729
|
end
|
1057
730
|
|
1058
731
|
it "makes sure that you can use the :exponential_retry key" do
|
@@ -1069,6 +742,7 @@ describe "RubyFlowDecider" do
|
|
1069
742
|
end
|
1070
743
|
workflow_execution = @my_workflow_client.start_execution
|
1071
744
|
4.times { @worker.run_once }
|
745
|
+
wait_for_execution(workflow_execution)
|
1072
746
|
workflow_execution.events.to_a.last.event_type.should == "WorkflowExecutionFailed"
|
1073
747
|
end
|
1074
748
|
|
@@ -1080,7 +754,7 @@ describe "RubyFlowDecider" do
|
|
1080
754
|
logger.level = Logger::DEBUG
|
1081
755
|
worker = WorkflowWorker.new(@swf.client, @domain, "arbitrary logger", @workflow_class) { {:logger => logger} }
|
1082
756
|
activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary logger", @activity_class) { { :logger => logger, :execution_workers => 20, :use_forking => false} }
|
1083
|
-
|
757
|
+
workflow_execution = @my_workflow_client.start_execution
|
1084
758
|
worker.run_once
|
1085
759
|
file = File.open(testing_file)
|
1086
760
|
# The file should have something in it(i.e., not blank)
|
@@ -1097,9 +771,10 @@ describe "RubyFlowDecider" do
|
|
1097
771
|
raise Exception
|
1098
772
|
end
|
1099
773
|
end
|
1100
|
-
|
774
|
+
workflow_execution = @my_workflow_client.start_execution
|
1101
775
|
@worker.run_once
|
1102
|
-
|
776
|
+
wait_for_execution(workflow_execution)
|
777
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
|
1103
778
|
end
|
1104
779
|
it "makes sure that the return value of an activity is directly useable" do
|
1105
780
|
general_test(:task_list => "return value activity", :class_name => "ActivityReturn")
|
@@ -1114,7 +789,7 @@ describe "RubyFlowDecider" do
|
|
1114
789
|
x.should == 5
|
1115
790
|
end
|
1116
791
|
end
|
1117
|
-
|
792
|
+
workflow_execution = @my_workflow_client.start_execution
|
1118
793
|
@worker.run_once
|
1119
794
|
@activity_worker.run_once
|
1120
795
|
@worker.run_once
|
@@ -1126,87 +801,71 @@ describe "RubyFlowDecider" do
|
|
1126
801
|
workflow_id
|
1127
802
|
end
|
1128
803
|
end
|
1129
|
-
|
804
|
+
workflow_execution = @my_workflow_client.start_execution
|
1130
805
|
@worker.run_once
|
1131
|
-
|
806
|
+
wait_for_execution(workflow_execution)
|
807
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
1132
808
|
end
|
1133
809
|
it "makes sure that arguments get passed correctly" do
|
1134
810
|
task_list = "argument_task_list"
|
1135
|
-
class
|
1136
|
-
class << self; attr_accessor :task_list; end
|
1137
|
-
end
|
1138
|
-
class ArgumentWorkflow
|
811
|
+
class TaskListProvider
|
1139
812
|
class << self; attr_accessor :task_list; end
|
1140
813
|
end
|
814
|
+
TaskListProvider.task_list = task_list
|
1141
815
|
|
1142
|
-
ArgumentActivity
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
options.default_task_schedule_to_close_timeout = "3600"
|
1153
|
-
options.default_task_schedule_to_start_timeout = "3600"
|
1154
|
-
options.default_task_start_to_close_timeout = "3600"
|
1155
|
-
options.version = "1"
|
816
|
+
class ArgumentActivity < TaskListProvider
|
817
|
+
extend AWS::Flow::Activities
|
818
|
+
activity :run_activity1 do
|
819
|
+
{
|
820
|
+
version: "1.0",
|
821
|
+
default_task_list: self.task_list,
|
822
|
+
default_task_schedule_to_close_timeout: "120",
|
823
|
+
default_task_schedule_to_start_timeout: "60",
|
824
|
+
default_task_start_to_close_timeout: "60"
|
825
|
+
}
|
1156
826
|
end
|
827
|
+
|
1157
828
|
def run_activity1(arg)
|
1158
829
|
arg.should == 5
|
1159
830
|
arg + 1
|
1160
831
|
end
|
1161
832
|
end
|
1162
|
-
class ArgumentWorkflow
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
options.default_task_list = ArgumentWorkflow.task_list
|
1173
|
-
options.default_task_schedule_to_close_timeout = "3600"
|
1174
|
-
options.default_task_schedule_to_start_timeout = "3600"
|
1175
|
-
options.default_task_start_to_close_timeout = "3600"
|
1176
|
-
|
833
|
+
class ArgumentWorkflow < TaskListProvider
|
834
|
+
extend AWS::Flow::Workflows
|
835
|
+
workflow :entry_point do
|
836
|
+
{
|
837
|
+
version: "1.0",
|
838
|
+
default_execution_start_to_close_timeout: 600,
|
839
|
+
default_task_list: self.task_list,
|
840
|
+
default_task_start_to_close_timeout: 10,
|
841
|
+
default_child_policy: :request_cancel,
|
842
|
+
}
|
1177
843
|
end
|
844
|
+
activity_client(:activity) { { from_class: "ArgumentActivity" } }
|
1178
845
|
def entry_point(arg)
|
1179
846
|
arg.should == 5
|
1180
847
|
activity.run_activity1(arg)
|
1181
848
|
end
|
1182
849
|
end
|
1183
850
|
|
1184
|
-
worker = WorkflowWorker.new(@
|
1185
|
-
|
1186
|
-
activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
|
1187
|
-
activity_worker.add_activities_implementation(ArgumentActivity)
|
851
|
+
worker = WorkflowWorker.new(@domain.client, @domain, task_list, ArgumentWorkflow)
|
852
|
+
activity_worker = ActivityWorker.new(@domain.client, @domain, task_list, ArgumentActivity)
|
1188
853
|
worker.register
|
1189
854
|
activity_worker.register
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
options.task_list = "argument_task_list"
|
1194
|
-
options.task_start_to_close_timeout = 10
|
1195
|
-
options.child_policy = :request_cancel
|
1196
|
-
end
|
1197
|
-
my_workflow = my_workflow_factory.get_client
|
1198
|
-
workflow_execution = my_workflow.start_execution(5)
|
855
|
+
client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "ArgumentWorkflow" } }
|
856
|
+
|
857
|
+
workflow_execution = client.start_execution(5)
|
1199
858
|
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
1200
859
|
@forking_executor.execute { worker.start }
|
1201
|
-
sleep 4
|
1202
860
|
@forking_executor.execute { activity_worker.start }
|
1203
861
|
|
1204
|
-
|
862
|
+
wait_for_execution(workflow_execution)
|
1205
863
|
workflow_execution.events.map(&:event_type).should ==
|
1206
864
|
["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
|
1207
865
|
workflow_execution.events.to_a.last.attributes[:result].should =~ /6/
|
1208
866
|
@forking_executor.shutdown(1)
|
1209
867
|
end
|
868
|
+
|
1210
869
|
it "makes sure that a standard error works" do
|
1211
870
|
general_test(:task_list => "regular error raise", :class_name => "StandardError")
|
1212
871
|
@workflow_class.class_eval do
|
@@ -1225,6 +884,7 @@ describe "RubyFlowDecider" do
|
|
1225
884
|
@worker.run_once
|
1226
885
|
@activity_worker.run_once
|
1227
886
|
@worker.run_once
|
887
|
+
wait_for_execution(workflow_execution)
|
1228
888
|
|
1229
889
|
workflow_execution.events.map(&:event_type).count("WorkflowExecutionFailed").should == 1
|
1230
890
|
end
|
@@ -1234,7 +894,7 @@ describe "RubyFlowDecider" do
|
|
1234
894
|
general_test(:task_list => "exceptions_to_include", :class_name => "ExceptionsToInclude")
|
1235
895
|
@workflow_class.class_eval do
|
1236
896
|
def entry_point
|
1237
|
-
activity.exponential_retry(:run_activity1) {
|
897
|
+
activity.exponential_retry(:run_activity1) { {:exceptions_to_exclude => [SecurityError] } }
|
1238
898
|
end
|
1239
899
|
end
|
1240
900
|
@activity_class.class_eval do
|
@@ -1246,6 +906,7 @@ describe "RubyFlowDecider" do
|
|
1246
906
|
@worker.run_once
|
1247
907
|
@activity_worker.run_once
|
1248
908
|
@worker.run_once
|
909
|
+
wait_for_execution(workflow_execution)
|
1249
910
|
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
|
1250
911
|
end
|
1251
912
|
class YAMLPlusOne
|
@@ -1265,7 +926,7 @@ describe "RubyFlowDecider" do
|
|
1265
926
|
:data_converter => YAMLPlusOne.new,
|
1266
927
|
:default_task_list => "different converter activity",
|
1267
928
|
:version => "1",
|
1268
|
-
:default_task_heartbeat_timeout => "
|
929
|
+
:default_task_heartbeat_timeout => "600",
|
1269
930
|
:default_task_schedule_to_close_timeout => "60",
|
1270
931
|
:default_task_schedule_to_start_timeout => "60",
|
1271
932
|
:default_task_start_to_close_timeout => "60",
|
@@ -1278,7 +939,7 @@ describe "RubyFlowDecider" do
|
|
1278
939
|
activity_worker = ActivityWorker.new(@swf.client, @domain,"different converter activity", DifferentActivityConverterActivity)
|
1279
940
|
class DifferentActivityConverterWorkflow
|
1280
941
|
extend Workflows
|
1281
|
-
workflow(:entry_point) { {:version => "1", :
|
942
|
+
workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "different converter activity"} }
|
1282
943
|
activity_client(:activity) { { :from_class => DifferentActivityConverterActivity } }
|
1283
944
|
def entry_point
|
1284
945
|
activity.test_converter
|
@@ -1307,9 +968,8 @@ describe "RubyFlowDecider" do
|
|
1307
968
|
workflow_execution = @my_workflow_client.start_execution
|
1308
969
|
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
1309
970
|
@forking_executor.execute { @worker.start }
|
1310
|
-
sleep 10
|
1311
971
|
@forking_executor.execute { @activity_worker.start }
|
1312
|
-
|
972
|
+
wait_for_execution(workflow_execution)
|
1313
973
|
workflow_execution.events.map(&:event_type).should ==
|
1314
974
|
["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "TimerStarted", "TimerFired", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
|
1315
975
|
@forking_executor.shutdown(1)
|
@@ -1326,9 +986,8 @@ describe "RubyFlowDecider" do
|
|
1326
986
|
workflow_execution = @my_workflow_client.start_execution
|
1327
987
|
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
1328
988
|
@forking_executor.execute { @worker.start }
|
1329
|
-
sleep 10
|
1330
989
|
@forking_executor.execute { @activity_worker.start }
|
1331
|
-
|
990
|
+
wait_for_execution(workflow_execution)
|
1332
991
|
@forking_executor.shutdown(1)
|
1333
992
|
workflow_execution.events.map(&:event_type).should ==
|
1334
993
|
["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "TimerStarted", "TimerFired", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
|
@@ -1345,10 +1004,10 @@ describe "RubyFlowDecider" do
|
|
1345
1004
|
workflow_execution = @my_workflow_client.start_execution
|
1346
1005
|
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
1347
1006
|
@forking_executor.execute { @worker.start }
|
1348
|
-
sleep 5
|
1349
1007
|
@forking_executor.execute { @activity_worker.start }
|
1350
1008
|
|
1351
|
-
|
1009
|
+
wait_for_execution(workflow_execution)
|
1010
|
+
|
1352
1011
|
@forking_executor.shutdown(1)
|
1353
1012
|
after_first_decision = workflow_execution.events.to_a.slice(4, 2).map(&:event_type)
|
1354
1013
|
after_first_decision.should include "TimerStarted"
|
@@ -1364,15 +1023,14 @@ describe "RubyFlowDecider" do
|
|
1364
1023
|
end
|
1365
1024
|
@activity_worker = ActivityWorker.new(@swf.client, @domain, "async timer with block", AsyncBlockActivity)
|
1366
1025
|
@activity_worker.register
|
1367
|
-
|
1026
|
+
workflow_execution = @my_workflow_client.start_execution
|
1368
1027
|
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
1369
1028
|
@forking_executor.execute { @worker.start }
|
1370
|
-
sleep 5
|
1371
1029
|
@forking_executor.execute { @activity_worker.start }
|
1372
|
-
|
1030
|
+
wait_for_execution(workflow_execution)
|
1373
1031
|
@forking_executor.shutdown(1)
|
1374
|
-
activity_scheduled =
|
1375
|
-
history_events =
|
1032
|
+
activity_scheduled = workflow_execution.events.to_a.each_with_index.map{|x, i| i if x.event_type == "ActivityTaskScheduled"}.compact
|
1033
|
+
history_events = workflow_execution.events.to_a
|
1376
1034
|
history_events[activity_scheduled.first - 1].event_type == "TimerStarted" ||
|
1377
1035
|
history_events[activity_scheduled.first + 1].event_type == "TimerStarted"
|
1378
1036
|
history_events[activity_scheduled.first].attributes[:activity_type].name.should == "AsyncBlockActivity.run_activity2"
|
@@ -1381,215 +1039,202 @@ describe "RubyFlowDecider" do
|
|
1381
1039
|
|
1382
1040
|
describe "Child Workflows" do
|
1383
1041
|
|
1384
|
-
|
1385
|
-
class OtherChildWorkflow
|
1386
|
-
extend Decider
|
1387
|
-
version "1"
|
1388
|
-
entry_point :entry_point
|
1389
|
-
def entry_point(arg)
|
1390
|
-
sleep 1
|
1391
|
-
end
|
1042
|
+
it "is a basic child workflow test" do
|
1392
1043
|
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
client = workflow_client do |options|
|
1402
|
-
options.workflow_name = "OtherChildWorkflow"
|
1403
|
-
options.execution_method = "entry_point"
|
1404
|
-
options.execution_start_to_close_timeout = 3600
|
1405
|
-
options.task_start_to_close_timeout = 10
|
1406
|
-
options.version = "1"
|
1407
|
-
options.task_list = "test2"
|
1044
|
+
class ChildWorkflowsTestChildWorkflow
|
1045
|
+
extend AWS::Flow::Workflows
|
1046
|
+
workflow :child do
|
1047
|
+
{
|
1048
|
+
version: "1.0",
|
1049
|
+
default_execution_start_to_close_timeout: 600,
|
1050
|
+
default_task_start_to_close_timeout: 10,
|
1051
|
+
}
|
1408
1052
|
end
|
1409
|
-
|
1410
|
-
client.send_async(:start_execution, 5)
|
1411
|
-
client.send_async(:start_execution, 5)
|
1053
|
+
def child; sleep 1; end
|
1412
1054
|
end
|
1413
|
-
end
|
1414
|
-
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
1415
|
-
options.workflow_name = "BadChildWorkflow"
|
1416
|
-
options.execution_start_to_close_timeout = 3600
|
1417
|
-
options.task_list = "test"
|
1418
|
-
options.version = "1"
|
1419
|
-
end
|
1420
|
-
worker2 = WorkflowWorker.new(@swf.client, @domain, "test2")
|
1421
|
-
worker2.add_workflow_implementation(OtherChildWorkflow)
|
1422
|
-
worker2.register
|
1423
|
-
worker = WorkflowWorker.new(@swf.client, @domain, "test")
|
1424
|
-
worker.add_workflow_implementation(BadChildWorkflow)
|
1425
|
-
worker.register
|
1426
|
-
sleep 5
|
1427
|
-
my_workflow_client = my_workflow_factory.get_client
|
1428
|
-
workflow_execution = my_workflow_client.entry_point(5)
|
1429
|
-
# sleep 10
|
1430
1055
|
|
1431
|
-
|
1432
|
-
|
1056
|
+
class ChildWorkflowsTestParentWorkflow
|
1057
|
+
extend AWS::Flow::Workflows
|
1058
|
+
workflow :parent do
|
1059
|
+
{
|
1060
|
+
version: "1.0",
|
1061
|
+
default_execution_start_to_close_timeout: 600,
|
1062
|
+
default_task_list: "test"
|
1063
|
+
}
|
1064
|
+
end
|
1065
|
+
def parent
|
1066
|
+
domain = get_test_domain
|
1067
|
+
client = AWS::Flow::workflow_client(domain.client, domain) { { from_class: "ChildWorkflowsTestChildWorkflow", task_list: "test2" } }
|
1068
|
+
client.send_async(:start_execution)
|
1069
|
+
client.send_async(:start_execution)
|
1070
|
+
end
|
1071
|
+
end
|
1433
1072
|
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
worker.run_once
|
1438
|
-
# Appears to a case that happens sometimes where the history looks like
|
1439
|
-
# ["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "StartChildWorkflowExecutionInitiated", "StartChildWorkflowExecutionInitiated", "ChildWorkflowExecutionStarted", "DecisionTaskScheduled", "ChildWorkflowExecutionStarted", "ChildWorkflowExecutionCompleted", "DecisionTaskStarted", "ChildWorkflowExecutionCompleted", "DecisionTaskScheduled", "DecisionTaskCompleted"]
|
1440
|
-
# In order to deal with this, we have the following line below
|
1441
|
-
worker.run_once if workflow_execution.events.map(&:event_type).last == "DecisionTaskCompleted"
|
1442
|
-
events = workflow_execution.events.map(&:event_type)
|
1443
|
-
workflow_execution.events.to_a.last.attributes.result.should_not =~ /secret_access_key/
|
1444
|
-
events.should include "ChildWorkflowExecutionStarted"
|
1445
|
-
events.should include "ChildWorkflowExecutionCompleted"
|
1446
|
-
events.should include "WorkflowExecutionCompleted"
|
1447
|
-
end
|
1073
|
+
parent_client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "ChildWorkflowsTestParentWorkflow" } }
|
1074
|
+
@child_worker = WorkflowWorker.new(@domain.client, @domain, "test2", ChildWorkflowsTestChildWorkflow)
|
1075
|
+
@parent_worker = WorkflowWorker.new(@domain.client, @domain, "test", ChildWorkflowsTestParentWorkflow)
|
1448
1076
|
|
1449
|
-
|
1450
|
-
|
1077
|
+
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
1078
|
+
@forking_executor.execute { @parent_worker.start }
|
1079
|
+
@forking_executor.execute { @child_worker.start }
|
1080
|
+
@forking_executor.execute { @child_worker.start }
|
1081
|
+
sleep 2
|
1451
1082
|
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
self.class.replaying_hash[name] << decision_context.workflow_clock.replaying
|
1459
|
-
self.class.time_hash[name] << decision_context.workflow_clock.current_time
|
1460
|
-
end
|
1461
|
-
record_point(:first)
|
1462
|
-
create_timer(5)
|
1463
|
-
record_point(:second)
|
1464
|
-
create_timer(3)
|
1465
|
-
record_point(:third)
|
1466
|
-
end
|
1467
|
-
end
|
1468
|
-
@workflow_class.time_hash = Hash.new {|hash, key| hash[key] = []}
|
1469
|
-
@workflow_class.replaying_hash = Hash.new {|hash, key| hash[key] = []}
|
1470
|
-
workflow_execution = @my_workflow_client.start_execution
|
1471
|
-
3.times { @worker.run_once }
|
1472
|
-
# Maintain the invariant that you should *not* be replaying only once
|
1473
|
-
@workflow_class.replaying_hash.values.each {|x| x.count(false).should be 1}
|
1474
|
-
# Maintain the invariant that at the same point in the code,
|
1475
|
-
# replay_current_time_millis will return the same value
|
1476
|
-
@workflow_class.time_hash.values.each do |array|
|
1477
|
-
array.reduce {|first, second| first if first.should == second}
|
1083
|
+
workflow_execution = parent_client.start_execution
|
1084
|
+
wait_for_execution(workflow_execution)
|
1085
|
+
|
1086
|
+
events = workflow_execution.events.map(&:event_type)
|
1087
|
+
workflow_execution.events.to_a.last.attributes.result.should_not =~ /secret_access_key/
|
1088
|
+
events.should include("ChildWorkflowExecutionStarted", "ChildWorkflowExecutionCompleted", "WorkflowExecutionCompleted")
|
1478
1089
|
end
|
1479
|
-
end
|
1480
1090
|
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1091
|
+
it "ensures that workflow clock provides at least basic support for current_time_millis" do
|
1092
|
+
general_test(:task_list => "workflow_clock_basic", :class_name => "WorkflowClockBasic")
|
1093
|
+
|
1094
|
+
@workflow_class.class_eval do
|
1095
|
+
class << self
|
1096
|
+
attr_accessor :time_hash, :replaying_hash
|
1097
|
+
end
|
1098
|
+
def entry_point
|
1099
|
+
def record_point(name)
|
1100
|
+
self.class.replaying_hash[name] << decision_context.workflow_clock.replaying
|
1101
|
+
self.class.time_hash[name] << decision_context.workflow_clock.current_time
|
1102
|
+
end
|
1103
|
+
record_point(:first)
|
1104
|
+
create_timer(5)
|
1105
|
+
record_point(:second)
|
1106
|
+
create_timer(3)
|
1107
|
+
record_point(:third)
|
1108
|
+
end
|
1487
1109
|
end
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1110
|
+
@workflow_class.time_hash = Hash.new {|hash, key| hash[key] = []}
|
1111
|
+
@workflow_class.replaying_hash = Hash.new {|hash, key| hash[key] = []}
|
1112
|
+
workflow_execution = @my_workflow_client.start_execution
|
1113
|
+
3.times { @worker.run_once }
|
1114
|
+
# Maintain the invariant that you should *not* be replaying only once
|
1115
|
+
@workflow_class.replaying_hash.values.each {|x| x.count(false).should be 1}
|
1116
|
+
# Maintain the invariant that at the same point in the code,
|
1117
|
+
# replay_current_time_millis will return the same value
|
1118
|
+
@workflow_class.time_hash.values.each do |array|
|
1119
|
+
array.reduce {|first, second| first if first.should == second}
|
1120
|
+
end
|
1121
|
+
end
|
1122
|
+
|
1123
|
+
it "ensures that a child workflow failing raises a ChildWorkflowExecutionFailed" do
|
1124
|
+
class FailingChildChildWorkflow
|
1125
|
+
extend Workflows
|
1126
|
+
workflow(:entry_point) { {:version => 1, :task_list => "failing_child_workflow", :default_execution_start_to_close_timeout => 600} }
|
1127
|
+
def entry_point(arg)
|
1128
|
+
raise "simulated error"
|
1129
|
+
end
|
1493
1130
|
end
|
1131
|
+
class FailingHostChildWorkflow
|
1132
|
+
extend Workflows
|
1133
|
+
workflow(:entry_point) { {:version => 1, :task_list => "failing_parent_workflow", :default_execution_start_to_close_timeout => 600} }
|
1134
|
+
def other_entry_point
|
1135
|
+
end
|
1494
1136
|
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1137
|
+
def entry_point(arg)
|
1138
|
+
domain = get_test_domain
|
1139
|
+
client = workflow_client(domain.client, domain) { {:from_class => "FailingChildChildWorkflow"} }
|
1140
|
+
begin
|
1141
|
+
client.start_execution(5)
|
1142
|
+
rescue Exception => e
|
1143
|
+
#pass
|
1144
|
+
end
|
1501
1145
|
end
|
1502
1146
|
end
|
1147
|
+
worker2 = WorkflowWorker.new(@swf.client, @domain, "failing_child_workflow", FailingChildChildWorkflow)
|
1148
|
+
worker2.register
|
1149
|
+
worker = WorkflowWorker.new(@swf.client, @domain, "failing_parent_workflow", FailingHostChildWorkflow)
|
1150
|
+
worker.register
|
1151
|
+
client = workflow_client(@swf.client, @domain) { {:from_class => "FailingHostChildWorkflow"} }
|
1152
|
+
workflow_execution = client.entry_point(5)
|
1153
|
+
worker.run_once
|
1154
|
+
worker2.run_once
|
1155
|
+
worker2.run_once
|
1156
|
+
worker.run_once
|
1157
|
+
events = workflow_execution.events.map(&:event_type)
|
1158
|
+
events.should include "ChildWorkflowExecutionFailed"
|
1159
|
+
events.should include "WorkflowExecutionCompleted"
|
1503
1160
|
end
|
1504
|
-
worker2 = WorkflowWorker.new(@swf.client, @domain, "failing_child_workflow", FailingChildChildWorkflow)
|
1505
|
-
worker2.register
|
1506
|
-
worker = WorkflowWorker.new(@swf.client, @domain, "failing_parent_workflow", FailingHostChildWorkflow)
|
1507
|
-
worker.register
|
1508
|
-
client = workflow_client(@swf.client, @domain) { {:from_class => "FailingHostChildWorkflow"} }
|
1509
|
-
workflow_execution = client.entry_point(5)
|
1510
|
-
worker.run_once
|
1511
|
-
worker2.run_once
|
1512
|
-
worker2.run_once
|
1513
|
-
worker.run_once
|
1514
|
-
events = workflow_execution.events.map(&:event_type)
|
1515
|
-
events.should include "ChildWorkflowExecutionFailed"
|
1516
|
-
events.should include "WorkflowExecutionCompleted"
|
1517
|
-
end
|
1518
1161
|
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
end
|
1527
|
-
class DataConverterHostChildWorkflow
|
1528
|
-
extend Workflows
|
1529
|
-
workflow(:entry_point) { {:version => 1, :task_list => "data_converter_parent_workflow", :execution_start_to_close_timeout => 3600} }
|
1530
|
-
def other_entry_point
|
1162
|
+
it "ensures that a child workflow can use data_converter correctly" do
|
1163
|
+
class DataConverterChildChildWorkflow
|
1164
|
+
extend Workflows
|
1165
|
+
workflow(:entry_point) { {:version => 1, :task_list => "data_converter_child_workflow", :default_execution_start_to_close_timeout => 600, :data_converter => YAMLPlusOne.new} }
|
1166
|
+
def entry_point(arg)
|
1167
|
+
return arg + 1
|
1168
|
+
end
|
1531
1169
|
end
|
1170
|
+
class DataConverterHostChildWorkflow
|
1171
|
+
extend Workflows
|
1172
|
+
workflow(:entry_point) { {:version => 1, :task_list => "data_converter_parent_workflow", :default_execution_start_to_close_timeout => 600} }
|
1173
|
+
def other_entry_point
|
1174
|
+
end
|
1532
1175
|
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1176
|
+
def entry_point(arg)
|
1177
|
+
domain = get_test_domain
|
1178
|
+
client = workflow_client(domain.client, domain) { {:from_class => "DataConverterChildChildWorkflow"} }
|
1179
|
+
task { client.start_execution(5) }
|
1180
|
+
end
|
1536
1181
|
end
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
worker.register
|
1182
|
+
worker2 = WorkflowWorker.new(@swf.client, @domain, "data_converter_child_workflow", DataConverterChildChildWorkflow)
|
1183
|
+
worker2.register
|
1184
|
+
worker = WorkflowWorker.new(@swf.client, @domain, "data_converter_parent_workflow", DataConverterHostChildWorkflow)
|
1185
|
+
worker.register
|
1542
1186
|
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1187
|
+
client = workflow_client(@swf.client, @domain) { {:from_class => "DataConverterHostChildWorkflow"} }
|
1188
|
+
workflow_execution = client.entry_point(5)
|
1189
|
+
worker.run_once
|
1190
|
+
worker2.run_once
|
1191
|
+
worker.run_once
|
1192
|
+
# We have to find the index dynamically, because due to how scheduled/starts work, it isn't necessarily in the same place in our history.
|
1193
|
+
child_execution_completed_index = workflow_execution.events.map(&:event_type).index("ChildWorkflowExecutionCompleted")
|
1550
1194
|
|
1551
|
-
|
1552
|
-
|
1195
|
+
workflow_execution.events.to_a[child_execution_completed_index].attributes.result.should =~ /1\z/
|
1196
|
+
end
|
1553
1197
|
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1198
|
+
it "makes sure that the new way of doing child workflows works" do
|
1199
|
+
class OtherNewChildWorkflow
|
1200
|
+
extend Workflows
|
1201
|
+
workflow(:entry_point) { {:version => 1, :task_list => "new_child_workflow", :default_execution_start_to_close_timeout => 600} }
|
1202
|
+
def entry_point(arg)
|
1203
|
+
sleep 2
|
1204
|
+
end
|
1561
1205
|
|
1562
|
-
end
|
1563
|
-
class BadNewChildWorkflow
|
1564
|
-
extend Workflows
|
1565
|
-
workflow(:entry_point) { {:version => 1, :task_list => "new_parent_workflow", :execution_start_to_close_timeout => 3600} }
|
1566
|
-
def other_entry_point
|
1567
1206
|
end
|
1207
|
+
class BadNewChildWorkflow
|
1208
|
+
extend Workflows
|
1209
|
+
workflow(:entry_point) { {:version => 1, :task_list => "new_parent_workflow", :default_execution_start_to_close_timeout => 600} }
|
1210
|
+
def other_entry_point
|
1211
|
+
end
|
1568
1212
|
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1213
|
+
def entry_point(arg)
|
1214
|
+
domain = get_test_domain
|
1215
|
+
client = workflow_client(domain.client, domain) { {:from_class => "OtherNewChildWorkflow"} }
|
1216
|
+
task { client.start_execution(5) }
|
1217
|
+
task { client.start_execution(5) }
|
1218
|
+
end
|
1573
1219
|
end
|
1220
|
+
worker2 = WorkflowWorker.new(@swf.client, @domain, "new_child_workflow", OtherNewChildWorkflow)
|
1221
|
+
worker2.register
|
1222
|
+
worker = WorkflowWorker.new(@swf.client, @domain, "new_parent_workflow", BadNewChildWorkflow)
|
1223
|
+
worker.register
|
1224
|
+
client = workflow_client(@swf.client, @domain) { {:from_class => "BadNewChildWorkflow"} }
|
1225
|
+
workflow_execution = client.entry_point(5)
|
1226
|
+
worker.run_once
|
1227
|
+
worker2.run_once
|
1228
|
+
worker2.run_once
|
1229
|
+
worker.run_once
|
1230
|
+
worker.run_once if workflow_execution.events.map(&:event_type).last == "DecisionTaskCompleted"
|
1231
|
+
events = workflow_execution.events.map(&:event_type)
|
1232
|
+
events.should include "ChildWorkflowExecutionStarted"
|
1233
|
+
events.should include "ChildWorkflowExecutionCompleted"
|
1234
|
+
events.should include "WorkflowExecutionCompleted"
|
1574
1235
|
end
|
1575
|
-
worker2 = WorkflowWorker.new(@swf.client, @domain, "new_child_workflow", OtherNewChildWorkflow)
|
1576
|
-
worker2.register
|
1577
|
-
worker = WorkflowWorker.new(@swf.client, @domain, "new_parent_workflow", BadNewChildWorkflow)
|
1578
|
-
worker.register
|
1579
|
-
client = workflow_client(@swf.client, @domain) { {:from_class => "BadNewChildWorkflow"} }
|
1580
|
-
workflow_execution = client.entry_point(5)
|
1581
|
-
worker.run_once
|
1582
|
-
worker2.run_once
|
1583
|
-
worker2.run_once
|
1584
|
-
worker.run_once
|
1585
|
-
worker.run_once if workflow_execution.events.map(&:event_type).last == "DecisionTaskCompleted"
|
1586
|
-
events = workflow_execution.events.map(&:event_type)
|
1587
|
-
events.should include "ChildWorkflowExecutionStarted"
|
1588
|
-
events.should include "ChildWorkflowExecutionCompleted"
|
1589
|
-
events.should include "WorkflowExecutionCompleted"
|
1590
1236
|
end
|
1591
|
-
|
1592
|
-
it "makes sure that you can use retries_per_exception" do
|
1237
|
+
it "makes sure that you can use retries_per_exception" do
|
1593
1238
|
general_test(:task_list => "retries_per_exception", :class_name => "RetriesPerException")
|
1594
1239
|
@activity_class.class_eval do
|
1595
1240
|
def run_activity1
|
@@ -1598,7 +1243,7 @@ describe "RubyFlowDecider" do
|
|
1598
1243
|
end
|
1599
1244
|
@workflow_class.class_eval do
|
1600
1245
|
activity_client :activity do |options|
|
1601
|
-
options.default_task_heartbeat_timeout = "
|
1246
|
+
options.default_task_heartbeat_timeout = "600"
|
1602
1247
|
options.default_task_list = self.task_list
|
1603
1248
|
options.default_task_schedule_to_close_timeout = "5"
|
1604
1249
|
options.default_task_schedule_to_start_timeout = "5"
|
@@ -1629,6 +1274,7 @@ describe "RubyFlowDecider" do
|
|
1629
1274
|
|
1630
1275
|
@worker.run_once
|
1631
1276
|
|
1277
|
+
wait_for_execution(workflow_execution)
|
1632
1278
|
workflow_history = workflow_execution.events.map(&:event_type)
|
1633
1279
|
workflow_history.count("ActivityTaskFailed").should == 3
|
1634
1280
|
|
@@ -1641,7 +1287,7 @@ describe "RubyFlowDecider" do
|
|
1641
1287
|
def entry_point
|
1642
1288
|
create_timer(5) do
|
1643
1289
|
continue_as_new do |options|
|
1644
|
-
options.execution_start_to_close_timeout =
|
1290
|
+
options.execution_start_to_close_timeout = 600
|
1645
1291
|
options.task_list = "continue_as_new_timer"
|
1646
1292
|
options.tag_list = []
|
1647
1293
|
options.version = "1"
|
@@ -1677,7 +1323,7 @@ describe "RubyFlowDecider" do
|
|
1677
1323
|
continue_as_new do |options|
|
1678
1324
|
options.workflow_name = @workflow_class.to_s
|
1679
1325
|
options.execution_method = :entry_point
|
1680
|
-
options.execution_start_to_close_timeout =
|
1326
|
+
options.execution_start_to_close_timeout = 600
|
1681
1327
|
options.task_list = "continue_as_new"
|
1682
1328
|
options.tag_list = []
|
1683
1329
|
options.task_start_to_close_timeout = 30
|
@@ -1697,14 +1343,15 @@ describe "RubyFlowDecider" do
|
|
1697
1343
|
|
1698
1344
|
it "makes sure that exponential retry returns values correctly" do
|
1699
1345
|
class ExponentialActivity
|
1700
|
-
extend Activity
|
1701
|
-
activity :run_activity1 do
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1346
|
+
extend AWS::Flow::Activity
|
1347
|
+
activity :run_activity1 do
|
1348
|
+
{
|
1349
|
+
version: "1.0",
|
1350
|
+
default_task_list: "exponential_test_return_task_list",
|
1351
|
+
default_task_schedule_to_close_timeout: "30",
|
1352
|
+
default_task_schedule_to_start_timeout: "15",
|
1353
|
+
default_task_start_to_close_timeout: "15",
|
1354
|
+
}
|
1708
1355
|
end
|
1709
1356
|
def run_activity1
|
1710
1357
|
return 5
|
@@ -1712,106 +1359,98 @@ describe "RubyFlowDecider" do
|
|
1712
1359
|
end
|
1713
1360
|
|
1714
1361
|
class ExponentialWorkflow
|
1715
|
-
extend
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1362
|
+
extend AWS::Flow::Workflows
|
1363
|
+
workflow :start do
|
1364
|
+
{
|
1365
|
+
version: "1.0",
|
1366
|
+
default_task_list: "exponential_test_return_task_list",
|
1367
|
+
default_execution_start_to_close_timeout: 600,
|
1368
|
+
default_task_start_to_close_timeout: 60,
|
1369
|
+
default_child_policy: "REQUEST_CANCEL"
|
1370
|
+
}
|
1724
1371
|
end
|
1725
|
-
|
1726
|
-
def
|
1727
|
-
x = activity.exponential_retry(:run_activity1)
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1372
|
+
activity_client(:activity) { { from_class: "ExponentialActivity" } }
|
1373
|
+
def start
|
1374
|
+
x = activity.exponential_retry(:run_activity1) {
|
1375
|
+
{
|
1376
|
+
retries_per_exception: {
|
1377
|
+
ActivityTaskTimedOutException => Float::INFINITY,
|
1378
|
+
ActivityTaskFailedException => 3
|
1379
|
+
}
|
1731
1380
|
}
|
1732
|
-
|
1381
|
+
}
|
1733
1382
|
x.should == 5
|
1734
1383
|
end
|
1735
1384
|
end
|
1736
1385
|
|
1737
1386
|
task_list = "exponential_test_return_task_list"
|
1738
|
-
# @swf and @domain are set beforehand with the aws ruby sdk
|
1739
1387
|
|
1740
|
-
worker = WorkflowWorker.new(@
|
1741
|
-
activity_worker = ActivityWorker.new(@
|
1388
|
+
worker = WorkflowWorker.new(@domain.client, @domain, task_list, ExponentialWorkflow)
|
1389
|
+
activity_worker = ActivityWorker.new(@domain.client, @domain, task_list, ExponentialActivity)
|
1742
1390
|
worker.register
|
1743
|
-
|
1744
1391
|
activity_worker.register
|
1745
|
-
|
1746
|
-
options.workflow_name = "ExponentialWorkflow"
|
1747
|
-
options.execution_start_to_close_timeout = 3600
|
1748
|
-
options.task_list = task_list
|
1749
|
-
options.task_start_to_close_timeout = 120
|
1750
|
-
options.child_policy = :request_cancel
|
1751
|
-
end
|
1752
|
-
|
1753
|
-
sleep 5
|
1754
|
-
client = my_workflow_factory.get_client
|
1392
|
+
client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "ExponentialWorkflow" } }
|
1755
1393
|
workflow_execution = client.start_execution
|
1756
1394
|
worker.run_once
|
1757
1395
|
activity_worker.run_once
|
1758
1396
|
activity_worker.run_once unless workflow_execution.events.map(&:event_type).include? "ActivityTaskCompleted"
|
1759
1397
|
worker.run_once
|
1398
|
+
wait_for_execution(workflow_execution)
|
1760
1399
|
workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
|
1761
1400
|
end
|
1762
1401
|
|
1763
1402
|
it "makes sure that signals work correctly" do
|
1403
|
+
|
1764
1404
|
class SignalWorkflow
|
1765
|
-
extend Workflows
|
1405
|
+
extend AWS::Flow::Workflows
|
1766
1406
|
workflow :entry_point do
|
1767
1407
|
{
|
1768
|
-
:
|
1408
|
+
version: "1.0",
|
1409
|
+
default_execution_start_to_close_timeout: 600,
|
1769
1410
|
}
|
1770
1411
|
end
|
1412
|
+
|
1413
|
+
signal :this_signal
|
1771
1414
|
def this_signal(input)
|
1772
1415
|
@wait.broadcast
|
1773
1416
|
@input = input
|
1774
1417
|
end
|
1775
|
-
|
1418
|
+
|
1776
1419
|
def entry_point
|
1777
1420
|
@input = "bad_input"
|
1778
1421
|
@wait ||= FiberConditionVariable.new
|
1779
1422
|
@wait.wait
|
1780
1423
|
@input.should =~ /new input!/
|
1781
1424
|
end
|
1425
|
+
|
1782
1426
|
end
|
1783
|
-
|
1784
|
-
worker =
|
1785
|
-
worker.add_workflow_implementation(SignalWorkflow)
|
1427
|
+
|
1428
|
+
worker = build_worker(SignalWorkflow, "SignalWorkflow_tasklist")
|
1786
1429
|
worker.register
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
options.task_list = task_list
|
1791
|
-
options.task_start_to_close_timeout = 10
|
1792
|
-
options.child_policy = :request_cancel
|
1793
|
-
end
|
1794
|
-
sleep 3
|
1795
|
-
workflow_execution = my_workflow_client.start_execution
|
1796
|
-
forking_executor = ForkingExecutor.new(:max_workers => 2)
|
1797
|
-
worker.run_once
|
1430
|
+
client = build_client(from_class: "SignalWorkflow")
|
1431
|
+
|
1432
|
+
workflow_execution = client.start_execution
|
1798
1433
|
|
1799
|
-
my_workflow_client.signal_workflow_execution("this_signal", workflow_execution) { {:input => "new input!"}}
|
1800
1434
|
worker.run_once
|
1801
|
-
|
1435
|
+
client.signal_workflow_execution("this_signal", workflow_execution) { {:input => "new input!"}}
|
1436
|
+
worker.run_once
|
1437
|
+
|
1438
|
+
wait_for_execution(workflow_execution)
|
1802
1439
|
workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
|
1803
1440
|
end
|
1804
1441
|
|
1805
1442
|
it "makes sure that internal signalling works" do
|
1443
|
+
|
1806
1444
|
class SignallingActivity
|
1807
|
-
extend
|
1808
|
-
activity :run_activity1 do
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1445
|
+
extend AWS::Flow::Activities
|
1446
|
+
activity :run_activity1 do
|
1447
|
+
{
|
1448
|
+
version: "1.0",
|
1449
|
+
default_task_list: "SignalWorker_activity_tasklist",
|
1450
|
+
default_task_schedule_to_close_timeout: "10",
|
1451
|
+
default_task_schedule_to_start_timeout: "10",
|
1452
|
+
default_task_start_to_close_timeout: "8",
|
1453
|
+
}
|
1815
1454
|
end
|
1816
1455
|
def run_activity1
|
1817
1456
|
return 5
|
@@ -1819,76 +1458,75 @@ describe "RubyFlowDecider" do
|
|
1819
1458
|
end
|
1820
1459
|
|
1821
1460
|
class SignalInternalWorkflow
|
1822
|
-
extend
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1461
|
+
extend AWS::Flow::Workflows
|
1462
|
+
|
1463
|
+
workflow :entry_point do
|
1464
|
+
{
|
1465
|
+
version: "1.0",
|
1466
|
+
default_task_list: "SignalWorkflow_tasklist",
|
1467
|
+
default_execution_start_to_close_timeout: 600,
|
1468
|
+
default_child_policy: :request_cancel,
|
1469
|
+
}
|
1830
1470
|
end
|
1831
|
-
|
1471
|
+
|
1472
|
+
activity_client(:activity) { { from_class: "SignallingActivity" } }
|
1473
|
+
|
1832
1474
|
def entry_point
|
1833
|
-
|
1834
|
-
options.workflow_name = "SignalWorkflow"
|
1835
|
-
options.execution_method = "entry_point"
|
1836
|
-
options.execution_start_to_close_timeout = 3600
|
1837
|
-
options.task_start_to_close_timeout = 3600
|
1838
|
-
options.child_policy = :request_cancel
|
1839
|
-
options.version = "1"
|
1840
|
-
options.task_list = "WorkflowSignalee_tasklist"
|
1841
|
-
end
|
1842
|
-
client = my_workflow_factory.get_client
|
1475
|
+
client = build_client(from_class: "SignaleeWorkflow")
|
1843
1476
|
workflow_future = client.send_async(:start_execution)
|
1844
1477
|
activity.run_activity1
|
1845
1478
|
client.signal_workflow_execution(:this_signal, workflow_future)
|
1846
1479
|
end
|
1847
1480
|
end
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1481
|
+
|
1482
|
+
class SignaleeWorkflow
|
1483
|
+
extend AWS::Flow::Workflows
|
1484
|
+
|
1485
|
+
workflow :entry_point do
|
1486
|
+
{
|
1487
|
+
version: "1.0",
|
1488
|
+
default_task_list: "WorkflowSignalee_tasklist",
|
1489
|
+
default_execution_start_to_close_timeout: 600,
|
1490
|
+
default_child_policy: :request_cancel,
|
1491
|
+
}
|
1857
1492
|
end
|
1858
1493
|
signal :this_signal
|
1859
|
-
|
1494
|
+
|
1860
1495
|
def entry_point
|
1861
1496
|
@wait ||= FiberConditionVariable.new
|
1862
1497
|
@wait.wait
|
1863
1498
|
end
|
1499
|
+
def this_signal
|
1500
|
+
@wait.broadcast
|
1501
|
+
end
|
1864
1502
|
end
|
1865
|
-
|
1866
|
-
worker_signalee =
|
1867
|
-
|
1868
|
-
|
1869
|
-
worker_signaler.add_workflow_implementation(SignalInternalWorkflow)
|
1870
|
-
activity_worker = ActivityWorker.new(@swf.client, @domain, "SignalWorker_activity_task_task", SignallingActivity)
|
1503
|
+
|
1504
|
+
worker_signalee = build_worker(SignaleeWorkflow, "WorkflowSignalee_tasklist")
|
1505
|
+
worker_signaler = build_worker(SignalInternalWorkflow, "SignalWorkflow_tasklist")
|
1506
|
+
activity_worker = build_worker(SignallingActivity, "SignalWorker_activity_tasklist")
|
1871
1507
|
worker_signaler.register
|
1872
1508
|
worker_signalee.register
|
1873
1509
|
activity_worker.register
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
options.task_start_to_close_timeout = 600
|
1879
|
-
options.child_policy = :request_cancel
|
1880
|
-
end
|
1881
|
-
my_workflow = my_workflow_factory.get_client
|
1882
|
-
workflow_execution = my_workflow.start_execution
|
1510
|
+
|
1511
|
+
client = build_client(from_class: "SignalInternalWorkflow")
|
1512
|
+
workflow_execution = client.start_execution
|
1513
|
+
|
1883
1514
|
worker_signaler.run_once
|
1884
1515
|
worker_signalee.run_once
|
1885
1516
|
activity_worker.run_once
|
1886
|
-
|
1887
|
-
|
1517
|
+
wait_for_decision(workflow_execution, "ActivityTaskCompleted")
|
1518
|
+
|
1888
1519
|
worker_signaler.run_once
|
1520
|
+
wait_for_decision(workflow_execution)
|
1521
|
+
|
1889
1522
|
worker_signalee.run_once
|
1523
|
+
wait_for_decision(workflow_execution, "ChildWorkflowExecutionCompleted")
|
1524
|
+
|
1890
1525
|
worker_signaler.run_once
|
1526
|
+
wait_for_execution(workflow_execution)
|
1527
|
+
|
1891
1528
|
workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
|
1529
|
+
|
1892
1530
|
end
|
1893
1531
|
end
|
1894
1532
|
|
@@ -1903,8 +1541,8 @@ describe "RubyFlowDecider" do
|
|
1903
1541
|
extend Activity
|
1904
1542
|
activity :run_activity1 do |options|
|
1905
1543
|
options.default_task_list = GeneralActivity.task_list
|
1906
|
-
options.default_task_schedule_to_start_timeout = "
|
1907
|
-
options.default_task_start_to_close_timeout = "
|
1544
|
+
options.default_task_schedule_to_start_timeout = "600"
|
1545
|
+
options.default_task_start_to_close_timeout = "600"
|
1908
1546
|
options.version = "1"
|
1909
1547
|
end
|
1910
1548
|
def run_activity1
|
@@ -1915,14 +1553,14 @@ describe "RubyFlowDecider" do
|
|
1915
1553
|
class << self
|
1916
1554
|
attr_accessor :task_list
|
1917
1555
|
end
|
1918
|
-
extend
|
1556
|
+
extend AWS::Flow::Workflows
|
1919
1557
|
version "1"
|
1920
1558
|
activity_client :activity do |options|
|
1921
1559
|
options.prefix_name = "GeneralActivity"
|
1922
1560
|
options.version = "1"
|
1923
1561
|
options.default_task_list = MyWorkflow.task_list
|
1924
|
-
options.default_task_schedule_to_start_timeout = "
|
1925
|
-
options.default_task_start_to_close_timeout = "
|
1562
|
+
options.default_task_schedule_to_start_timeout = "60"
|
1563
|
+
options.default_task_start_to_close_timeout = "60"
|
1926
1564
|
end
|
1927
1565
|
entry_point :entry_point
|
1928
1566
|
def entry_point(arg)
|
@@ -1938,24 +1576,21 @@ describe "RubyFlowDecider" do
|
|
1938
1576
|
activity_worker.register
|
1939
1577
|
my_workflow_factory = workflow_factory(@swf.client, @domain) do |options|
|
1940
1578
|
options.workflow_name = "MyWorkflow"
|
1941
|
-
options.execution_start_to_close_timeout =
|
1579
|
+
options.execution_start_to_close_timeout = 600
|
1942
1580
|
options.task_list = task_list
|
1943
|
-
options.task_start_to_close_timeout =
|
1581
|
+
options.task_start_to_close_timeout = 120
|
1944
1582
|
options.child_policy = :request_cancel
|
1945
1583
|
end
|
1946
1584
|
my_workflow = my_workflow_factory.get_client
|
1947
1585
|
|
1948
|
-
workflow_execution = my_workflow.start_execution(5)
|
1949
1586
|
|
1950
|
-
sleep 10
|
1951
1587
|
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
1952
1588
|
@forking_executor.execute { worker.start }
|
1953
|
-
sleep 5
|
1954
1589
|
@forking_executor.execute { activity_worker.start }
|
1955
|
-
|
1956
|
-
|
1590
|
+
workflow_execution = my_workflow.start_execution(5)
|
1591
|
+
wait_for_execution(workflow_execution)
|
1957
1592
|
@forking_executor.shutdown(1)
|
1958
|
-
workflow_execution.events.map(&:event_type)
|
1593
|
+
workflow_execution.events.map(&:event_type).count("ActivityTaskFailed").should == 1
|
1959
1594
|
end
|
1960
1595
|
|
1961
1596
|
it "is a good example of the service" do
|
@@ -1965,7 +1600,7 @@ describe "RubyFlowDecider" do
|
|
1965
1600
|
activity :run_activity1 do |options|
|
1966
1601
|
options.default_task_list = "add_one_task_list"
|
1967
1602
|
options.version = "1"
|
1968
|
-
options.default_task_heartbeat_timeout = "
|
1603
|
+
options.default_task_heartbeat_timeout = "600"
|
1969
1604
|
options.default_task_schedule_to_close_timeout = "30"
|
1970
1605
|
options.default_task_schedule_to_start_timeout = "30"
|
1971
1606
|
options.default_task_start_to_close_timeout = "30"
|
@@ -1977,7 +1612,7 @@ describe "RubyFlowDecider" do
|
|
1977
1612
|
end
|
1978
1613
|
# Definition of the workflow logic
|
1979
1614
|
class MyWorkflow
|
1980
|
-
extend
|
1615
|
+
extend AWS::Flow::Workflows
|
1981
1616
|
version "1"
|
1982
1617
|
activity_client :activity do |options|
|
1983
1618
|
options.prefix_name = "AddOneActivity"
|
@@ -1985,11 +1620,11 @@ describe "RubyFlowDecider" do
|
|
1985
1620
|
# to have the lines below, but since the have access to the activity, we
|
1986
1621
|
# can simply "peek" at its configuration, and use those
|
1987
1622
|
|
1988
|
-
# options.default_task_heartbeat_timeout = "
|
1623
|
+
# options.default_task_heartbeat_timeout = "600"
|
1989
1624
|
# options.default_task_list = "add_one_task_list"
|
1990
|
-
# options.default_task_schedule_to_close_timeout = "
|
1991
|
-
# options.default_task_schedule_to_start_timeout = "
|
1992
|
-
# options.default_task_start_to_close_timeout = "
|
1625
|
+
# options.default_task_schedule_to_close_timeout = "600"
|
1626
|
+
# options.default_task_schedule_to_start_timeout = "600"
|
1627
|
+
# options.default_task_start_to_close_timeout = "600"
|
1993
1628
|
end
|
1994
1629
|
|
1995
1630
|
# The default place to start the execution of a workflow is "entry_point",
|
@@ -2020,9 +1655,9 @@ describe "RubyFlowDecider" do
|
|
2020
1655
|
# Get a workflow client to start the workflow
|
2021
1656
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2022
1657
|
options.workflow_name = "MyWorkflow"
|
2023
|
-
options.execution_start_to_close_timeout =
|
1658
|
+
options.execution_start_to_close_timeout = 600
|
2024
1659
|
options.task_list = task_list
|
2025
|
-
options.task_start_to_close_timeout =
|
1660
|
+
options.task_start_to_close_timeout = 120
|
2026
1661
|
options.child_policy = :request_cancel
|
2027
1662
|
end
|
2028
1663
|
# Forking executors have some possibility of race conditions, so we will
|
@@ -2040,7 +1675,7 @@ describe "RubyFlowDecider" do
|
|
2040
1675
|
|
2041
1676
|
# Sleep to give the threads some time to compute, as we'll run right out of
|
2042
1677
|
# the test before they can run otherwise
|
2043
|
-
|
1678
|
+
wait_for_execution(workflow_execution)
|
2044
1679
|
workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
|
2045
1680
|
end
|
2046
1681
|
|
@@ -2051,10 +1686,10 @@ describe "RubyFlowDecider" do
|
|
2051
1686
|
activity :run_activity1, :run_activity2, :run_activity3 do |options|
|
2052
1687
|
options.default_task_list = "parallel_split_task_list"
|
2053
1688
|
options.version = "1"
|
2054
|
-
options.default_task_heartbeat_timeout = "
|
2055
|
-
options.default_task_schedule_to_close_timeout = "
|
2056
|
-
options.default_task_schedule_to_start_timeout = "
|
2057
|
-
options.default_task_start_to_close_timeout = "
|
1689
|
+
options.default_task_heartbeat_timeout = "600"
|
1690
|
+
options.default_task_schedule_to_close_timeout = "120"
|
1691
|
+
options.default_task_schedule_to_start_timeout = "120"
|
1692
|
+
options.default_task_start_to_close_timeout = "120"
|
2058
1693
|
end
|
2059
1694
|
def run_activity1(arg)
|
2060
1695
|
arg + 1
|
@@ -2068,7 +1703,7 @@ describe "RubyFlowDecider" do
|
|
2068
1703
|
end
|
2069
1704
|
# Definition of the workflow logic
|
2070
1705
|
class ParallelWorkflow
|
2071
|
-
extend
|
1706
|
+
extend AWS::Flow::Workflows
|
2072
1707
|
version "1"
|
2073
1708
|
activity_client :activity do |options|
|
2074
1709
|
options.prefix_name = "ParallelSplitActivity"
|
@@ -2076,11 +1711,11 @@ describe "RubyFlowDecider" do
|
|
2076
1711
|
# to have the lines below, but since the have access to the activity, we
|
2077
1712
|
# can simply "peek" at its configuration, and use those
|
2078
1713
|
|
2079
|
-
# options.default_task_heartbeat_timeout = "
|
1714
|
+
# options.default_task_heartbeat_timeout = "600"
|
2080
1715
|
# options.default_task_list = "parallel_split_task_list"
|
2081
|
-
# options.default_task_schedule_to_close_timeout = "
|
2082
|
-
# options.default_task_schedule_to_start_timeout = "
|
2083
|
-
# options.default_task_start_to_close_timeout = "
|
1716
|
+
# options.default_task_schedule_to_close_timeout = "120"
|
1717
|
+
# options.default_task_schedule_to_start_timeout = "120"
|
1718
|
+
# options.default_task_start_to_close_timeout = "120"
|
2084
1719
|
end
|
2085
1720
|
|
2086
1721
|
# The default place to start the execution of a workflow is "entry_point",
|
@@ -2117,7 +1752,7 @@ describe "RubyFlowDecider" do
|
|
2117
1752
|
# Get a workflow client to start the workflow
|
2118
1753
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2119
1754
|
options.workflow_name = "ParallelWorkflow"
|
2120
|
-
options.execution_start_to_close_timeout =
|
1755
|
+
options.execution_start_to_close_timeout = 600
|
2121
1756
|
options.task_list = task_list
|
2122
1757
|
options.task_start_to_close_timeout = 10
|
2123
1758
|
options.child_policy = :request_cancel
|
@@ -2126,24 +1761,11 @@ describe "RubyFlowDecider" do
|
|
2126
1761
|
my_workflow_client = my_workflow_factory.get_client
|
2127
1762
|
workflow_execution = my_workflow_client.start_execution(5)
|
2128
1763
|
|
2129
|
-
# We use an executor here so as to be able to test this feature within one
|
2130
|
-
# working process, as activity_worker.start and worker.start will block
|
2131
|
-
# otherwise
|
2132
|
-
|
2133
|
-
# Forking executors have some possibility of race conditions, so we will
|
2134
|
-
# avoid them by putting in a small sleep. There is no plan to fix at current, as
|
2135
|
-
# we don't expect forking executor to be used by most customers.
|
2136
|
-
sleep 5
|
2137
1764
|
forking_executor = ForkingExecutor.new(:max_workers => 2)
|
2138
|
-
|
2139
1765
|
forking_executor.execute { activity_worker.start }
|
2140
|
-
sleep 5
|
2141
1766
|
forking_executor.execute { worker.start }
|
2142
1767
|
|
2143
|
-
|
2144
|
-
# Sleep to give the threads some time to compute, as we'll run right out of
|
2145
|
-
# the test before they can run otherwise
|
2146
|
-
sleep 50
|
1768
|
+
wait_for_execution(workflow_execution)
|
2147
1769
|
workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
|
2148
1770
|
end
|
2149
1771
|
|
@@ -2153,7 +1775,7 @@ describe "RubyFlowDecider" do
|
|
2153
1775
|
activity :run_activity1, :run_activity2 do |options|
|
2154
1776
|
options.default_task_list = "error_handling_task_list"
|
2155
1777
|
options.version = "1"
|
2156
|
-
options.default_task_heartbeat_timeout = "
|
1778
|
+
options.default_task_heartbeat_timeout = "600"
|
2157
1779
|
options.default_task_schedule_to_close_timeout = "10"
|
2158
1780
|
options.default_task_schedule_to_start_timeout = "10"
|
2159
1781
|
options.default_task_start_to_close_timeout = "10"
|
@@ -2167,7 +1789,7 @@ describe "RubyFlowDecider" do
|
|
2167
1789
|
end
|
2168
1790
|
# Definition of the workflow logic
|
2169
1791
|
class MyWorkflow
|
2170
|
-
extend
|
1792
|
+
extend AWS::Flow::Workflows
|
2171
1793
|
version "1"
|
2172
1794
|
activity_client :activity do |options|
|
2173
1795
|
options.prefix_name = "ErrorHandlingActivity"
|
@@ -2175,11 +1797,11 @@ describe "RubyFlowDecider" do
|
|
2175
1797
|
# to have the lines below, but since the have access to the activity, we
|
2176
1798
|
# can simply "peek" at its configuration, and use those
|
2177
1799
|
|
2178
|
-
# options.default_task_heartbeat_timeout = "
|
1800
|
+
# options.default_task_heartbeat_timeout = "600"
|
2179
1801
|
# options.default_task_list = "error_handling_task_list"
|
2180
|
-
# options.default_task_schedule_to_close_timeout = "
|
2181
|
-
# options.default_task_schedule_to_start_timeout = "
|
2182
|
-
# options.default_task_start_to_close_timeout = "
|
1802
|
+
# options.default_task_schedule_to_close_timeout = "120"
|
1803
|
+
# options.default_task_schedule_to_start_timeout = "120"
|
1804
|
+
# options.default_task_start_to_close_timeout = "120"
|
2183
1805
|
end
|
2184
1806
|
|
2185
1807
|
# The default place to start the execution of a workflow is "entry_point",
|
@@ -2215,7 +1837,7 @@ describe "RubyFlowDecider" do
|
|
2215
1837
|
error_seen.should == ActivityTaskFailedException
|
2216
1838
|
# Do something to clean up after
|
2217
1839
|
end
|
2218
|
-
|
1840
|
+
end
|
2219
1841
|
5
|
2220
1842
|
end
|
2221
1843
|
end
|
@@ -2233,7 +1855,7 @@ describe "RubyFlowDecider" do
|
|
2233
1855
|
# Get a workflow client to start the workflow
|
2234
1856
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2235
1857
|
options.workflow_name = "MyWorkflow"
|
2236
|
-
options.execution_start_to_close_timeout =
|
1858
|
+
options.execution_start_to_close_timeout = 600
|
2237
1859
|
options.task_list = task_list
|
2238
1860
|
options.task_start_to_close_timeout = 20
|
2239
1861
|
options.child_policy = :request_cancel
|
@@ -2264,6 +1886,7 @@ describe "RubyFlowDecider" do
|
|
2264
1886
|
worker.run_once
|
2265
1887
|
# worker.start
|
2266
1888
|
|
1889
|
+
wait_for_execution(workflow_execution)
|
2267
1890
|
|
2268
1891
|
workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
|
2269
1892
|
end
|
@@ -2305,135 +1928,137 @@ describe "RubyFlowDecider" do
|
|
2305
1928
|
|
2306
1929
|
describe "ensures that you can specify the {workflow_id,execution_method} to be used for an external client" do
|
2307
1930
|
{:workflow_id => ["blah", "workflow_id"] ,
|
2308
|
-
|
1931
|
+
:execution_method => ["start", "workflow_type.name.split('.').last" ]
|
2309
1932
|
}.each_pair do |method, value_and_method_to_check|
|
2310
1933
|
value, method_to_check = value_and_method_to_check
|
2311
|
-
|
1934
|
+
|
2312
1935
|
it "makes sure that #{method} can be specified correctly" do
|
2313
1936
|
class WorkflowIDWorkflow
|
2314
|
-
extend
|
2315
|
-
|
2316
|
-
|
2317
|
-
|
1937
|
+
extend Workflows
|
1938
|
+
workflow :start do
|
1939
|
+
{
|
1940
|
+
version: "1.0",
|
1941
|
+
default_execution_start_to_close_timeout: 600,
|
1942
|
+
default_task_list: "timeout_test"
|
1943
|
+
}
|
2318
1944
|
end
|
1945
|
+
def start; end
|
2319
1946
|
end
|
2320
|
-
|
1947
|
+
|
1948
|
+
worker = WorkflowWorker.new(@domain.client, @domain, "timeout_test", WorkflowIDWorkflow)
|
2321
1949
|
worker.register
|
2322
|
-
|
2323
|
-
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2327
|
-
|
2328
|
-
execution = my_workflow_client.entry_point do |opt|
|
2329
|
-
opt.send("#{method}=", value)
|
2330
|
-
opt.tag_list = ["stuff"]
|
1950
|
+
client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "WorkflowIDWorkflow" } }
|
1951
|
+
|
1952
|
+
workflow_execution = client.start do {
|
1953
|
+
method.to_sym => value,
|
1954
|
+
tag_list: ["stuff"]
|
1955
|
+
}
|
2331
1956
|
end
|
2332
|
-
|
1957
|
+
|
1958
|
+
return_value = eval "workflow_execution.#{method_to_check}"
|
2333
1959
|
return_value.should == value
|
2334
|
-
|
1960
|
+
workflow_execution.tags.should == ["stuff"]
|
2335
1961
|
end
|
2336
1962
|
end
|
2337
1963
|
end
|
2338
1964
|
describe "making sure that timeouts are infrequent" do
|
2339
1965
|
it "is a basic repro case" do
|
2340
1966
|
class TimeoutActivity
|
2341
|
-
extend
|
2342
|
-
activity :run_activity1 do
|
2343
|
-
|
2344
|
-
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
1967
|
+
extend AWS::Flow::Activities
|
1968
|
+
activity :run_activity1 do
|
1969
|
+
{
|
1970
|
+
default_task_list: "timeout_test_activity",
|
1971
|
+
version: "1.0",
|
1972
|
+
default_task_schedule_to_close_timeout: "60",
|
1973
|
+
default_task_schedule_to_start_timeout: "30",
|
1974
|
+
default_task_start_to_close_timeout: "30",
|
1975
|
+
}
|
2349
1976
|
end
|
2350
1977
|
def run_activity1
|
2351
1978
|
"did some work in run_activity1"
|
2352
1979
|
end
|
2353
1980
|
end
|
2354
1981
|
class TimeoutWorkflow
|
2355
|
-
extend
|
2356
|
-
|
2357
|
-
|
2358
|
-
|
1982
|
+
extend AWS::Flow::Workflows
|
1983
|
+
workflow :entry_point do
|
1984
|
+
{
|
1985
|
+
version: "1.0",
|
1986
|
+
default_execution_start_to_close_timeout: 600,
|
1987
|
+
default_task_list: "timeout_test_workflow"
|
1988
|
+
}
|
2359
1989
|
end
|
2360
|
-
|
1990
|
+
activity_client (:activity) { { from_class: "TimeoutActivity" } }
|
2361
1991
|
def entry_point
|
2362
1992
|
activity.run_activity1
|
2363
1993
|
end
|
2364
1994
|
end
|
2365
|
-
worker = WorkflowWorker.new(@
|
2366
|
-
|
2367
|
-
|
2368
|
-
activity_worker.register
|
2369
|
-
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2370
|
-
options.workflow_name = "TimeoutWorkflow"
|
2371
|
-
options.execution_start_to_close_timeout = 3600
|
2372
|
-
options.task_start_to_close_timeout = 5
|
2373
|
-
options.task_list = "timeout_test"
|
2374
|
-
end
|
2375
|
-
my_workflow_client = my_workflow_factory.get_client
|
1995
|
+
@worker = WorkflowWorker.new(@domain.client, @domain, "timeout_test_workflow", TimeoutWorkflow)
|
1996
|
+
@activity_workers = []
|
1997
|
+
|
2376
1998
|
num_tests = 15
|
1999
|
+
1.upto(num_tests) { @activity_workers << ActivityWorker.new(@domain.client, @domain, "timeout_test_activity", TimeoutActivity) }
|
2000
|
+
|
2001
|
+
@worker.register
|
2002
|
+
@activity_workers.first.register
|
2003
|
+
|
2004
|
+
my_workflow_client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "TimeoutWorkflow" } }
|
2005
|
+
|
2377
2006
|
workflow_executions = []
|
2007
|
+
|
2008
|
+
@forking_executor = ForkingExecutor.new(max_workers: 20)
|
2009
|
+
@forking_executor.execute { @worker.start }
|
2010
|
+
@activity_workers.each { |x| @forking_executor.execute { x.start } }
|
2011
|
+
sleep 10
|
2012
|
+
|
2378
2013
|
1.upto(num_tests) { |i| workflow_executions << my_workflow_client.entry_point }
|
2379
|
-
|
2380
|
-
|
2381
|
-
|
2382
|
-
|
2383
|
-
failed_executions = workflow_executions.each{|x| x.events.to_a.last.event_type.should == "WorkflowExecutionCompleted" }
|
2014
|
+
|
2015
|
+
workflow_executions.each { |x| wait_for_execution(x) }
|
2016
|
+
workflow_executions.each{|x| x.events.to_a.last.event_type.should == "WorkflowExecutionCompleted" }
|
2017
|
+
@forking_executor.shutdown(1)
|
2384
2018
|
|
2385
2019
|
end
|
2386
2020
|
end
|
2387
2021
|
|
2388
2022
|
describe "makes sure that workflow clients expose the same client api and do the right thing" do
|
2389
2023
|
it "makes sure that send_async works" do
|
2390
|
-
class
|
2391
|
-
extend
|
2392
|
-
|
2393
|
-
|
2394
|
-
|
2024
|
+
class SendAsyncChildWorkflow
|
2025
|
+
extend AWS::Flow::Workflows
|
2026
|
+
workflow :start do
|
2027
|
+
{
|
2028
|
+
version: "1.0",
|
2029
|
+
default_execution_start_to_close_timeout: "600"
|
2030
|
+
}
|
2395
2031
|
end
|
2032
|
+
def start; end
|
2396
2033
|
end
|
2397
|
-
class
|
2398
|
-
|
2399
|
-
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2403
|
-
version "1"
|
2404
|
-
entry_point :entry_point
|
2405
|
-
def entry_point(arg)
|
2406
|
-
client = workflow_client(@swf_client, @domain) do |options|
|
2407
|
-
options.workflow_name = "SendAsyncWorkflow"
|
2408
|
-
options.execution_method = "entry_point"
|
2409
|
-
options.execution_start_to_close_timeout = 3600
|
2410
|
-
options.task_start_to_close_timeout = 10
|
2411
|
-
options.version = "1"
|
2412
|
-
options.task_list = "client_test_async2"
|
2413
|
-
end
|
2414
|
-
client.send_async(:start_execution, arg) {
|
2415
|
-
{ :task_start_to_close_timeout => 35 }
|
2034
|
+
class SendAsyncParentWorkflow
|
2035
|
+
extend AWS::Flow::Workflows
|
2036
|
+
workflow :start do
|
2037
|
+
{
|
2038
|
+
version: "1.0",
|
2039
|
+
default_execution_start_to_close_timeout: "600",
|
2416
2040
|
}
|
2417
|
-
|
2041
|
+
end
|
2042
|
+
def start
|
2043
|
+
domain = get_test_domain
|
2044
|
+
client = AWS::Flow::workflow_client(domain.client, domain) { { from_class: "SendAsyncChildWorkflow" } }
|
2045
|
+
client.send_async(:start_execution) { { task_list: "client_test_async2" } }
|
2046
|
+
client.send_async(:start_execution) { { task_list: "client_test_async2" } }
|
2418
2047
|
end
|
2419
2048
|
end
|
2420
|
-
|
2421
|
-
|
2422
|
-
|
2423
|
-
|
2424
|
-
|
2425
|
-
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
|
2431
|
-
|
2049
|
+
@parent_worker = WorkflowWorker.new(@domain.client, @domain, "client_test_async", SendAsyncParentWorkflow)
|
2050
|
+
@child_worker = WorkflowWorker.new(@domain.client, @domain, "client_test_async2", SendAsyncChildWorkflow)
|
2051
|
+
@parent_worker.register
|
2052
|
+
@child_worker.register
|
2053
|
+
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
2054
|
+
@forking_executor.execute { @parent_worker.start }
|
2055
|
+
@forking_executor.execute { @child_worker.start }
|
2056
|
+
|
2057
|
+
my_workflow_client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "SendAsyncParentWorkflow" } }
|
2058
|
+
workflow_execution = my_workflow_client.start_execution
|
2059
|
+
|
2060
|
+
wait_for_execution(workflow_execution)
|
2432
2061
|
|
2433
|
-
internal_worker.run_once
|
2434
|
-
internal_worker.run_once
|
2435
|
-
worker.run_once
|
2436
|
-
worker.run_once if workflow_execution.events.map(&:event_type).last == "DecisionTaskCompleted"
|
2437
2062
|
history_events = workflow_execution.events.map(&:event_type)
|
2438
2063
|
history_events.count("ChildWorkflowExecutionCompleted").should == 2
|
2439
2064
|
history_events.count("WorkflowExecutionCompleted").should == 1
|
@@ -2441,58 +2066,48 @@ describe "RubyFlowDecider" do
|
|
2441
2066
|
|
2442
2067
|
it "makes sure that retry works" do
|
2443
2068
|
class OtherWorkflow
|
2444
|
-
extend
|
2445
|
-
|
2446
|
-
|
2447
|
-
|
2069
|
+
extend AWS::Flow::Workflows
|
2070
|
+
workflow :other_workflow do
|
2071
|
+
{
|
2072
|
+
version: "1.0",
|
2073
|
+
default_execution_start_to_close_timeout: 120,
|
2074
|
+
default_task_start_to_close_timeout: 10
|
2075
|
+
}
|
2076
|
+
|
2077
|
+
end
|
2078
|
+
def other_workflow
|
2448
2079
|
raise "Simulated error"
|
2449
2080
|
end
|
2450
2081
|
end
|
2451
2082
|
class BadWorkflow
|
2452
|
-
|
2453
|
-
|
2083
|
+
extend AWS::Flow::Workflows
|
2084
|
+
workflow :bad_workflow do
|
2085
|
+
{
|
2086
|
+
version: "1.0",
|
2087
|
+
default_execution_start_to_close_timeout: 600,
|
2088
|
+
default_task_start_to_close_timeout: 30
|
2089
|
+
}
|
2454
2090
|
end
|
2455
|
-
|
2456
|
-
|
2457
|
-
|
2458
|
-
|
2459
|
-
|
2460
|
-
my_workflow_factory = workflow_factory($swf_client, $domain) do |options|
|
2461
|
-
options.workflow_name = "OtherWorkflow"
|
2462
|
-
options.execution_method = "entry_point"
|
2463
|
-
options.execution_start_to_close_timeout = 3600
|
2464
|
-
options.task_start_to_close_timeout = 10
|
2465
|
-
options.version = "1"
|
2466
|
-
options.task_list = "client_test_retry2"
|
2467
|
-
end
|
2468
|
-
client = my_workflow_factory.get_client
|
2469
|
-
client.exponential_retry(:start_execution, arg) do |opt|
|
2470
|
-
opt.maximum_attempts = 1
|
2471
|
-
end
|
2091
|
+
|
2092
|
+
def bad_workflow
|
2093
|
+
domain = get_test_domain
|
2094
|
+
child_client = AWS::Flow::workflow_client(domain.client, domain) { { from_class: "OtherWorkflow" } }
|
2095
|
+
child_client.exponential_retry(:start_execution) { { maximum_attempts: 1 }}
|
2472
2096
|
end
|
2473
2097
|
end
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2478
|
-
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2479
|
-
options.workflow_name = "BadWorkflow"
|
2480
|
-
options.execution_start_to_close_timeout = 3600
|
2481
|
-
options.task_list = "client_test_retry"
|
2482
|
-
end
|
2483
|
-
my_workflow_client = my_workflow_factory.get_client
|
2484
|
-
workflow_execution = my_workflow_client.entry_point(5)
|
2098
|
+
@parent_worker = WorkflowWorker.new(@domain.client, @domain, "client_test_retry", BadWorkflow)
|
2099
|
+
@child_worker = WorkflowWorker.new(@domain.client, @domain, "client_test_retry2", OtherWorkflow)
|
2100
|
+
@parent_worker.register
|
2101
|
+
@child_worker.register
|
2485
2102
|
|
2486
|
-
|
2487
|
-
|
2103
|
+
forking_executor = ForkingExecutor.new(:max_workers => 3)
|
2104
|
+
forking_executor.execute { @parent_worker.start }
|
2105
|
+
forking_executor.execute { @child_worker.start }
|
2488
2106
|
|
2489
|
-
|
2490
|
-
|
2491
|
-
|
2492
|
-
|
2493
|
-
internal_worker.run_once
|
2494
|
-
sleep 10
|
2495
|
-
worker.run_once
|
2107
|
+
parent_client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "BadWorkflow" } }
|
2108
|
+
workflow_execution = parent_client.start_execution
|
2109
|
+
|
2110
|
+
wait_for_execution(workflow_execution)
|
2496
2111
|
history_events = workflow_execution.events.map(&:event_type)
|
2497
2112
|
history_events.count("ChildWorkflowExecutionFailed").should == 2
|
2498
2113
|
history_events.count("WorkflowExecutionFailed").should == 1
|
@@ -2513,12 +2128,12 @@ describe "RubyFlowDecider" do
|
|
2513
2128
|
end
|
2514
2129
|
end
|
2515
2130
|
|
2516
|
-
|
2131
|
+
workflow_execution = @my_workflow_client.entry_point
|
2517
2132
|
@worker.run_once
|
2518
2133
|
sleep 20
|
2519
2134
|
@worker.run_once
|
2520
2135
|
@worker.run_once
|
2521
|
-
|
2136
|
+
workflow_execution.events.map(&:event_type).last.should == "ActivityTaskScheduled"
|
2522
2137
|
end
|
2523
2138
|
|
2524
2139
|
it "ensures that with_retry does synchronous blocking by default" do
|
@@ -2555,18 +2170,20 @@ describe "RubyFlowDecider" do
|
|
2555
2170
|
|
2556
2171
|
|
2557
2172
|
it "makes sure that option inheritance doesn't override set values" do
|
2558
|
-
class
|
2173
|
+
class InheritanceOptionsWorkflow
|
2559
2174
|
extend Workflows
|
2560
|
-
|
2561
|
-
|
2562
|
-
|
2175
|
+
workflow :entry_point do
|
2176
|
+
{
|
2177
|
+
version: "1.0",
|
2178
|
+
}
|
2563
2179
|
end
|
2180
|
+
def entry_point ; end
|
2564
2181
|
end
|
2565
|
-
worker = WorkflowWorker.new(@swf.client, @domain, "client_test_inheritance",
|
2182
|
+
worker = WorkflowWorker.new(@swf.client, @domain, "client_test_inheritance", InheritanceOptionsWorkflow)
|
2566
2183
|
worker.register
|
2567
2184
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2568
|
-
options.workflow_name = "
|
2569
|
-
options.execution_start_to_close_timeout =
|
2185
|
+
options.workflow_name = "InheritanceOptionsWorkflow"
|
2186
|
+
options.execution_start_to_close_timeout = 600
|
2570
2187
|
options.task_start_to_close_timeout = 10
|
2571
2188
|
options.child_policy = :REQUEST_CANCEL
|
2572
2189
|
options.task_list = "client_test_inheritance"
|
@@ -2577,25 +2194,24 @@ describe "RubyFlowDecider" do
|
|
2577
2194
|
end
|
2578
2195
|
|
2579
2196
|
it "makes sure that option inheritance gives you defaults" do
|
2580
|
-
class
|
2197
|
+
class InheritanceOptionsWorkflow2
|
2581
2198
|
extend Workflows
|
2582
|
-
|
2583
|
-
|
2584
|
-
|
2199
|
+
workflow :options_workflow do
|
2200
|
+
{
|
2201
|
+
version: "1.0",
|
2202
|
+
default_execution_start_to_close_timeout: 600,
|
2203
|
+
default_task_list: "client_test_inheritance"
|
2204
|
+
}
|
2585
2205
|
end
|
2206
|
+
def options_workflow ; end
|
2586
2207
|
end
|
2587
|
-
worker = WorkflowWorker.new(@
|
2208
|
+
worker = WorkflowWorker.new(@domain.client, @domain, "client_test_inheritance", InheritanceOptionsWorkflow2)
|
2588
2209
|
worker.register
|
2589
|
-
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2590
|
-
options.workflow_name = "OptionsWorkflow"
|
2591
|
-
options.execution_start_to_close_timeout = 3600
|
2592
|
-
options.child_policy = :REQUEST_CANCEL
|
2593
|
-
options.task_list = "client_test_inheritance"
|
2594
|
-
end
|
2595
2210
|
|
2596
|
-
|
2597
|
-
workflow_execution.terminate
|
2211
|
+
client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "InheritanceOptionsWorkflow2", child_policy: "REQUEST_CANCEL" } }
|
2598
2212
|
|
2213
|
+
workflow_execution = client.start_execution
|
2214
|
+
workflow_execution.terminate
|
2599
2215
|
workflow_execution.child_policy.should == :request_cancel
|
2600
2216
|
end
|
2601
2217
|
|
@@ -2604,11 +2220,11 @@ describe "RubyFlowDecider" do
|
|
2604
2220
|
extend Activity
|
2605
2221
|
activity :run_activity1 do
|
2606
2222
|
{
|
2607
|
-
|
2608
|
-
|
2609
|
-
|
2610
|
-
|
2611
|
-
|
2223
|
+
:default_task_list => "options_test", :version => "1",
|
2224
|
+
:default_task_heartbeat_timeout => "600",
|
2225
|
+
:default_task_schedule_to_close_timeout => "60",
|
2226
|
+
:default_task_schedule_to_start_timeout => "60",
|
2227
|
+
:default_task_start_to_close_timeout => "60",
|
2612
2228
|
}
|
2613
2229
|
end
|
2614
2230
|
def run_activity1
|
@@ -2634,7 +2250,7 @@ describe "RubyFlowDecider" do
|
|
2634
2250
|
activity_worker.register
|
2635
2251
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2636
2252
|
options.workflow_name = "NewOptionsWorkflow"
|
2637
|
-
options.execution_start_to_close_timeout =
|
2253
|
+
options.execution_start_to_close_timeout = 600
|
2638
2254
|
options.task_start_to_close_timeout = 10
|
2639
2255
|
options.child_policy = :REQUEST_CANCEL
|
2640
2256
|
options.task_list = "options_test"
|
@@ -2654,7 +2270,7 @@ describe "RubyFlowDecider" do
|
|
2654
2270
|
activity :run_activity1 do
|
2655
2271
|
{
|
2656
2272
|
:default_task_list => "options_test", :version => "1",
|
2657
|
-
:default_task_heartbeat_timeout => "
|
2273
|
+
:default_task_heartbeat_timeout => "600",
|
2658
2274
|
:default_task_schedule_to_close_timeout => "60",
|
2659
2275
|
:default_task_schedule_to_start_timeout => "60",
|
2660
2276
|
:default_task_start_to_close_timeout => "60",
|
@@ -2683,7 +2299,7 @@ describe "RubyFlowDecider" do
|
|
2683
2299
|
activity_worker.register
|
2684
2300
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2685
2301
|
options.workflow_name = "WithRetryWorkflow"
|
2686
|
-
options.execution_start_to_close_timeout =
|
2302
|
+
options.execution_start_to_close_timeout = 600
|
2687
2303
|
options.task_start_to_close_timeout = 10
|
2688
2304
|
options.child_policy = :REQUEST_CANCEL
|
2689
2305
|
options.task_list = "options_test"
|
@@ -2727,7 +2343,7 @@ describe "RubyFlowDecider" do
|
|
2727
2343
|
activity :run_activity1 do |options|
|
2728
2344
|
options.default_task_list = "options_test"
|
2729
2345
|
options.version = "1"
|
2730
|
-
options.default_task_heartbeat_timeout = "
|
2346
|
+
options.default_task_heartbeat_timeout = "600"
|
2731
2347
|
options.default_task_schedule_to_close_timeout = "60"
|
2732
2348
|
options.default_task_schedule_to_start_timeout = "60"
|
2733
2349
|
options.default_task_start_to_close_timeout = "60"
|
@@ -2755,7 +2371,7 @@ describe "RubyFlowDecider" do
|
|
2755
2371
|
activity_worker.register
|
2756
2372
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2757
2373
|
options.workflow_name = "OptionsWorkflow"
|
2758
|
-
options.execution_start_to_close_timeout =
|
2374
|
+
options.execution_start_to_close_timeout = 600
|
2759
2375
|
options.task_start_to_close_timeout = 10
|
2760
2376
|
options.child_policy = :REQUEST_CANCEL
|
2761
2377
|
options.task_list = "options_test"
|
@@ -2770,28 +2386,30 @@ describe "RubyFlowDecider" do
|
|
2770
2386
|
it "makes sure that you can create a workflow in the new way" do
|
2771
2387
|
class WorkflowWorkflow
|
2772
2388
|
extend Workflows
|
2773
|
-
workflow(:entry_point) { {:version => "1", :
|
2389
|
+
workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
|
2774
2390
|
def entry_point; ;end
|
2775
2391
|
end
|
2776
2392
|
worker = WorkflowWorker.new(@swf.client, @domain, "test", WorkflowWorkflow)
|
2777
2393
|
worker.register
|
2778
2394
|
client = workflow_client(@swf.client, @domain) { {:from_class => "WorkflowWorkflow"} }
|
2779
|
-
|
2395
|
+
workflow_execution = client.start_execution
|
2780
2396
|
worker.run_once
|
2781
|
-
|
2397
|
+
wait_for_execution(workflow_execution)
|
2398
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
2782
2399
|
end
|
2783
2400
|
it "makes sure that you can use with_opts with workflow_client" do
|
2784
2401
|
class WorkflowWorkflow
|
2785
2402
|
extend Workflows
|
2786
|
-
workflow(:entry_point) { {:version => "1", :
|
2403
|
+
workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
|
2787
2404
|
def entry_point; ;end
|
2788
2405
|
end
|
2789
2406
|
worker = WorkflowWorker.new(@swf.client, @domain, "Foobarbaz", WorkflowWorkflow)
|
2790
2407
|
worker.register
|
2791
2408
|
client = workflow_client(@swf.client, @domain) { {:from_class => "WorkflowWorkflow"} }
|
2792
|
-
|
2409
|
+
workflow_execution = client.with_opts(:task_list => "Foobarbaz").start_execution
|
2793
2410
|
worker.run_once
|
2794
|
-
|
2411
|
+
wait_for_execution(workflow_execution)
|
2412
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
2795
2413
|
end
|
2796
2414
|
|
2797
2415
|
it "makes sure you can use with_opts with activity_client" do
|
@@ -2801,7 +2419,7 @@ describe "RubyFlowDecider" do
|
|
2801
2419
|
{
|
2802
2420
|
:version => 1,
|
2803
2421
|
:default_task_list => "options_test",
|
2804
|
-
:default_task_heartbeat_timeout => "
|
2422
|
+
:default_task_heartbeat_timeout => "600",
|
2805
2423
|
:default_task_schedule_to_close_timeout => "60",
|
2806
2424
|
:default_task_schedule_to_start_timeout => "60",
|
2807
2425
|
:default_task_start_to_close_timeout => "60",
|
@@ -2810,16 +2428,17 @@ describe "RubyFlowDecider" do
|
|
2810
2428
|
end
|
2811
2429
|
class WorkflowWorkflow
|
2812
2430
|
extend Workflows
|
2813
|
-
workflow(:entry_point) { {:version => "1", :
|
2431
|
+
workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
|
2814
2432
|
|
2815
2433
|
def entry_point; ;end
|
2816
2434
|
end
|
2817
2435
|
worker = WorkflowWorker.new(@swf.client, @domain, "Foobarbaz", WorkflowWorkflow)
|
2818
2436
|
worker.register
|
2819
2437
|
client = workflow_client(@swf.client, @domain) { {:from_class => "WorkflowWorkflow"} }
|
2820
|
-
|
2438
|
+
workflow_execution = client.with_opts(:task_list => "Foobarbaz").start_execution
|
2821
2439
|
worker.run_once
|
2822
|
-
|
2440
|
+
wait_for_execution(workflow_execution)
|
2441
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
2823
2442
|
end
|
2824
2443
|
|
2825
2444
|
it "makes sure that workflow errors out on schedule_activity_task_failed" do
|
@@ -2833,17 +2452,18 @@ describe "RubyFlowDecider" do
|
|
2833
2452
|
end
|
2834
2453
|
class WorkflowWorkflow
|
2835
2454
|
extend Workflows
|
2836
|
-
workflow(:entry_point) { {:version => "1", :
|
2455
|
+
workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
|
2837
2456
|
activity_client(:client) { {:version => "1", :from_class => "BadActivityActivity"} }
|
2838
2457
|
def entry_point; client.run_activity1; end
|
2839
2458
|
end
|
2840
2459
|
worker = WorkflowWorker.new(@swf.client, @domain, "Foobarbaz", WorkflowWorkflow)
|
2841
2460
|
worker.register
|
2842
2461
|
client = workflow_client(@swf.client, @domain) { {:from_class => "WorkflowWorkflow"} }
|
2843
|
-
|
2462
|
+
workflow_execution = client.with_opts(:task_list => "Foobarbaz").start_execution
|
2844
2463
|
worker.run_once
|
2845
2464
|
worker.run_once
|
2846
|
-
|
2465
|
+
wait_for_execution(workflow_execution)
|
2466
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
|
2847
2467
|
end
|
2848
2468
|
|
2849
2469
|
it "makes sure that you can have arbitrary activity names with from_class" do
|
@@ -2851,7 +2471,7 @@ describe "RubyFlowDecider" do
|
|
2851
2471
|
@activity_class.class_eval do
|
2852
2472
|
activity :test do
|
2853
2473
|
{
|
2854
|
-
:default_task_heartbeat_timeout => "
|
2474
|
+
:default_task_heartbeat_timeout => "600",
|
2855
2475
|
:default_task_list => task_list,
|
2856
2476
|
:default_task_schedule_to_close_timeout => "20",
|
2857
2477
|
:default_task_schedule_to_start_timeout => "20",
|
@@ -2863,7 +2483,7 @@ describe "RubyFlowDecider" do
|
|
2863
2483
|
def test; end
|
2864
2484
|
end
|
2865
2485
|
$activity_class = @activity_class
|
2866
|
-
|
2486
|
+
workflow_execution = @my_workflow_client.start_execution
|
2867
2487
|
@activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary_with_from_class", @activity_class)
|
2868
2488
|
@activity_worker.register
|
2869
2489
|
@workflow_class.class_eval do
|
@@ -2875,7 +2495,8 @@ describe "RubyFlowDecider" do
|
|
2875
2495
|
@worker.run_once
|
2876
2496
|
@activity_worker.run_once
|
2877
2497
|
@worker.run_once
|
2878
|
-
|
2498
|
+
wait_for_execution(workflow_execution)
|
2499
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
2879
2500
|
end
|
2880
2501
|
|
2881
2502
|
it "makes sure that you can have arbitrary activity names" do
|
@@ -2887,7 +2508,7 @@ describe "RubyFlowDecider" do
|
|
2887
2508
|
{
|
2888
2509
|
:default_task_list => "arbitrary_test",
|
2889
2510
|
:version => "1",
|
2890
|
-
:default_task_heartbeat_timeout => "
|
2511
|
+
:default_task_heartbeat_timeout => "600",
|
2891
2512
|
:default_task_schedule_to_close_timeout => "60",
|
2892
2513
|
:default_task_schedule_to_start_timeout => "60",
|
2893
2514
|
:default_task_start_to_close_timeout => "60",
|
@@ -2908,17 +2529,18 @@ describe "RubyFlowDecider" do
|
|
2908
2529
|
activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary_test", ArbitraryActivity)
|
2909
2530
|
activity_worker.register
|
2910
2531
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
2911
|
-
|
2912
|
-
|
2913
|
-
|
2914
|
-
|
2915
|
-
|
2532
|
+
options.workflow_name = "ArbitraryWorkflow"
|
2533
|
+
options.execution_start_to_close_timeout = 600
|
2534
|
+
options.task_start_to_close_timeout = 10
|
2535
|
+
options.child_policy = :REQUEST_CANCEL
|
2536
|
+
options.task_list = "arbitrary_test"
|
2916
2537
|
end
|
2917
|
-
|
2538
|
+
workflow_execution = my_workflow_factory.get_client.start_execution
|
2918
2539
|
worker.run_once
|
2919
2540
|
activity_worker.run_once
|
2920
2541
|
worker.run_once
|
2921
|
-
|
2542
|
+
wait_for_execution(workflow_execution)
|
2543
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
2922
2544
|
end
|
2923
2545
|
it "makes sure that exponential_retry's max_attempts works correctly" do
|
2924
2546
|
general_test(:task_list => "exponential_retry_test_max_attempts", :class_name => "ExponentialRetryMaxAttempts")
|
@@ -2951,6 +2573,7 @@ describe "RubyFlowDecider" do
|
|
2951
2573
|
# Finally, fail
|
2952
2574
|
@worker.run_once
|
2953
2575
|
|
2576
|
+
wait_for_execution(workflow_execution)
|
2954
2577
|
events = workflow_execution.events.map(&:event_type)
|
2955
2578
|
events.count("WorkflowExecutionFailed").should == 1
|
2956
2579
|
(events.count("ActivityTaskFailed") + events.count("ActivityTaskTimedOut")).should >= 3
|
@@ -2989,6 +2612,7 @@ describe "RubyFlowDecider" do
|
|
2989
2612
|
|
2990
2613
|
@worker.run_once
|
2991
2614
|
|
2615
|
+
wait_for_execution(workflow_execution)
|
2992
2616
|
events = workflow_execution.events.map(&:event_type)
|
2993
2617
|
events.count("WorkflowExecutionFailed").should == 1
|
2994
2618
|
(events.count("ActivityTaskFailed") + events.count("ActivityTaskTimedOut")).should >= 3
|
@@ -3028,6 +2652,7 @@ describe "RubyFlowDecider" do
|
|
3028
2652
|
# Finally, fail, catch, and succeed
|
3029
2653
|
@worker.run_once
|
3030
2654
|
|
2655
|
+
wait_for_execution(workflow_execution)
|
3031
2656
|
events = workflow_execution.events.map(&:event_type)
|
3032
2657
|
events.count("WorkflowExecutionCompleted").should == 1
|
3033
2658
|
(events.count("ActivityTaskFailed") + events.count("ActivityTaskTimedOut")).should >= 3
|
@@ -3042,6 +2667,9 @@ describe "RubyFlowDecider" do
|
|
3042
2667
|
end
|
3043
2668
|
workflow_execution = @my_workflow_client.start_execution
|
3044
2669
|
@worker.run_once
|
2670
|
+
@activity_worker.run_once
|
2671
|
+
@worker.run_once
|
2672
|
+
wait_for_execution(workflow_execution)
|
3045
2673
|
# The default registered is 20, we want to make sure we overrode it
|
3046
2674
|
workflow_execution.events.to_a[4].attributes[:start_to_close_timeout].should == 120
|
3047
2675
|
end
|
@@ -3068,6 +2696,7 @@ describe "RubyFlowDecider" do
|
|
3068
2696
|
@worker.run_once
|
3069
2697
|
@activity_worker.run_once
|
3070
2698
|
@worker.run_once
|
2699
|
+
wait_for_execution(workflow_execution)
|
3071
2700
|
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
3072
2701
|
end
|
3073
2702
|
|
@@ -3103,6 +2732,8 @@ describe "RubyFlowDecider" do
|
|
3103
2732
|
@worker.run_once
|
3104
2733
|
sleep 10
|
3105
2734
|
@worker.run_once
|
2735
|
+
wait_for_execution(workflow_execution)
|
2736
|
+
forking_executor.shutdown(1)
|
3106
2737
|
# If we didn't cancel, the activity would fail
|
3107
2738
|
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
3108
2739
|
end
|
@@ -3124,7 +2755,7 @@ describe "RubyFlowDecider" do
|
|
3124
2755
|
workflow_execution = @my_workflow_client.start_execution
|
3125
2756
|
@worker.run_once
|
3126
2757
|
activity_worker.run_once
|
3127
|
-
workflow_execution.events.map(&:event_type).
|
2758
|
+
workflow_execution.events.map(&:event_type).should include("ActivityTaskStarted")
|
3128
2759
|
end
|
3129
2760
|
|
3130
2761
|
it "makes sure that exponential_retry allows you to capture the error" do
|
@@ -3164,6 +2795,7 @@ describe "RubyFlowDecider" do
|
|
3164
2795
|
# Finally, fail
|
3165
2796
|
@worker.run_once
|
3166
2797
|
|
2798
|
+
wait_for_execution(workflow_execution)
|
3167
2799
|
events = workflow_execution.events.map(&:event_type)
|
3168
2800
|
events.count("WorkflowExecutionCompleted").should == 1
|
3169
2801
|
(events.count("ActivityTaskFailed") + events.count("ActivityTaskTimedOut")).should >= 3
|
@@ -3178,7 +2810,7 @@ describe "RubyFlowDecider" do
|
|
3178
2810
|
{
|
3179
2811
|
:default_task_list => "arbitrary_test",
|
3180
2812
|
:version => "1",
|
3181
|
-
:default_task_heartbeat_timeout => "
|
2813
|
+
:default_task_heartbeat_timeout => "600",
|
3182
2814
|
:default_task_schedule_to_close_timeout => "60",
|
3183
2815
|
:default_task_schedule_to_start_timeout => "60",
|
3184
2816
|
:default_task_start_to_close_timeout => "60",
|
@@ -3199,17 +2831,18 @@ describe "RubyFlowDecider" do
|
|
3199
2831
|
activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary_test", ActivitiesActivity)
|
3200
2832
|
activity_worker.register
|
3201
2833
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
3202
|
-
|
3203
|
-
|
3204
|
-
|
3205
|
-
|
3206
|
-
|
2834
|
+
options.workflow_name = "ActivitiesWorkflow"
|
2835
|
+
options.execution_start_to_close_timeout = 600
|
2836
|
+
options.task_start_to_close_timeout = 10
|
2837
|
+
options.child_policy = :REQUEST_CANCEL
|
2838
|
+
options.task_list = "arbitrary_test"
|
3207
2839
|
end
|
3208
|
-
|
2840
|
+
workflow_execution = my_workflow_factory.get_client.start_execution
|
3209
2841
|
worker.run_once
|
3210
2842
|
activity_worker.run_once
|
3211
2843
|
worker.run_once
|
3212
|
-
|
2844
|
+
wait_for_execution(workflow_execution)
|
2845
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
3213
2846
|
end
|
3214
2847
|
|
3215
2848
|
it "makes sure that you can't have a '.' in prefix name" do
|
@@ -3224,15 +2857,16 @@ describe "RubyFlowDecider" do
|
|
3224
2857
|
worker = WorkflowWorker.new(@swf.client, @domain, "arbitrary_test", ArbitraryWorkflow)
|
3225
2858
|
worker.register
|
3226
2859
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
3227
|
-
|
3228
|
-
|
3229
|
-
|
3230
|
-
|
3231
|
-
|
2860
|
+
options.workflow_name = "ArbitraryWorkflow"
|
2861
|
+
options.execution_start_to_close_timeout = 600
|
2862
|
+
options.task_start_to_close_timeout = 10
|
2863
|
+
options.child_policy = :REQUEST_CANCEL
|
2864
|
+
options.task_list = "arbitrary_test"
|
3232
2865
|
end
|
3233
|
-
|
2866
|
+
workflow_execution = my_workflow_factory.get_client.start_execution
|
3234
2867
|
worker.run_once
|
3235
|
-
|
2868
|
+
wait_for_execution(workflow_execution)
|
2869
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
|
3236
2870
|
end
|
3237
2871
|
|
3238
2872
|
it "ensures that reregistering with different values without changing the version will alert you" do
|
@@ -3265,7 +2899,7 @@ describe "RubyFlowDecider" do
|
|
3265
2899
|
activity :foo do |opt|
|
3266
2900
|
opt.default_task_list = "arbitrary_test"
|
3267
2901
|
opt.version = "1"
|
3268
|
-
opt.default_task_heartbeat_timeout = "
|
2902
|
+
opt.default_task_heartbeat_timeout = "600"
|
3269
2903
|
opt.default_task_schedule_to_close_timeout = "60"
|
3270
2904
|
opt.default_task_schedule_to_start_timeout = "60"
|
3271
2905
|
opt.default_task_start_to_close_timeout = "60"
|
@@ -3285,33 +2919,34 @@ describe "RubyFlowDecider" do
|
|
3285
2919
|
activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary_test", ArbitraryActivity)
|
3286
2920
|
activity_worker.register
|
3287
2921
|
my_workflow_factory = workflow_factory @swf.client, @domain do |options|
|
3288
|
-
|
3289
|
-
|
3290
|
-
|
3291
|
-
|
3292
|
-
|
2922
|
+
options.workflow_name = "ArbitraryWorkflow"
|
2923
|
+
options.execution_start_to_close_timeout = 600
|
2924
|
+
options.task_start_to_close_timeout = 10
|
2925
|
+
options.child_policy = :REQUEST_CANCEL
|
2926
|
+
options.task_list = "arbitrary_test"
|
3293
2927
|
end
|
3294
|
-
|
2928
|
+
workflow_execution = my_workflow_factory.get_client.start_execution
|
3295
2929
|
worker.run_once
|
3296
2930
|
activity_worker.run_once
|
3297
2931
|
worker.run_once
|
3298
|
-
|
2932
|
+
wait_for_execution(workflow_execution)
|
2933
|
+
workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
|
3299
2934
|
end
|
3300
2935
|
|
3301
2936
|
describe "Miscellaneous tests" do
|
3302
2937
|
it "will test whether the service client uses the correct user-agent-prefix" do
|
3303
2938
|
|
3304
|
-
|
3305
|
-
|
2939
|
+
domain = get_test_domain
|
2940
|
+
domain.client.config.user_agent_prefix.should == "ruby-flow"
|
3306
2941
|
|
3307
|
-
response =
|
2942
|
+
response = domain.client.list_domains({:registration_status => "REGISTERED"})
|
3308
2943
|
result = response.http_request.headers["user-agent"]
|
3309
2944
|
|
3310
2945
|
result.should match(/^ruby-flow/)
|
3311
2946
|
end
|
3312
2947
|
|
3313
2948
|
it "will test whether from_class can take in non-strings" do
|
3314
|
-
|
2949
|
+
domain = get_test_domain
|
3315
2950
|
|
3316
2951
|
class ActivityActivity
|
3317
2952
|
extend Activity
|
@@ -3323,18 +2958,18 @@ describe "RubyFlowDecider" do
|
|
3323
2958
|
end
|
3324
2959
|
class WorkflowWorkflow
|
3325
2960
|
extend Workflows
|
3326
|
-
workflow(:entry_point) { {:version => "1", :
|
2961
|
+
workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
|
3327
2962
|
activity_client(:activity) { {:version => "1", :from_class => ActivityActivity} }
|
3328
2963
|
def entry_point
|
3329
2964
|
activity.activity1
|
3330
2965
|
end
|
3331
2966
|
end
|
3332
2967
|
|
3333
|
-
client = workflow_client(
|
2968
|
+
client = workflow_client(domain.client, domain) { {:from_class => WorkflowWorkflow} }
|
3334
2969
|
client.is_execution_method(:entry_point).should == true
|
3335
2970
|
end
|
3336
2971
|
it "tests whether a forking executor will not accept work when it has no free workers" do
|
3337
|
-
|
2972
|
+
domain = get_test_domain
|
3338
2973
|
|
3339
2974
|
class ForkingTestActivity
|
3340
2975
|
extend Activity
|
@@ -3344,33 +2979,33 @@ describe "RubyFlowDecider" do
|
|
3344
2979
|
:default_task_list => "forking_executor_test",
|
3345
2980
|
:default_task_schedule_to_start_timeout => 120,
|
3346
2981
|
:default_task_start_to_close_timeout => 120,
|
3347
|
-
:default_task_heartbeat_timeout => "
|
2982
|
+
:default_task_heartbeat_timeout => "600"
|
3348
2983
|
}
|
3349
2984
|
end
|
3350
2985
|
def activity1; sleep 10; end
|
3351
2986
|
end
|
3352
2987
|
class ForkingTestWorkflow
|
3353
2988
|
extend Workflows
|
3354
|
-
workflow(:entry_point) { {:version => "1", :
|
2989
|
+
workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "forking_executor_test"} }
|
3355
2990
|
activity_client(:activity) { {:version => "1", :from_class => ForkingTestActivity} }
|
3356
2991
|
def entry_point
|
3357
2992
|
3.times { activity.send_async(:activity1) }
|
3358
2993
|
end
|
3359
2994
|
end
|
3360
2995
|
|
3361
|
-
worker = WorkflowWorker.new(
|
2996
|
+
worker = WorkflowWorker.new(domain.client, domain, "forking_executor_test", ForkingTestWorkflow)
|
3362
2997
|
worker.register
|
3363
2998
|
|
3364
|
-
activity_worker = ActivityWorker.new(
|
2999
|
+
activity_worker = ActivityWorker.new(domain.client, domain, "forking_executor_test", ForkingTestActivity) { { :execution_workers => 1 } }
|
3365
3000
|
activity_worker.register
|
3366
3001
|
|
3367
|
-
client = workflow_client(
|
3002
|
+
client = workflow_client(domain.client, domain) { {:from_class => ForkingTestWorkflow} }
|
3368
3003
|
|
3369
3004
|
workflow_execution = client.start_execution
|
3370
3005
|
forking_executor = ForkingExecutor.new(:max_workers => 3)
|
3371
3006
|
forking_executor.execute { worker.start }
|
3372
3007
|
forking_executor.execute { activity_worker.start }
|
3373
|
-
|
3008
|
+
wait_for_execution(workflow_execution)
|
3374
3009
|
history = workflow_execution.events.map(&:event_type)
|
3375
3010
|
current_depth = 0
|
3376
3011
|
0.upto(history.length) do |i|
|