dynflow 1.8.1 → 1.8.3

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.
Files changed (233) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.rubocop.yml +11 -5
  4. data/.rubocop_todo.yml +777 -345
  5. data/Gemfile +4 -3
  6. data/Rakefile +1 -0
  7. data/doc/pages/Gemfile +4 -3
  8. data/doc/pages/Rakefile +1 -0
  9. data/doc/pages/plugins/alert_block.rb +1 -0
  10. data/doc/pages/plugins/div_tag.rb +1 -0
  11. data/doc/pages/plugins/graphviz.rb +6 -6
  12. data/doc/pages/plugins/plantuml.rb +2 -3
  13. data/doc/pages/plugins/play.rb +1 -2
  14. data/doc/pages/plugins/tags.rb +2 -8
  15. data/doc/pages/plugins/toc.rb +1 -1
  16. data/dynflow.gemspec +11 -10
  17. data/examples/clock_benchmark.rb +1 -0
  18. data/examples/example_helper.rb +4 -3
  19. data/examples/future_execution.rb +0 -2
  20. data/examples/memory_limit_watcher.rb +8 -8
  21. data/examples/orchestrate.rb +9 -21
  22. data/examples/orchestrate_evented.rb +18 -33
  23. data/examples/remote_executor.rb +13 -14
  24. data/examples/singletons.rb +1 -0
  25. data/examples/sub_plan_concurrency_control.rb +0 -1
  26. data/examples/sub_plans.rb +1 -0
  27. data/examples/sub_plans_v2.rb +1 -0
  28. data/lib/dynflow/action/cancellable.rb +1 -0
  29. data/lib/dynflow/action/format.rb +1 -4
  30. data/lib/dynflow/action/missing.rb +4 -4
  31. data/lib/dynflow/action/polling.rb +2 -3
  32. data/lib/dynflow/action/progress.rb +1 -4
  33. data/lib/dynflow/action/rescue.rb +1 -2
  34. data/lib/dynflow/action/singleton.rb +1 -0
  35. data/lib/dynflow/action/suspended.rb +1 -0
  36. data/lib/dynflow/action/timeouts.rb +2 -1
  37. data/lib/dynflow/action/with_bulk_sub_plans.rb +1 -0
  38. data/lib/dynflow/action/with_polling_sub_plans.rb +1 -1
  39. data/lib/dynflow/action/with_sub_plans.rb +20 -19
  40. data/lib/dynflow/action.rb +37 -37
  41. data/lib/dynflow/active_job/queue_adapter.rb +2 -1
  42. data/lib/dynflow/actor.rb +2 -2
  43. data/lib/dynflow/actors/execution_plan_cleaner.rb +1 -0
  44. data/lib/dynflow/actors.rb +1 -0
  45. data/lib/dynflow/clock.rb +3 -4
  46. data/lib/dynflow/config.rb +6 -5
  47. data/lib/dynflow/connectors/abstract.rb +11 -10
  48. data/lib/dynflow/connectors/database.rb +2 -2
  49. data/lib/dynflow/connectors/direct.rb +2 -3
  50. data/lib/dynflow/connectors.rb +1 -0
  51. data/lib/dynflow/coordinator.rb +2 -6
  52. data/lib/dynflow/coordinator_adapters/abstract.rb +1 -0
  53. data/lib/dynflow/coordinator_adapters/sequel.rb +1 -0
  54. data/lib/dynflow/coordinator_adapters.rb +1 -2
  55. data/lib/dynflow/dead_letter_silencer.rb +1 -0
  56. data/lib/dynflow/debug/telemetry/persistence.rb +3 -2
  57. data/lib/dynflow/delayed_executors/abstract.rb +1 -2
  58. data/lib/dynflow/delayed_executors/abstract_core.rb +1 -1
  59. data/lib/dynflow/delayed_executors/polling.rb +1 -2
  60. data/lib/dynflow/delayed_executors.rb +1 -2
  61. data/lib/dynflow/delayed_plan.rb +6 -6
  62. data/lib/dynflow/director/execution_plan_manager.rb +1 -1
  63. data/lib/dynflow/director/flow_manager.rb +1 -0
  64. data/lib/dynflow/director/queue_hash.rb +2 -1
  65. data/lib/dynflow/director/running_steps_manager.rb +3 -2
  66. data/lib/dynflow/director/sequence_cursor.rb +1 -2
  67. data/lib/dynflow/director/sequential_manager.rb +1 -0
  68. data/lib/dynflow/director.rb +12 -11
  69. data/lib/dynflow/dispatcher/abstract.rb +1 -0
  70. data/lib/dynflow/dispatcher/client_dispatcher.rb +33 -33
  71. data/lib/dynflow/dispatcher/executor_dispatcher.rb +7 -6
  72. data/lib/dynflow/dispatcher.rb +8 -7
  73. data/lib/dynflow/errors.rb +1 -0
  74. data/lib/dynflow/execution_history.rb +2 -1
  75. data/lib/dynflow/execution_plan/dependency_graph.rb +1 -2
  76. data/lib/dynflow/execution_plan/hooks.rb +1 -1
  77. data/lib/dynflow/execution_plan/output_reference.rb +4 -4
  78. data/lib/dynflow/execution_plan/steps/abstract.rb +21 -20
  79. data/lib/dynflow/execution_plan/steps/abstract_flow_step.rb +1 -1
  80. data/lib/dynflow/execution_plan/steps/error.rb +10 -9
  81. data/lib/dynflow/execution_plan/steps/finalize_step.rb +1 -2
  82. data/lib/dynflow/execution_plan/steps/plan_step.rb +12 -11
  83. data/lib/dynflow/execution_plan/steps/run_step.rb +1 -1
  84. data/lib/dynflow/execution_plan/steps.rb +1 -2
  85. data/lib/dynflow/execution_plan.rb +46 -46
  86. data/lib/dynflow/executors/abstract/core.rb +4 -3
  87. data/lib/dynflow/executors/parallel/core.rb +3 -2
  88. data/lib/dynflow/executors/parallel/pool.rb +1 -4
  89. data/lib/dynflow/executors/parallel/worker.rb +1 -0
  90. data/lib/dynflow/executors/parallel.rb +3 -2
  91. data/lib/dynflow/executors/sidekiq/core.rb +3 -1
  92. data/lib/dynflow/executors/sidekiq/internal_job_base.rb +1 -0
  93. data/lib/dynflow/executors/sidekiq/orchestrator_jobs.rb +1 -0
  94. data/lib/dynflow/executors/sidekiq/redis_locking.rb +1 -0
  95. data/lib/dynflow/executors/sidekiq/serialization.rb +1 -0
  96. data/lib/dynflow/executors/sidekiq/worker_jobs.rb +1 -0
  97. data/lib/dynflow/executors.rb +1 -1
  98. data/lib/dynflow/extensions/msgpack.rb +5 -4
  99. data/lib/dynflow/extensions.rb +1 -0
  100. data/lib/dynflow/flows/abstract.rb +1 -1
  101. data/lib/dynflow/flows/abstract_composed.rb +1 -2
  102. data/lib/dynflow/flows/atom.rb +1 -2
  103. data/lib/dynflow/flows/concurrence.rb +1 -1
  104. data/lib/dynflow/flows/registry.rb +1 -0
  105. data/lib/dynflow/flows/sequence.rb +1 -1
  106. data/lib/dynflow/flows.rb +1 -2
  107. data/lib/dynflow/logger_adapters/abstract.rb +1 -1
  108. data/lib/dynflow/logger_adapters/delegator.rb +1 -1
  109. data/lib/dynflow/logger_adapters/formatters/abstract.rb +1 -0
  110. data/lib/dynflow/logger_adapters/formatters/exception.rb +1 -0
  111. data/lib/dynflow/logger_adapters/formatters.rb +1 -0
  112. data/lib/dynflow/logger_adapters/simple.rb +6 -5
  113. data/lib/dynflow/logger_adapters.rb +1 -0
  114. data/lib/dynflow/middleware/common/singleton.rb +1 -0
  115. data/lib/dynflow/middleware/common/transaction.rb +1 -0
  116. data/lib/dynflow/middleware/register.rb +1 -0
  117. data/lib/dynflow/middleware/resolver.rb +2 -3
  118. data/lib/dynflow/middleware/stack.rb +1 -0
  119. data/lib/dynflow/middleware/world.rb +1 -2
  120. data/lib/dynflow/middleware.rb +1 -0
  121. data/lib/dynflow/persistence.rb +4 -5
  122. data/lib/dynflow/persistence_adapters/abstract.rb +1 -1
  123. data/lib/dynflow/persistence_adapters/sequel.rb +14 -14
  124. data/lib/dynflow/persistence_adapters/sequel_migrations/001_initial.rb +2 -1
  125. data/lib/dynflow/persistence_adapters/sequel_migrations/002_incremental_progress.rb +1 -0
  126. data/lib/dynflow/persistence_adapters/sequel_migrations/003_parent_action.rb +1 -0
  127. data/lib/dynflow/persistence_adapters/sequel_migrations/004_coordinator_records.rb +1 -1
  128. data/lib/dynflow/persistence_adapters/sequel_migrations/005_envelopes.rb +1 -0
  129. data/lib/dynflow/persistence_adapters/sequel_migrations/006_fix_data_length.rb +1 -0
  130. data/lib/dynflow/persistence_adapters/sequel_migrations/007_future_execution.rb +1 -0
  131. data/lib/dynflow/persistence_adapters/sequel_migrations/008_rename_scheduled_plans_to_delayed_plans.rb +1 -0
  132. data/lib/dynflow/persistence_adapters/sequel_migrations/009_fix_mysql_data_length.rb +1 -1
  133. data/lib/dynflow/persistence_adapters/sequel_migrations/010_add_execution_plans_label.rb +1 -0
  134. data/lib/dynflow/persistence_adapters/sequel_migrations/011_placeholder.rb +1 -0
  135. data/lib/dynflow/persistence_adapters/sequel_migrations/012_add_delayed_plans_serialized_args.rb +1 -0
  136. data/lib/dynflow/persistence_adapters/sequel_migrations/013_add_action_columns.rb +1 -0
  137. data/lib/dynflow/persistence_adapters/sequel_migrations/014_add_step_columns.rb +1 -0
  138. data/lib/dynflow/persistence_adapters/sequel_migrations/015_add_execution_plan_columns.rb +1 -0
  139. data/lib/dynflow/persistence_adapters/sequel_migrations/016_add_step_queue.rb +1 -0
  140. data/lib/dynflow/persistence_adapters/sequel_migrations/017_add_delayed_plan_frozen.rb +1 -0
  141. data/lib/dynflow/persistence_adapters/sequel_migrations/018_add_uuid_column.rb +37 -30
  142. data/lib/dynflow/persistence_adapters/sequel_migrations/019_update_mysql_time_precision.rb +1 -0
  143. data/lib/dynflow/persistence_adapters/sequel_migrations/020_drop_duplicate_indices.rb +1 -0
  144. data/lib/dynflow/persistence_adapters/sequel_migrations/021_create_output_chunks.rb +4 -3
  145. data/lib/dynflow/persistence_adapters/sequel_migrations/023_sqlite_workarounds.rb +1 -0
  146. data/lib/dynflow/persistence_adapters.rb +1 -0
  147. data/lib/dynflow/rails/configuration.rb +5 -4
  148. data/lib/dynflow/rails/daemon.rb +1 -1
  149. data/lib/dynflow/rails.rb +3 -2
  150. data/lib/dynflow/round_robin.rb +2 -2
  151. data/lib/dynflow/semaphores/abstract.rb +1 -1
  152. data/lib/dynflow/semaphores/aggregating.rb +1 -2
  153. data/lib/dynflow/semaphores/dummy.rb +1 -1
  154. data/lib/dynflow/semaphores/stateful.rb +1 -1
  155. data/lib/dynflow/semaphores.rb +1 -0
  156. data/lib/dynflow/serializable.rb +1 -0
  157. data/lib/dynflow/serializer.rb +2 -2
  158. data/lib/dynflow/serializers/abstract.rb +1 -2
  159. data/lib/dynflow/serializers/noop.rb +1 -2
  160. data/lib/dynflow/serializers.rb +1 -2
  161. data/lib/dynflow/stateful.rb +1 -0
  162. data/lib/dynflow/telemetry.rb +11 -10
  163. data/lib/dynflow/telemetry_adapters/abstract.rb +1 -0
  164. data/lib/dynflow/telemetry_adapters/dummy.rb +1 -0
  165. data/lib/dynflow/telemetry_adapters/statsd.rb +2 -1
  166. data/lib/dynflow/testing/assertions.rb +7 -7
  167. data/lib/dynflow/testing/dummy_coordinator.rb +1 -0
  168. data/lib/dynflow/testing/dummy_execution_plan.rb +1 -0
  169. data/lib/dynflow/testing/dummy_executor.rb +1 -0
  170. data/lib/dynflow/testing/dummy_planned_action.rb +3 -1
  171. data/lib/dynflow/testing/dummy_step.rb +1 -0
  172. data/lib/dynflow/testing/dummy_world.rb +1 -0
  173. data/lib/dynflow/testing/factories.rb +42 -37
  174. data/lib/dynflow/testing/in_thread_executor.rb +1 -0
  175. data/lib/dynflow/testing/in_thread_world.rb +1 -0
  176. data/lib/dynflow/testing/managed_clock.rb +1 -1
  177. data/lib/dynflow/testing/mimic.rb +4 -4
  178. data/lib/dynflow/testing.rb +1 -0
  179. data/lib/dynflow/throttle_limiter.rb +1 -1
  180. data/lib/dynflow/transaction_adapters/abstract.rb +1 -0
  181. data/lib/dynflow/transaction_adapters/active_record.rb +1 -0
  182. data/lib/dynflow/transaction_adapters/none.rb +1 -0
  183. data/lib/dynflow/transaction_adapters.rb +1 -2
  184. data/lib/dynflow/utils/indifferent_hash.rb +7 -1
  185. data/lib/dynflow/utils/priority_queue.rb +1 -0
  186. data/lib/dynflow/utils.rb +1 -1
  187. data/lib/dynflow/version.rb +2 -1
  188. data/lib/dynflow/watchers/memory_consumption_watcher.rb +1 -1
  189. data/lib/dynflow/web/console.rb +1 -3
  190. data/lib/dynflow/web/console_helpers.rb +5 -4
  191. data/lib/dynflow/web/filtering_helpers.rb +1 -0
  192. data/lib/dynflow/web/world_helpers.rb +1 -0
  193. data/lib/dynflow/web.rb +3 -3
  194. data/lib/dynflow/web_console.rb +1 -0
  195. data/lib/dynflow/world/invalidation.rb +1 -0
  196. data/lib/dynflow/world.rb +19 -19
  197. data/lib/dynflow.rb +3 -6
  198. data/test/abnormal_states_recovery_test.rb +4 -8
  199. data/test/action_test.rb +10 -18
  200. data/test/activejob_adapter_test.rb +2 -2
  201. data/test/batch_sub_tasks_test.rb +1 -1
  202. data/test/clock_test.rb +2 -3
  203. data/test/concurrency_control_test.rb +6 -7
  204. data/test/coordinator_test.rb +1 -0
  205. data/test/daemon_test.rb +3 -2
  206. data/test/dead_letter_silencer_test.rb +2 -1
  207. data/test/dispatcher_test.rb +4 -5
  208. data/test/execution_plan_cleaner_test.rb +1 -0
  209. data/test/execution_plan_hooks_test.rb +1 -0
  210. data/test/execution_plan_test.rb +10 -32
  211. data/test/executor_test.rb +20 -37
  212. data/test/extensions_test.rb +1 -0
  213. data/test/flows_test.rb +2 -2
  214. data/test/future_execution_test.rb +2 -3
  215. data/test/memory_cosumption_watcher_test.rb +1 -0
  216. data/test/middleware_test.rb +4 -6
  217. data/test/persistence_test.rb +26 -26
  218. data/test/redis_locking_test.rb +1 -0
  219. data/test/rescue_test.rb +3 -11
  220. data/test/round_robin_test.rb +1 -0
  221. data/test/semaphores_test.rb +5 -7
  222. data/test/support/code_workflow_example.rb +11 -28
  223. data/test/support/dummy_example.rb +20 -19
  224. data/test/support/middleware_example.rb +2 -8
  225. data/test/support/rescue_example.rb +1 -14
  226. data/test/support/test_execution_log.rb +1 -2
  227. data/test/test_helper.rb +3 -7
  228. data/test/testing_test.rb +6 -8
  229. data/test/utils_test.rb +1 -0
  230. data/test/v2_sub_plans_test.rb +1 -0
  231. data/test/web_console_test.rb +4 -4
  232. data/test/world_test.rb +4 -3
  233. metadata +43 -43
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
- module Dynflow
3
2
 
3
+ module Dynflow
4
4
  # Input/output format validation logic calling
5
5
  # input_format/output_format with block acts as a setter for
6
6
  # specifying the format. Without a block it acts as a getter
7
7
  module Action::Format
8
-
9
8
  # we don't evaluate tbe block immediatelly, but postpone it till all the
10
9
  # action classes are loaded, because we can use them to reference output format
11
10
  def input_format(&block)
@@ -41,7 +40,5 @@ module Dynflow
41
40
  end
42
41
  end
43
42
  end
44
-
45
43
  end
46
44
  end
47
-
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  # for cases the serialized action was renamed and it's not available
4
5
  # in the code base anymore.
5
6
  class Action::Missing < Dynflow::Action
6
-
7
7
  def self.generate(action_name)
8
8
  Class.new(self).tap do |klass|
9
9
  klass.singleton_class.send(:define_method, :name) do
@@ -14,17 +14,17 @@ module Dynflow
14
14
 
15
15
  def plan(*args)
16
16
  raise StandardError,
17
- "The action class was not found and therefore plan phase failed, this can happen if the action was added/renamed but the executor was not restarted."
17
+ "The action class was not found and therefore plan phase failed, this can happen if the action was added/renamed but the executor was not restarted."
18
18
  end
19
19
 
20
20
  def run
21
21
  raise StandardError,
22
- "The action class was not found and therefore run phase failed, this can happen if the action was added/renamed but the executor was not restarted."
22
+ "The action class was not found and therefore run phase failed, this can happen if the action was added/renamed but the executor was not restarted."
23
23
  end
24
24
 
25
25
  def finalize
26
26
  raise StandardError,
27
- "The action class was not found and therefore finalize phase failed, this can happen if the action was added/renamed but the executor was not restarted."
27
+ "The action class was not found and therefore finalize phase failed, this can happen if the action was added/renamed but the executor was not restarted."
28
28
  end
29
29
  end
30
30
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'dynflow/action/timeouts'
3
4
 
4
5
  module Dynflow
5
6
  module Action::Polling
6
-
7
7
  def self.included(base)
8
8
  base.send :include, Action::Timeouts
9
9
  end
@@ -71,7 +71,7 @@ module Dynflow
71
71
 
72
72
  # Returns the time to wait between two polling intervals.
73
73
  def poll_interval
74
- interval_level = poll_attempts[:total]/attempts_before_next_interval
74
+ interval_level = poll_attempts[:total] / attempts_before_next_interval
75
75
  poll_intervals[interval_level] || poll_intervals.last
76
76
  end
77
77
 
@@ -116,6 +116,5 @@ module Dynflow
116
116
  raise error
117
117
  end
118
118
  end
119
-
120
119
  end
121
120
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
- module Dynflow
3
2
 
3
+ module Dynflow
4
4
  # Methods for specifying the progress of the action
5
5
  # the +*_progress+ methods should return number in 0..1.
6
6
  # The weight is there to increase/decrease the portion of this task
@@ -10,9 +10,7 @@ module Dynflow
10
10
  # The +*_progress+ is run only when the action is in running/suspend state. Otherwise
11
11
  # the progress is 1 for success/skipped actions and 0 for errorneous ones.
12
12
  module Action::Progress
13
-
14
13
  class Calculate < Middleware
15
-
16
14
  def run(*args)
17
15
  with_progress_calculation(*args) do
18
16
  [action.run_progress, action.run_progress_weight]
@@ -61,4 +59,3 @@ module Dynflow
61
59
  attr_accessor :calculated_progress
62
60
  end
63
61
  end
64
-
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Action::Rescue
4
-
5
5
  Strategy = Algebrick.type do
6
6
  variants Skip = atom, Pause = atom, Fail = atom
7
7
  end
@@ -65,4 +65,3 @@ module Dynflow
65
65
  end
66
66
  end
67
67
  end
68
-
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  class Action
4
5
  module Singleton
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  class Action::Suspended
4
5
  attr_reader :execution_plan_id, :step_id
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Action::Timeouts
4
5
  Timeout = Algebrick.atom
@@ -10,5 +11,5 @@ module Dynflow
10
11
  def schedule_timeout(seconds, optional: false)
11
12
  plan_event(Timeout, seconds, optional: optional)
12
13
  end
13
- end
14
+ end
14
15
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Action::WithBulkSubPlans
4
5
  include Dynflow::Action::Cancellable
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Action::WithPollingSubPlans
4
-
5
5
  REFRESH_INTERVAL = 10
6
6
  Poll = Algebrick.atom
7
7
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Action::WithSubPlans
4
5
  include Dynflow::Action::Cancellable
@@ -16,23 +17,23 @@ module Dynflow
16
17
 
17
18
  def run(event = nil)
18
19
  match event,
19
- (on nil do
20
- if output[:total_count]
21
- resume
22
- else
23
- initiate
24
- end
25
- end),
26
- (on SubPlanFinished do
27
- mark_as_done(event.execution_plan_id, event.success)
28
- try_to_finish or suspend
29
- end),
30
- (on Action::Cancellable::Cancel do
31
- cancel!
32
- end),
33
- (on Action::Cancellable::Abort do
34
- abort!
35
- end)
20
+ (on nil do
21
+ if output[:total_count]
22
+ resume
23
+ else
24
+ initiate
25
+ end
26
+ end),
27
+ (on SubPlanFinished do
28
+ mark_as_done(event.execution_plan_id, event.success)
29
+ try_to_finish or suspend
30
+ end),
31
+ (on Action::Cancellable::Cancel do
32
+ cancel!
33
+ end),
34
+ (on Action::Cancellable::Abort do
35
+ abort!
36
+ end)
36
37
  end
37
38
 
38
39
  def initiate
@@ -109,8 +110,8 @@ module Dynflow
109
110
  # Assume concurrency level 1 unless stated otherwise
110
111
  level = input[:concurrency_control].fetch(:level, {}).fetch(:free, 1)
111
112
  semaphore = ::Dynflow::Semaphores::Stateful.new(nil, level,
112
- :interval => time.to_f / (count * level),
113
- :time_span => time)
113
+ :interval => time.to_f / (count * level),
114
+ :time_span => time)
114
115
  input[:concurrency_control][:time] = semaphore.to_hash
115
116
  end
116
117
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  # rubocop:disable Metrics/ClassLength
4
5
  class Action < Serializable
5
-
6
6
  OutputReference = ExecutionPlan::OutputReference
7
7
 
8
8
  include Algebrick::TypeCheck
@@ -68,9 +68,9 @@ module Dynflow
68
68
  Skip = Algebrick.atom
69
69
  Phase = Algebrick.type do
70
70
  Executable = type do
71
- variants Plan = atom,
72
- Run = atom,
73
- Finalize = atom
71
+ variants Plan = atom,
72
+ Run = atom,
73
+ Finalize = atom
74
74
  end
75
75
  variants Executable, Present = atom
76
76
  end
@@ -78,9 +78,9 @@ module Dynflow
78
78
  module Executable
79
79
  def execute_method_name
80
80
  match self,
81
- (on Plan, :execute_plan),
82
- (on Run, :execute_run),
83
- (on Finalize, :execute_finalize)
81
+ (on Plan, :execute_plan),
82
+ (on Run, :execute_run),
83
+ (on Finalize, :execute_finalize)
84
84
  end
85
85
  end
86
86
 
@@ -105,9 +105,9 @@ module Dynflow
105
105
  end
106
106
 
107
107
  attr_reader :world, :phase, :execution_plan_id, :id, :input,
108
- :plan_step_id, :run_step_id, :finalize_step_id,
109
- :caller_execution_plan_id, :caller_action_id,
110
- :pending_output_chunks
108
+ :plan_step_id, :run_step_id, :finalize_step_id,
109
+ :caller_execution_plan_id, :caller_action_id,
110
+ :pending_output_chunks
111
111
 
112
112
  middleware.use Action::Progress::Calculate
113
113
 
@@ -124,12 +124,12 @@ module Dynflow
124
124
  @run_step_id = Type! attributes.fetch(:run_step_id), Integer, NilClass
125
125
  @finalize_step_id = Type! attributes.fetch(:finalize_step_id), Integer, NilClass
126
126
 
127
- @execution_plan = Type!(attributes.fetch(:execution_plan), ExecutionPlan) if phase? Present
127
+ @execution_plan = Type!(attributes.fetch(:execution_plan), ExecutionPlan) if phase? Present
128
128
 
129
129
  @caller_execution_plan_id = Type!(attributes.fetch(:caller_execution_plan_id, nil), String, NilClass)
130
130
  @caller_action_id = Type!(attributes.fetch(:caller_action_id, nil), Integer, NilClass)
131
131
 
132
- getter =-> key, required do
132
+ getter = ->key, required do
133
133
  required ? attributes.fetch(key) : attributes.fetch(key, {})
134
134
  end
135
135
 
@@ -236,10 +236,10 @@ module Dynflow
236
236
  # returned actions are in Present phase
237
237
  def planned_actions(filter = Action)
238
238
  phase! Present
239
- plan_step.
240
- planned_steps(execution_plan).
241
- map { |s| s.action(execution_plan) }.
242
- select { |a| a.is_a?(filter) }
239
+ plan_step
240
+ .planned_steps(execution_plan)
241
+ .map { |s| s.action(execution_plan) }
242
+ .select { |a| a.is_a?(filter) }
243
243
  end
244
244
 
245
245
  # @param [Class] filter_class return only actions which are kind of `filter_class`
@@ -248,8 +248,8 @@ module Dynflow
248
248
  def all_planned_actions(filter_class = Action)
249
249
  phase! Present
250
250
  mine = planned_actions
251
- (mine + mine.reduce([]) { |arr, action| arr + action.all_planned_actions }).
252
- select { |a| a.is_a?(filter_class) }
251
+ (mine + mine.reduce([]) { |arr, action| arr + action.all_planned_actions })
252
+ .select { |a| a.is_a?(filter_class) }
253
253
  end
254
254
 
255
255
  def run_step
@@ -268,18 +268,19 @@ module Dynflow
268
268
 
269
269
  def to_hash
270
270
  recursive_to_hash(
271
- { class: self.class.name,
272
- execution_plan_id: execution_plan_id,
273
- id: id,
274
- plan_step_id: plan_step_id,
275
- run_step_id: run_step_id,
276
- finalize_step_id: finalize_step_id,
277
- caller_execution_plan_id: caller_execution_plan_id,
278
- caller_action_id: caller_action_id,
279
- input: input },
280
- if phase? Run, Finalize, Present
281
- { output: output }
282
- end)
271
+ { class: self.class.name,
272
+ execution_plan_id: execution_plan_id,
273
+ id: id,
274
+ plan_step_id: plan_step_id,
275
+ run_step_id: run_step_id,
276
+ finalize_step_id: finalize_step_id,
277
+ caller_execution_plan_id: caller_execution_plan_id,
278
+ caller_action_id: caller_action_id,
279
+ input: input },
280
+ if phase? Run, Finalize, Present
281
+ { output: output }
282
+ end
283
+ )
283
284
  end
284
285
 
285
286
  def state
@@ -307,7 +308,7 @@ module Dynflow
307
308
  # @return [Array<Integer>] - ids of steps referenced from action
308
309
  def required_step_ids(input = self.input)
309
310
  results = []
310
- recursion =-> value do
311
+ recursion = ->value do
311
312
  case value
312
313
  when Hash
313
314
  value.values.each { |v| recursion.(v) }
@@ -364,9 +365,9 @@ module Dynflow
364
365
  def state=(state)
365
366
  phase! Executable
366
367
  @world.logger.debug format('%13s %s:%2d %9s >> %9s in phase %8s %s',
367
- 'Step', execution_plan_id, @step.id,
368
- self.state, state,
369
- phase.to_s_humanized, self.class)
368
+ 'Step', execution_plan_id, @step.id,
369
+ self.state, state,
370
+ phase.to_s_humanized, self.class)
370
371
  @step.state = state
371
372
  end
372
373
 
@@ -502,6 +503,7 @@ module Dynflow
502
503
  when :skipping
503
504
  self.state = :skipped
504
505
  when :suspended, :error
506
+ # Do nothing
505
507
  else
506
508
  raise "wrong state #{self.state}"
507
509
  end
@@ -551,11 +553,10 @@ module Dynflow
551
553
  end
552
554
 
553
555
  # TODO: This is getting out of hand, refactoring needed
554
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
555
556
  def execute_run(event)
556
557
  phase! Run
557
558
  @world.logger.debug format('%13s %s:%2d got event %s',
558
- 'Step', execution_plan_id, @step.id, event) if event
559
+ 'Step', execution_plan_id, @step.id, event) if event
559
560
 
560
561
  case
561
562
  when state == :running
@@ -599,7 +600,6 @@ module Dynflow
599
600
  raise "wrong state #{state} when event:#{event}"
600
601
  end
601
602
  end
602
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
603
603
 
604
604
  def execute_finalize
605
605
  phase! Finalize
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module ActiveJob
4
5
  module QueueAdapters
@@ -13,7 +14,7 @@ module Dynflow
13
14
  def enqueue_at(job, timestamp)
14
15
  job.provider_job_id = job.job_id
15
16
  ::Rails.application.dynflow.world
16
- .delay_with_options(id: job.provider_job_id,
17
+ .delay_with_options(id: job.provider_job_id,
17
18
  action_class: JobWrapper,
18
19
  delay_options: { :start_at => Time.at(timestamp) },
19
20
  args: [job.serialize])
data/lib/dynflow/actor.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
- module Dynflow
3
2
 
3
+ module Dynflow
4
4
  FULL_BACKTRACE = %w[1 y yes].include?((ENV['DYNFLOW_FULL_BACKTRACE'] || '').downcase)
5
5
  BACKTRACE_LIMIT = begin
6
6
  limit = ENV['DYNFLOW_BACKTRACE_LIMIT'].to_i
@@ -94,7 +94,7 @@ module Dynflow
94
94
  # takes an array of backtrace lines and replaces each chunk
95
95
  def filter_backtrace(backtrace)
96
96
  trace = backtrace.map { |line| filter_line(line) }
97
- .chunk_while { |l1, l2| l1 == l2}
97
+ .chunk_while { |l1, l2| l1 == l2 }
98
98
  .map(&:first)
99
99
  if BACKTRACE_LIMIT
100
100
  count = trace.count
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Actors
4
5
  class ExecutionPlanCleaner
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Actors
4
5
  require 'dynflow/actors/execution_plan_cleaner'
data/lib/dynflow/clock.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  class Clock < Actor
4
-
5
5
  include Algebrick::Types
6
6
 
7
7
  Timer = Algebrick.type do
@@ -13,7 +13,7 @@ module Dynflow
13
13
 
14
14
  module Timer
15
15
  def self.[](*fields)
16
- super(*fields).tap { |v| Match! v.who, -> who { who.respond_to? v.where } }
16
+ super(*fields).tap { |v| Match! v.who, ->who { who.respond_to? v.where } }
17
17
  end
18
18
 
19
19
  include Comparable
@@ -116,7 +116,7 @@ module Dynflow
116
116
 
117
117
  def ping(who, time, with_what = nil, where = :<<, optional: false)
118
118
  Type! time, Time, Numeric
119
- time = current_time + time if time.is_a? Numeric
119
+ time = current_time + time if time.is_a? Numeric
120
120
  if who.is_a?(Action::Suspended)
121
121
  who.plan_event(with_what, time, optional: optional)
122
122
  else
@@ -125,5 +125,4 @@ module Dynflow
125
125
  end
126
126
  end
127
127
  end
128
-
129
128
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'socket'
3
4
 
4
5
  module Dynflow
@@ -6,11 +7,11 @@ module Dynflow
6
7
  include Algebrick::TypeCheck
7
8
 
8
9
  def self.config_attr(name, *types, &default)
9
- self.send(:define_method, "validate_#{ name }!") do |value|
10
+ self.send(:define_method, "validate_#{name}!") do |value|
10
11
  Type! value, *types unless types.empty?
11
12
  end
12
13
  self.send(:define_method, name) do
13
- var_name = "@#{ name }"
14
+ var_name = "@#{name}"
14
15
  if instance_variable_defined?(var_name)
15
16
  return instance_variable_get(var_name)
16
17
  else
@@ -41,7 +42,7 @@ module Dynflow
41
42
  return @cache[name] if @cache.key?(name)
42
43
  value = @config.send(name)
43
44
  value = value.call(@world, self) if value.is_a? Proc
44
- validation_method = "validate_#{ name }!"
45
+ validation_method = "validate_#{name}!"
45
46
  @config.send(validation_method, value) if @config.respond_to?(validation_method)
46
47
  @cache[name] = value
47
48
  end
@@ -51,7 +52,7 @@ module Dynflow
51
52
  attr_reader :queues
52
53
 
53
54
  def initialize
54
- @queues = {:default => {}}
55
+ @queues = { :default => {} }
55
56
  end
56
57
 
57
58
  # Add a new queue to the configuration
@@ -204,7 +205,7 @@ module Dynflow
204
205
  "it's #{ar_pool_size} but there is #{config_for_world.pool_size} " +
205
206
  'threads in Dynflow pool.'
206
207
  end
207
- rescue ActiveRecord::ConnectionNotEstablished # rubocop:disable Lint/HandleExceptions
208
+ rescue ActiveRecord::ConnectionNotEstablished
208
209
  # If in tests or in an environment where ActiveRecord doesn't have a
209
210
  # real DB connection, we want to skip AR configuration altogether
210
211
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Connectors
4
5
  class Abstract
@@ -35,16 +36,16 @@ module Dynflow
35
36
  Type! envelope, Dispatcher::Envelope
36
37
  Telemetry.with_instance { |t| t.increment_counter(:dynflow_connector_envelopes, 1, :world => world.id, :direction => 'incoming') }
37
38
  match(envelope.message,
38
- (on Dispatcher::Ping do
39
- response_envelope = envelope.build_response_envelope(Dispatcher::Pong, world)
40
- send(response_envelope)
41
- end),
42
- (on Dispatcher::Request do
43
- world.executor_dispatcher.tell([:handle_request, envelope])
44
- end),
45
- (on Dispatcher::Response do
46
- world.client_dispatcher.tell([:dispatch_response, envelope])
47
- end))
39
+ (on Dispatcher::Ping do
40
+ response_envelope = envelope.build_response_envelope(Dispatcher::Pong, world)
41
+ send(response_envelope)
42
+ end),
43
+ (on Dispatcher::Request do
44
+ world.executor_dispatcher.tell([:handle_request, envelope])
45
+ end),
46
+ (on Dispatcher::Response do
47
+ world.client_dispatcher.tell([:dispatch_response, envelope])
48
+ end))
48
49
  end
49
50
  end
50
51
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Connectors
4
5
  class Database < Abstract
5
-
6
6
  class PostgresListerner
7
7
  def initialize(core, world_id, db)
8
8
  @core = core
@@ -22,7 +22,7 @@ module Dynflow
22
22
  def start
23
23
  @started.set true
24
24
  @thread = Thread.new do
25
- @db.listen("world:#{ @world_id }", :loop => true) do
25
+ @db.listen("world:#{@world_id}", :loop => true) do
26
26
  if started?
27
27
  @core << :check_inbox
28
28
  else
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Connectors
4
5
  class Direct < Abstract
5
-
6
6
  class Core < Actor
7
-
8
7
  def initialize(connector)
9
8
  @connector = connector
10
9
  @worlds = {}
@@ -30,7 +29,7 @@ module Dynflow
30
29
  if world = find_receiver(envelope)
31
30
  @connector.receive(world, envelope)
32
31
  else
33
- log(Logger::ERROR, "Receiver for envelope #{ envelope } not found")
32
+ log(Logger::ERROR, "Receiver for envelope #{envelope} not found")
34
33
  end
35
34
  end
36
35
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module Connectors
4
5
  require 'dynflow/connectors/abstract'
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'dynflow/coordinator_adapters'
3
4
 
4
5
  module Dynflow
5
6
  class Coordinator
6
-
7
7
  include Algebrick::TypeCheck
8
8
 
9
9
  class DuplicateRecordError < Dynflow::Error
@@ -41,7 +41,7 @@ module Dynflow
41
41
  end
42
42
 
43
43
  def initialize(*args)
44
- @data ||= {}
44
+ @data = {}
45
45
  @data = Utils.indifferent_hash(@data.merge(class: self.class.name))
46
46
  end
47
47
 
@@ -145,10 +145,6 @@ module Dynflow
145
145
  raise "Can't acquire the lock after deserialization" if @from_hash
146
146
  Type! owner_id, String
147
147
  end
148
-
149
- def to_s
150
- "#{self.class.name}: #{id} by #{owner_id}"
151
- end
152
148
  end
153
149
 
154
150
  class LockByWorld < Lock
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module CoordinatorAdapters
4
5
  class Abstract
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module CoordinatorAdapters
4
5
  class Sequel < Abstract
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  module CoordinatorAdapters
4
-
5
5
  require 'dynflow/coordinator_adapters/abstract'
6
6
  require 'dynflow/coordinator_adapters/sequel'
7
-
8
7
  end
9
8
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Dynflow
3
4
  class DeadLetterSilencer < Concurrent::Actor::DefaultDeadLetterHandler
4
5
  def initialize(matchers)