dynflow 0.8.16 → 0.8.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +21 -0
  3. data/.rubocop_todo.yml +0 -25
  4. data/doc/pages/plugins/div_tag.rb +1 -1
  5. data/doc/pages/plugins/tags.rb +0 -1
  6. data/examples/orchestrate.rb +0 -1
  7. data/examples/remote_executor.rb +3 -3
  8. data/examples/sub_plan_concurrency_control.rb +0 -1
  9. data/examples/sub_plans.rb +0 -1
  10. data/lib/dynflow.rb +1 -0
  11. data/lib/dynflow/action.rb +6 -6
  12. data/lib/dynflow/config.rb +2 -2
  13. data/lib/dynflow/connectors/database.rb +1 -1
  14. data/lib/dynflow/connectors/direct.rb +1 -1
  15. data/lib/dynflow/coordinator.rb +4 -4
  16. data/lib/dynflow/director.rb +190 -0
  17. data/lib/dynflow/director/execution_plan_manager.rb +107 -0
  18. data/lib/dynflow/director/flow_manager.rb +43 -0
  19. data/lib/dynflow/director/running_steps_manager.rb +79 -0
  20. data/lib/dynflow/director/sequence_cursor.rb +91 -0
  21. data/lib/dynflow/{executors/parallel → director}/sequential_manager.rb +2 -2
  22. data/lib/dynflow/director/work_queue.rb +48 -0
  23. data/lib/dynflow/dispatcher/client_dispatcher.rb +24 -24
  24. data/lib/dynflow/dispatcher/executor_dispatcher.rb +1 -1
  25. data/lib/dynflow/execution_plan.rb +32 -15
  26. data/lib/dynflow/execution_plan/steps/abstract.rb +14 -14
  27. data/lib/dynflow/execution_plan/steps/error.rb +1 -1
  28. data/lib/dynflow/execution_plan/steps/finalize_step.rb +0 -1
  29. data/lib/dynflow/execution_plan/steps/plan_step.rb +11 -12
  30. data/lib/dynflow/execution_plan/steps/run_step.rb +1 -1
  31. data/lib/dynflow/executors/abstract.rb +5 -8
  32. data/lib/dynflow/executors/parallel.rb +4 -34
  33. data/lib/dynflow/executors/parallel/core.rb +18 -118
  34. data/lib/dynflow/executors/parallel/pool.rb +2 -2
  35. data/lib/dynflow/executors/parallel/worker.rb +3 -11
  36. data/lib/dynflow/persistence_adapters/sequel.rb +1 -2
  37. data/lib/dynflow/testing.rb +2 -0
  38. data/lib/dynflow/testing/in_thread_executor.rb +52 -0
  39. data/lib/dynflow/testing/in_thread_world.rb +64 -0
  40. data/lib/dynflow/testing/managed_clock.rb +1 -1
  41. data/lib/dynflow/throttle_limiter.rb +1 -1
  42. data/lib/dynflow/version.rb +1 -1
  43. data/lib/dynflow/world.rb +13 -7
  44. data/test/abnormal_states_recovery_test.rb +10 -0
  45. data/test/action_test.rb +9 -9
  46. data/test/clock_test.rb +0 -2
  47. data/test/concurrency_control_test.rb +1 -1
  48. data/test/execution_plan_test.rb +0 -2
  49. data/test/executor_test.rb +6 -13
  50. data/test/support/code_workflow_example.rb +1 -1
  51. data/test/support/rescue_example.rb +0 -1
  52. data/test/test_helper.rb +9 -12
  53. data/test/testing_test.rb +74 -2
  54. data/web/views/plan_step.erb +2 -0
  55. metadata +11 -8
  56. data/lib/dynflow/executors/parallel/execution_plan_manager.rb +0 -111
  57. data/lib/dynflow/executors/parallel/flow_manager.rb +0 -45
  58. data/lib/dynflow/executors/parallel/running_steps_manager.rb +0 -81
  59. data/lib/dynflow/executors/parallel/sequence_cursor.rb +0 -97
  60. 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