dynflow 0.8.16 → 0.8.17
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 +4 -4
- data/.rubocop.yml +21 -0
- data/.rubocop_todo.yml +0 -25
- data/doc/pages/plugins/div_tag.rb +1 -1
- data/doc/pages/plugins/tags.rb +0 -1
- data/examples/orchestrate.rb +0 -1
- data/examples/remote_executor.rb +3 -3
- data/examples/sub_plan_concurrency_control.rb +0 -1
- data/examples/sub_plans.rb +0 -1
- data/lib/dynflow.rb +1 -0
- data/lib/dynflow/action.rb +6 -6
- data/lib/dynflow/config.rb +2 -2
- data/lib/dynflow/connectors/database.rb +1 -1
- data/lib/dynflow/connectors/direct.rb +1 -1
- data/lib/dynflow/coordinator.rb +4 -4
- data/lib/dynflow/director.rb +190 -0
- data/lib/dynflow/director/execution_plan_manager.rb +107 -0
- data/lib/dynflow/director/flow_manager.rb +43 -0
- data/lib/dynflow/director/running_steps_manager.rb +79 -0
- data/lib/dynflow/director/sequence_cursor.rb +91 -0
- data/lib/dynflow/{executors/parallel → director}/sequential_manager.rb +2 -2
- data/lib/dynflow/director/work_queue.rb +48 -0
- data/lib/dynflow/dispatcher/client_dispatcher.rb +24 -24
- data/lib/dynflow/dispatcher/executor_dispatcher.rb +1 -1
- data/lib/dynflow/execution_plan.rb +32 -15
- data/lib/dynflow/execution_plan/steps/abstract.rb +14 -14
- data/lib/dynflow/execution_plan/steps/error.rb +1 -1
- data/lib/dynflow/execution_plan/steps/finalize_step.rb +0 -1
- data/lib/dynflow/execution_plan/steps/plan_step.rb +11 -12
- data/lib/dynflow/execution_plan/steps/run_step.rb +1 -1
- data/lib/dynflow/executors/abstract.rb +5 -8
- data/lib/dynflow/executors/parallel.rb +4 -34
- data/lib/dynflow/executors/parallel/core.rb +18 -118
- data/lib/dynflow/executors/parallel/pool.rb +2 -2
- data/lib/dynflow/executors/parallel/worker.rb +3 -11
- data/lib/dynflow/persistence_adapters/sequel.rb +1 -2
- data/lib/dynflow/testing.rb +2 -0
- data/lib/dynflow/testing/in_thread_executor.rb +52 -0
- data/lib/dynflow/testing/in_thread_world.rb +64 -0
- data/lib/dynflow/testing/managed_clock.rb +1 -1
- data/lib/dynflow/throttle_limiter.rb +1 -1
- data/lib/dynflow/version.rb +1 -1
- data/lib/dynflow/world.rb +13 -7
- data/test/abnormal_states_recovery_test.rb +10 -0
- data/test/action_test.rb +9 -9
- data/test/clock_test.rb +0 -2
- data/test/concurrency_control_test.rb +1 -1
- data/test/execution_plan_test.rb +0 -2
- data/test/executor_test.rb +6 -13
- data/test/support/code_workflow_example.rb +1 -1
- data/test/support/rescue_example.rb +0 -1
- data/test/test_helper.rb +9 -12
- data/test/testing_test.rb +74 -2
- data/web/views/plan_step.erb +2 -0
- metadata +11 -8
- data/lib/dynflow/executors/parallel/execution_plan_manager.rb +0 -111
- data/lib/dynflow/executors/parallel/flow_manager.rb +0 -45
- data/lib/dynflow/executors/parallel/running_steps_manager.rb +0 -81
- data/lib/dynflow/executors/parallel/sequence_cursor.rb +0 -97
- data/lib/dynflow/executors/parallel/work_queue.rb +0 -50
@@ -1,97 +0,0 @@
|
|
1
|
-
module Dynflow
|
2
|
-
module Executors
|
3
|
-
class Parallel < Abstract
|
4
|
-
class SequenceCursor
|
5
|
-
|
6
|
-
def initialize(flow_manager, sequence, parent_cursor = nil)
|
7
|
-
@flow_manager = flow_manager
|
8
|
-
@sequence = sequence
|
9
|
-
@parent_cursor = parent_cursor
|
10
|
-
@todo = []
|
11
|
-
@index = -1 # starts before first element
|
12
|
-
@no_error_so_far = true
|
13
|
-
end
|
14
|
-
|
15
|
-
# @param [ExecutionPlan::Steps::Abstract, SequenceCursor] work
|
16
|
-
# step or sequence cursor that was done
|
17
|
-
# @param [true, false] success was the work finished successfully
|
18
|
-
# @return [Array<Integer>] new step_ids that can be done next
|
19
|
-
def what_is_next(work = nil, success = true)
|
20
|
-
unless work.nil? || @todo.delete(work)
|
21
|
-
raise "marking as done work that was not expected: #{work.inspect}"
|
22
|
-
end
|
23
|
-
|
24
|
-
@no_error_so_far &&= success
|
25
|
-
|
26
|
-
if done_here?
|
27
|
-
return next_steps
|
28
|
-
else
|
29
|
-
return []
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
# return true if we can't move the cursor further, either when
|
35
|
-
# everyting is done in the sequence or there was some failure
|
36
|
-
# that prevents us from moving
|
37
|
-
def done?
|
38
|
-
(!@no_error_so_far && done_here?) || @index == @sequence.size
|
39
|
-
end
|
40
|
-
|
41
|
-
protected
|
42
|
-
|
43
|
-
# steps we can do right now without waiting for anything
|
44
|
-
def steps_todo
|
45
|
-
@todo.map do |item|
|
46
|
-
case item
|
47
|
-
when SequenceCursor
|
48
|
-
item.steps_todo
|
49
|
-
else
|
50
|
-
item
|
51
|
-
end
|
52
|
-
end.flatten
|
53
|
-
end
|
54
|
-
|
55
|
-
def move
|
56
|
-
@index += 1
|
57
|
-
next_flow = @sequence.sub_flows[@index]
|
58
|
-
add_todo(next_flow)
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def done_here?
|
64
|
-
@todo.empty?
|
65
|
-
end
|
66
|
-
|
67
|
-
def next_steps
|
68
|
-
move if @no_error_so_far
|
69
|
-
if done?
|
70
|
-
if @parent_cursor
|
71
|
-
return @parent_cursor.what_is_next(self, @no_error_so_far)
|
72
|
-
else
|
73
|
-
return []
|
74
|
-
end
|
75
|
-
else
|
76
|
-
return steps_todo
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def add_todo(flow)
|
81
|
-
case flow
|
82
|
-
when Flows::Sequence
|
83
|
-
@todo << SequenceCursor.new(@flow_manager, flow, self).tap do |cursor|
|
84
|
-
cursor.move
|
85
|
-
end
|
86
|
-
when Flows::Concurrence
|
87
|
-
flow.sub_flows.each { |sub_flow| add_todo(sub_flow) }
|
88
|
-
when Flows::Atom
|
89
|
-
@flow_manager.cursor_index[flow.step_id] = self
|
90
|
-
@todo << @flow_manager.execution_plan.steps[flow.step_id]
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
module Dynflow
|
2
|
-
module Executors
|
3
|
-
class Parallel < Abstract
|
4
|
-
class WorkQueue
|
5
|
-
include Algebrick::TypeCheck
|
6
|
-
|
7
|
-
def initialize(key_type = Object, work_type = Object)
|
8
|
-
@key_type = key_type
|
9
|
-
@work_type = work_type
|
10
|
-
@stash = Hash.new { |hash, key| hash[key] = [] }
|
11
|
-
end
|
12
|
-
|
13
|
-
def push(key, work)
|
14
|
-
Type! key, @key_type
|
15
|
-
Type! work, @work_type
|
16
|
-
@stash[key].push work
|
17
|
-
end
|
18
|
-
|
19
|
-
def shift(key)
|
20
|
-
return nil unless present? key
|
21
|
-
@stash[key].shift.tap { |work| @stash.delete(key) if @stash[key].empty? }
|
22
|
-
end
|
23
|
-
|
24
|
-
def present?(key)
|
25
|
-
@stash.key?(key)
|
26
|
-
end
|
27
|
-
|
28
|
-
def empty?(key)
|
29
|
-
!present?(key)
|
30
|
-
end
|
31
|
-
|
32
|
-
def clear
|
33
|
-
ret = @stash.dup
|
34
|
-
@stash.clear
|
35
|
-
ret
|
36
|
-
end
|
37
|
-
|
38
|
-
def size(key)
|
39
|
-
return 0 if empty?(key)
|
40
|
-
@stash[key].size
|
41
|
-
end
|
42
|
-
|
43
|
-
def first(key)
|
44
|
-
return nil if empty?(key)
|
45
|
-
@stash[key].first
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|