aws-flow 1.0.7 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/aws/decider/history_helper.rb +1 -0
- data/lib/aws/decider/task_poller.rb +3 -2
- data/lib/aws/decider/version.rb +1 -1
- data/test/aws/decider_spec.rb +175 -13
- data/test/aws/integration_spec.rb +8 -8
- metadata +2 -2
@@ -131,6 +131,7 @@ module AWS
|
|
131
131
|
decision_start_to_completion_events, decision_completion_to_start_events = [], []
|
132
132
|
next_replay_current_time_milliseconds = -1
|
133
133
|
last_decision_index = -1
|
134
|
+
concurrent_to_decision = true
|
134
135
|
while @events.events.length > 0
|
135
136
|
event = @events.events.shift
|
136
137
|
event_type = event.event_type.to_sym
|
@@ -89,7 +89,6 @@ module AWS
|
|
89
89
|
@logger = options.logger if options
|
90
90
|
@logger ||= Utilities::LogFactory.make_logger(self, "debug")
|
91
91
|
@executor = executor
|
92
|
-
|
93
92
|
end
|
94
93
|
|
95
94
|
def execute(task)
|
@@ -166,11 +165,13 @@ module AWS
|
|
166
165
|
end
|
167
166
|
|
168
167
|
def poll_and_process_single_task(use_forking = true)
|
169
|
-
|
170
168
|
@poll_semaphore ||= SuspendableSemaphore.new
|
171
169
|
@poll_semaphore.acquire
|
172
170
|
semaphore_needs_release = true
|
173
171
|
@logger.debug "before the poll\n\n"
|
172
|
+
# This is to warm the lazily loaded clients in the @service, so we don't
|
173
|
+
# pay for their loading in every forked client
|
174
|
+
@service.config.to_h
|
174
175
|
begin
|
175
176
|
if use_forking
|
176
177
|
@executor.block_on_max_workers
|
data/lib/aws/decider/version.rb
CHANGED
data/test/aws/decider_spec.rb
CHANGED
@@ -17,10 +17,43 @@ require 'yaml'
|
|
17
17
|
|
18
18
|
require 'aws/decider'
|
19
19
|
include AWS::Flow
|
20
|
+
class FakeConfig
|
21
|
+
def to_h
|
20
22
|
|
23
|
+
end
|
24
|
+
end
|
21
25
|
|
22
26
|
$RUBYFLOW_DECIDER_DOMAIN = "rubyflow_decider_domain_06-12-2012"
|
23
27
|
$RUBYFLOW_DECIDER_TASK_LIST = 'test_task_list'
|
28
|
+
|
29
|
+
class FakeAttribute
|
30
|
+
def initialize(data); @data = data; end
|
31
|
+
def method_missing(method_name, *args, &block)
|
32
|
+
if @data.keys.include? method_name
|
33
|
+
return @data[method_name]
|
34
|
+
end
|
35
|
+
super
|
36
|
+
end
|
37
|
+
def keys; @data.keys; end
|
38
|
+
def [](key); @data[key]; end
|
39
|
+
def to_h; @data; end
|
40
|
+
def []=(key, val); @data[key] = val; end
|
41
|
+
end
|
42
|
+
|
43
|
+
class FakeEvents
|
44
|
+
def initialize(args)
|
45
|
+
@events = []
|
46
|
+
args.each_with_index do |event, index|
|
47
|
+
event, attr = event if event.is_a? Array
|
48
|
+
attr ||= {}
|
49
|
+
@events << TestHistoryEvent.new(event, index + 1, FakeAttribute.new(attr))
|
50
|
+
end
|
51
|
+
@events
|
52
|
+
end
|
53
|
+
def to_a
|
54
|
+
@events
|
55
|
+
end
|
56
|
+
end
|
24
57
|
class TrivialConverter
|
25
58
|
def dump(x)
|
26
59
|
x
|
@@ -44,9 +77,11 @@ class FakePage
|
|
44
77
|
end
|
45
78
|
|
46
79
|
class FakeWorkflowExecution
|
47
|
-
def run_id
|
48
|
-
|
80
|
+
def initialize(run_id = "1", workflow_id = "1")
|
81
|
+
@run_id = run_id
|
82
|
+
@workflow_id = workflow_id
|
49
83
|
end
|
84
|
+
attr_accessor :run_id, :workflow_id
|
50
85
|
end
|
51
86
|
|
52
87
|
class FakeWorkflowExecutionCollecton
|
@@ -142,6 +177,7 @@ describe Activity do
|
|
142
177
|
end
|
143
178
|
|
144
179
|
describe WorkflowClient do
|
180
|
+
|
145
181
|
class FakeServiceClient
|
146
182
|
attr_accessor :trace
|
147
183
|
def respond_decision_task_completed(task_completed_request)
|
@@ -155,6 +191,7 @@ describe WorkflowClient do
|
|
155
191
|
end
|
156
192
|
def register_workflow_type(options)
|
157
193
|
end
|
194
|
+
|
158
195
|
end
|
159
196
|
class TestWorkflow
|
160
197
|
extend Decider
|
@@ -414,6 +451,9 @@ describe "FakeHistory" do
|
|
414
451
|
def start_workflow_execution(options)
|
415
452
|
{"runId" => "blah"}
|
416
453
|
end
|
454
|
+
def config
|
455
|
+
FakeConfig.new
|
456
|
+
end
|
417
457
|
end
|
418
458
|
|
419
459
|
class Hash
|
@@ -1198,17 +1238,6 @@ describe "FakeHistory" do
|
|
1198
1238
|
end
|
1199
1239
|
|
1200
1240
|
it "ensures that CompleteWorkflowExecutionFailed is correctly handled" do
|
1201
|
-
class FakeAttribute
|
1202
|
-
def initialize(data)
|
1203
|
-
@data = data
|
1204
|
-
end
|
1205
|
-
def method_missing(method_name, *args, &block)
|
1206
|
-
if @data.keys.include? method_name
|
1207
|
-
return @data[method_name]
|
1208
|
-
end
|
1209
|
-
super
|
1210
|
-
end
|
1211
|
-
end
|
1212
1241
|
|
1213
1242
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1214
1243
|
def get_decision_tasks
|
@@ -1275,6 +1304,139 @@ describe "FakeHistory" do
|
|
1275
1304
|
worker.start
|
1276
1305
|
swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
|
1277
1306
|
end
|
1307
|
+
|
1308
|
+
it "ensures that time outs do not cause problems" do
|
1309
|
+
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1310
|
+
def get_decision_tasks
|
1311
|
+
fake_workflow_type = FakeWorkflowType.new(nil, "TimeOutWorkflow.entry_point", "1")
|
1312
|
+
TestHistoryWrapper.new(fake_workflow_type,
|
1313
|
+
FakeEvents.new(["WorkflowExecutionStarted",
|
1314
|
+
"DecisionTaskScheduled",
|
1315
|
+
"DecisionTaskStarted",
|
1316
|
+
"DecisionTaskCompleted",
|
1317
|
+
["StartChildWorkflowExecutionInitiated", {:workflow_id => "child_workflow_test"}],
|
1318
|
+
["ChildWorkflowExecutionStarted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
|
1319
|
+
"DecisionTaskScheduled",
|
1320
|
+
"DecisionTaskStarted",
|
1321
|
+
["ChildWorkflowExecutionCompleted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
|
1322
|
+
"DecisionTaskScheduled",
|
1323
|
+
"DecisionTaskTimedOut",
|
1324
|
+
"DecisionTaskStarted",
|
1325
|
+
"DecisionTaskCompleted",
|
1326
|
+
["ActivityTaskScheduled", {:activity_id => "Activity1"}],
|
1327
|
+
"ActivityTaskStarted",
|
1328
|
+
["ActivityTaskCompleted", {:scheduled_event_id => 14}],
|
1329
|
+
"DecisionTaskScheduled",
|
1330
|
+
"DecisionTaskStarted"
|
1331
|
+
]))
|
1332
|
+
end
|
1333
|
+
end
|
1334
|
+
workflow_type_object = double("workflow_type", :name => "TimeOutWorkflow.entry_point", :start_execution => "" )
|
1335
|
+
|
1336
|
+
|
1337
|
+
domain = FakeDomain.new(workflow_type_object)
|
1338
|
+
swf_client = FakeServiceClient.new
|
1339
|
+
$my_workflow_client = workflow_client(swf_client, domain) {{:prefix_name => "TimeOutWorkflow", :execution_method => "entry_point", :version => "1"}}
|
1340
|
+
class TimeOutActivity
|
1341
|
+
extend Activity
|
1342
|
+
activity :run_activity1
|
1343
|
+
def run_activity1; nil; end
|
1344
|
+
end
|
1345
|
+
class TimeOutWorkflow
|
1346
|
+
extend Workflows
|
1347
|
+
workflow(:entry_point) { {:version => "1"} }
|
1348
|
+
activity_client(:activity) { {:version => "1", :prefix_name => "TimeOutActivity" } }
|
1349
|
+
|
1350
|
+
def entry_point
|
1351
|
+
$my_workflow_client.start_execution() { {:task_list => "nonsense_task_list", :workflow_id => "child_workflow_test"}}
|
1352
|
+
activity_client.run_activity1
|
1353
|
+
p "yay"
|
1354
|
+
end
|
1355
|
+
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
task_list = "TimeOutWorkflow_tasklist"
|
1359
|
+
my_workflow_factory = workflow_factory(swf_client, domain) do |options|
|
1360
|
+
options.workflow_name = "TimeOutWorkflow"
|
1361
|
+
options.execution_start_to_close_timeout = 3600
|
1362
|
+
options.task_list = task_list
|
1363
|
+
end
|
1364
|
+
|
1365
|
+
worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
|
1366
|
+
worker.add_workflow_implementation(TimeOutWorkflow)
|
1367
|
+
my_workflow = my_workflow_factory.get_client
|
1368
|
+
workflow_execution = my_workflow.start_execution
|
1369
|
+
worker.start
|
1370
|
+
swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
it "ensures that the other timeout issue is not a problem" do
|
1374
|
+
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1375
|
+
def get_decision_tasks
|
1376
|
+
fake_workflow_type = FakeWorkflowType.new(nil, "OtherTimeOutWorkflow.entry_point", "1")
|
1377
|
+
TestHistoryWrapper.new(fake_workflow_type,
|
1378
|
+
FakeEvents.new(["WorkflowExecutionStarted",
|
1379
|
+
"DecisionTaskScheduled",
|
1380
|
+
"DecisionTaskStarted",
|
1381
|
+
"DecisionTaskCompleted",
|
1382
|
+
["ActivityTaskScheduled", {:activity_id => "Activity1"}],
|
1383
|
+
["ActivityTaskScheduled", {:activity_id => "Activity2"}],
|
1384
|
+
"ActivityTaskStarted",
|
1385
|
+
"ActivityTaskStarted",
|
1386
|
+
["ActivityTaskCompleted", {:scheduled_event_id => 5}],
|
1387
|
+
"DecisionTaskScheduled",
|
1388
|
+
"DecisionTaskStarted",
|
1389
|
+
["ActivityTaskCompleted", {:scheduled_event_id => 6}],
|
1390
|
+
"DecisionTaskScheduled",
|
1391
|
+
"DecisionTaskTimedOut",
|
1392
|
+
"DecisionTaskStarted",
|
1393
|
+
"DecisionTaskCompleted",
|
1394
|
+
["ActivityTaskScheduled", {:activity_id => "Activity3"}],
|
1395
|
+
"ActivityTaskStarted",
|
1396
|
+
["ActivityTaskCompleted", {:scheduled_event_id => 17}],
|
1397
|
+
"DecisionTaskScheduled",
|
1398
|
+
"DecisionTaskStarted"
|
1399
|
+
]))
|
1400
|
+
end
|
1401
|
+
end
|
1402
|
+
workflow_type_object = double("workflow_type", :name => "OtherTimeOutWorkflow.entry_point", :start_execution => "" )
|
1403
|
+
domain = FakeDomain.new(workflow_type_object)
|
1404
|
+
swf_client = FakeServiceClient.new
|
1405
|
+
$my_workflow_client = workflow_client(swf_client, domain) {{:prefix_name => "OtherTimeOutWorkflow", :execution_method => "entry_point", :version => "1"}}
|
1406
|
+
class OtherTimeOutActivity
|
1407
|
+
extend Activity
|
1408
|
+
activity :run_activity1
|
1409
|
+
def run_activity1; nil; end
|
1410
|
+
end
|
1411
|
+
class OtherTimeOutWorkflow
|
1412
|
+
extend Workflows
|
1413
|
+
workflow(:entry_point) { {:version => "1"} }
|
1414
|
+
activity_client(:activity) { {:version => "1", :prefix_name => "OtherTimeOutActivity" } }
|
1415
|
+
|
1416
|
+
def entry_point
|
1417
|
+
futures = []
|
1418
|
+
futures << activity_client.send_async(:run_activity1)
|
1419
|
+
futures << activity_client.send_async(:run_activity1)
|
1420
|
+
wait_for_all(futures)
|
1421
|
+
activity_client.run_activity1
|
1422
|
+
end
|
1423
|
+
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
task_list = "OtherTimeOutWorkflow_tasklist"
|
1427
|
+
my_workflow_factory = workflow_factory(swf_client, domain) do |options|
|
1428
|
+
options.workflow_name = "OtherTimeOutWorkflow"
|
1429
|
+
options.execution_start_to_close_timeout = 3600
|
1430
|
+
options.task_list = task_list
|
1431
|
+
end
|
1432
|
+
|
1433
|
+
worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
|
1434
|
+
worker.add_workflow_implementation(OtherTimeOutWorkflow)
|
1435
|
+
my_workflow = my_workflow_factory.get_client
|
1436
|
+
workflow_execution = my_workflow.start_execution
|
1437
|
+
worker.start
|
1438
|
+
swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
|
1439
|
+
end
|
1278
1440
|
end
|
1279
1441
|
|
1280
1442
|
describe "Misc tests" do
|
@@ -1007,6 +1007,7 @@ describe "RubyFlowDecider" do
|
|
1007
1007
|
raise "simulated error"
|
1008
1008
|
end
|
1009
1009
|
def run_activity2
|
1010
|
+
|
1010
1011
|
end
|
1011
1012
|
end
|
1012
1013
|
workflow_execution = @my_workflow_client.start_execution
|
@@ -1014,8 +1015,10 @@ describe "RubyFlowDecider" do
|
|
1014
1015
|
@activity_worker.run_once
|
1015
1016
|
@worker.run_once
|
1016
1017
|
@worker.run_once
|
1017
|
-
workflow_execution.events.map(&:event_type)
|
1018
|
-
|
1018
|
+
history = workflow_execution.events.map(&:event_type)
|
1019
|
+
history.last.should == "WorkflowExecutionFailed"
|
1020
|
+
# Should look something like: ["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskFailed", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskCancelRequested", "ActivityTaskCanceled", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionFailed"]
|
1021
|
+
history.should include "ActivityTaskCancelRequested"
|
1019
1022
|
end
|
1020
1023
|
|
1021
1024
|
it "makes sure that you can use the :exponential_retry key" do
|
@@ -2285,7 +2288,6 @@ describe "RubyFlowDecider" do
|
|
2285
2288
|
version "1"
|
2286
2289
|
entry_point :entry_point
|
2287
2290
|
def entry_point
|
2288
|
-
"yay"
|
2289
2291
|
end
|
2290
2292
|
end
|
2291
2293
|
worker = WorkflowWorker.new(swf.client, domain, "timeout_test", WorkflowIDWorkflow)
|
@@ -2529,7 +2531,6 @@ describe "RubyFlowDecider" do
|
|
2529
2531
|
version "1"
|
2530
2532
|
entry_point :entry_point
|
2531
2533
|
def entry_point
|
2532
|
-
"yay"
|
2533
2534
|
end
|
2534
2535
|
end
|
2535
2536
|
worker = WorkflowWorker.new(@swf.client, @domain, "client_test_inheritance", OptionsWorkflow)
|
@@ -2552,7 +2553,6 @@ describe "RubyFlowDecider" do
|
|
2552
2553
|
version "1"
|
2553
2554
|
entry_point :entry_point
|
2554
2555
|
def entry_point
|
2555
|
-
"yay"
|
2556
2556
|
end
|
2557
2557
|
end
|
2558
2558
|
worker = WorkflowWorker.new(@swf.client, @domain, "client_test_inheritance", OptionsWorkflow)
|
@@ -2742,7 +2742,7 @@ describe "RubyFlowDecider" do
|
|
2742
2742
|
class WorkflowWorkflow
|
2743
2743
|
extend Workflows
|
2744
2744
|
workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "test"} }
|
2745
|
-
def entry_point;
|
2745
|
+
def entry_point; ;end
|
2746
2746
|
end
|
2747
2747
|
worker = WorkflowWorker.new(@swf.client, @domain, "test", WorkflowWorkflow)
|
2748
2748
|
worker.register
|
@@ -2755,7 +2755,7 @@ describe "RubyFlowDecider" do
|
|
2755
2755
|
class WorkflowWorkflow
|
2756
2756
|
extend Workflows
|
2757
2757
|
workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "test"} }
|
2758
|
-
def entry_point;
|
2758
|
+
def entry_point; ;end
|
2759
2759
|
end
|
2760
2760
|
worker = WorkflowWorker.new(@swf.client, @domain, "Foobarbaz", WorkflowWorkflow)
|
2761
2761
|
worker.register
|
@@ -2783,7 +2783,7 @@ describe "RubyFlowDecider" do
|
|
2783
2783
|
extend Workflows
|
2784
2784
|
workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "test"} }
|
2785
2785
|
|
2786
|
-
def entry_point;
|
2786
|
+
def entry_point; ;end
|
2787
2787
|
end
|
2788
2788
|
worker = WorkflowWorker.new(@swf.client, @domain, "Foobarbaz", WorkflowWorkflow)
|
2789
2789
|
worker.register
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-flow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-01-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|