dynflow 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +3 -4
  4. data/Dockerfile +9 -0
  5. data/Gemfile +6 -0
  6. data/Rakefile +1 -0
  7. data/doc/pages/Gemfile +1 -0
  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 +1 -0
  12. data/doc/pages/plugins/plantuml.rb +1 -0
  13. data/doc/pages/plugins/play.rb +1 -0
  14. data/doc/pages/plugins/tags.rb +1 -0
  15. data/doc/pages/plugins/toc.rb +1 -0
  16. data/docker-compose.yml +41 -0
  17. data/dynflow.gemspec +1 -0
  18. data/examples/clock_benchmark.rb +1 -0
  19. data/examples/example_helper.rb +19 -2
  20. data/examples/future_execution.rb +2 -1
  21. data/examples/memory_limit_watcher.rb +1 -0
  22. data/examples/orchestrate.rb +4 -5
  23. data/examples/orchestrate_evented.rb +3 -2
  24. data/examples/remote_executor.rb +68 -0
  25. data/examples/singletons.rb +4 -3
  26. data/examples/sub_plan_concurrency_control.rb +2 -1
  27. data/examples/sub_plans.rb +3 -2
  28. data/examples/termination.rb +1 -0
  29. data/lib/dynflow.rb +20 -0
  30. data/lib/dynflow/action.rb +28 -3
  31. data/lib/dynflow/action/cancellable.rb +1 -0
  32. data/lib/dynflow/action/format.rb +1 -0
  33. data/lib/dynflow/action/missing.rb +1 -0
  34. data/lib/dynflow/action/polling.rb +3 -1
  35. data/lib/dynflow/action/progress.rb +1 -0
  36. data/lib/dynflow/action/rescue.rb +1 -0
  37. data/lib/dynflow/action/singleton.rb +1 -0
  38. data/lib/dynflow/action/suspended.rb +9 -2
  39. data/lib/dynflow/action/timeouts.rb +2 -1
  40. data/lib/dynflow/action/with_bulk_sub_plans.rb +2 -1
  41. data/lib/dynflow/action/with_polling_sub_plans.rb +7 -5
  42. data/lib/dynflow/action/with_sub_plans.rb +1 -0
  43. data/lib/dynflow/active_job/queue_adapter.rb +1 -0
  44. data/lib/dynflow/actor.rb +13 -5
  45. data/lib/dynflow/actors.rb +1 -0
  46. data/lib/dynflow/actors/execution_plan_cleaner.rb +1 -0
  47. data/lib/dynflow/clock.rb +27 -47
  48. data/lib/dynflow/config.rb +11 -2
  49. data/lib/dynflow/connectors.rb +1 -0
  50. data/lib/dynflow/connectors/abstract.rb +1 -0
  51. data/lib/dynflow/connectors/database.rb +1 -0
  52. data/lib/dynflow/connectors/direct.rb +1 -0
  53. data/lib/dynflow/coordinator.rb +1 -0
  54. data/lib/dynflow/coordinator_adapters.rb +1 -0
  55. data/lib/dynflow/coordinator_adapters/abstract.rb +1 -0
  56. data/lib/dynflow/coordinator_adapters/sequel.rb +1 -0
  57. data/lib/dynflow/dead_letter_silencer.rb +2 -0
  58. data/lib/dynflow/debug/telemetry/persistence.rb +1 -0
  59. data/lib/dynflow/delayed_executors.rb +1 -0
  60. data/lib/dynflow/delayed_executors/abstract.rb +1 -0
  61. data/lib/dynflow/delayed_executors/abstract_core.rb +1 -0
  62. data/lib/dynflow/delayed_executors/polling.rb +1 -0
  63. data/lib/dynflow/delayed_plan.rb +1 -0
  64. data/lib/dynflow/director.rb +80 -15
  65. data/lib/dynflow/director/execution_plan_manager.rb +17 -3
  66. data/lib/dynflow/director/flow_manager.rb +1 -0
  67. data/lib/dynflow/director/{work_queue.rb → queue_hash.rb} +9 -8
  68. data/lib/dynflow/director/running_steps_manager.rb +55 -18
  69. data/lib/dynflow/director/sequence_cursor.rb +1 -0
  70. data/lib/dynflow/director/sequential_manager.rb +12 -2
  71. data/lib/dynflow/dispatcher.rb +4 -2
  72. data/lib/dynflow/dispatcher/abstract.rb +1 -0
  73. data/lib/dynflow/dispatcher/client_dispatcher.rb +6 -4
  74. data/lib/dynflow/dispatcher/executor_dispatcher.rb +13 -1
  75. data/lib/dynflow/errors.rb +1 -0
  76. data/lib/dynflow/execution_history.rb +1 -0
  77. data/lib/dynflow/execution_plan.rb +3 -2
  78. data/lib/dynflow/execution_plan/dependency_graph.rb +1 -0
  79. data/lib/dynflow/execution_plan/hooks.rb +1 -0
  80. data/lib/dynflow/execution_plan/output_reference.rb +2 -1
  81. data/lib/dynflow/execution_plan/steps.rb +1 -0
  82. data/lib/dynflow/execution_plan/steps/abstract.rb +10 -5
  83. data/lib/dynflow/execution_plan/steps/abstract_flow_step.rb +2 -0
  84. data/lib/dynflow/execution_plan/steps/error.rb +1 -0
  85. data/lib/dynflow/execution_plan/steps/finalize_step.rb +1 -0
  86. data/lib/dynflow/execution_plan/steps/plan_step.rb +1 -0
  87. data/lib/dynflow/execution_plan/steps/run_step.rb +1 -0
  88. data/lib/dynflow/executors.rb +1 -1
  89. data/lib/dynflow/executors/abstract/core.rb +132 -0
  90. data/lib/dynflow/executors/parallel.rb +24 -11
  91. data/lib/dynflow/executors/parallel/core.rb +10 -91
  92. data/lib/dynflow/executors/parallel/pool.rb +4 -2
  93. data/lib/dynflow/executors/parallel/worker.rb +2 -1
  94. data/lib/dynflow/executors/sidekiq/core.rb +121 -0
  95. data/lib/dynflow/executors/sidekiq/internal_job_base.rb +24 -0
  96. data/lib/dynflow/executors/sidekiq/orchestrator_jobs.rb +60 -0
  97. data/lib/dynflow/executors/sidekiq/redis_locking.rb +69 -0
  98. data/lib/dynflow/executors/sidekiq/serialization.rb +33 -0
  99. data/lib/dynflow/executors/sidekiq/worker_jobs.rb +42 -0
  100. data/lib/dynflow/flows.rb +1 -0
  101. data/lib/dynflow/flows/abstract.rb +1 -0
  102. data/lib/dynflow/flows/abstract_composed.rb +1 -0
  103. data/lib/dynflow/flows/atom.rb +1 -0
  104. data/lib/dynflow/flows/concurrence.rb +1 -0
  105. data/lib/dynflow/flows/sequence.rb +1 -0
  106. data/lib/dynflow/logger_adapters.rb +1 -0
  107. data/lib/dynflow/logger_adapters/abstract.rb +1 -0
  108. data/lib/dynflow/logger_adapters/delegator.rb +1 -0
  109. data/lib/dynflow/logger_adapters/formatters.rb +1 -0
  110. data/lib/dynflow/logger_adapters/formatters/abstract.rb +1 -0
  111. data/lib/dynflow/logger_adapters/formatters/exception.rb +1 -0
  112. data/lib/dynflow/logger_adapters/simple.rb +1 -0
  113. data/lib/dynflow/middleware.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 +1 -0
  118. data/lib/dynflow/middleware/stack.rb +1 -0
  119. data/lib/dynflow/middleware/world.rb +1 -0
  120. data/lib/dynflow/persistence.rb +3 -2
  121. data/lib/dynflow/persistence_adapters.rb +1 -0
  122. data/lib/dynflow/persistence_adapters/abstract.rb +1 -0
  123. data/lib/dynflow/persistence_adapters/sequel.rb +10 -7
  124. data/lib/dynflow/persistence_adapters/sequel_migrations/001_initial.rb +1 -0
  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 -0
  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 -0
  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 +1 -0
  142. data/lib/dynflow/persistence_adapters/sequel_migrations/019_update_mysql_time_precision.rb +48 -0
  143. data/lib/dynflow/rails.rb +1 -0
  144. data/lib/dynflow/rails/configuration.rb +6 -3
  145. data/lib/dynflow/rails/daemon.rb +1 -0
  146. data/lib/dynflow/round_robin.rb +1 -0
  147. data/lib/dynflow/semaphores.rb +1 -0
  148. data/lib/dynflow/semaphores/abstract.rb +1 -0
  149. data/lib/dynflow/semaphores/aggregating.rb +1 -0
  150. data/lib/dynflow/semaphores/dummy.rb +1 -0
  151. data/lib/dynflow/semaphores/stateful.rb +1 -0
  152. data/lib/dynflow/serializable.rb +13 -4
  153. data/lib/dynflow/serializer.rb +24 -0
  154. data/lib/dynflow/serializers.rb +1 -0
  155. data/lib/dynflow/serializers/abstract.rb +1 -0
  156. data/lib/dynflow/serializers/noop.rb +1 -0
  157. data/lib/dynflow/stateful.rb +1 -0
  158. data/lib/dynflow/telemetry.rb +1 -0
  159. data/lib/dynflow/telemetry_adapters/abstract.rb +1 -0
  160. data/lib/dynflow/telemetry_adapters/dummy.rb +1 -0
  161. data/lib/dynflow/telemetry_adapters/statsd.rb +1 -0
  162. data/lib/dynflow/testing.rb +1 -0
  163. data/lib/dynflow/testing/assertions.rb +6 -5
  164. data/lib/dynflow/testing/dummy_execution_plan.rb +1 -0
  165. data/lib/dynflow/testing/dummy_executor.rb +19 -2
  166. data/lib/dynflow/testing/dummy_planned_action.rb +1 -0
  167. data/lib/dynflow/testing/dummy_step.rb +3 -1
  168. data/lib/dynflow/testing/dummy_world.rb +9 -0
  169. data/lib/dynflow/testing/factories.rb +6 -1
  170. data/lib/dynflow/testing/in_thread_executor.rb +22 -3
  171. data/lib/dynflow/testing/in_thread_world.rb +9 -0
  172. data/lib/dynflow/testing/managed_clock.rb +1 -0
  173. data/lib/dynflow/testing/mimic.rb +1 -0
  174. data/lib/dynflow/throttle_limiter.rb +1 -0
  175. data/lib/dynflow/transaction_adapters.rb +1 -0
  176. data/lib/dynflow/transaction_adapters/abstract.rb +1 -0
  177. data/lib/dynflow/transaction_adapters/active_record.rb +1 -0
  178. data/lib/dynflow/transaction_adapters/none.rb +1 -0
  179. data/lib/dynflow/utils.rb +1 -0
  180. data/lib/dynflow/utils/indifferent_hash.rb +1 -0
  181. data/lib/dynflow/utils/priority_queue.rb +1 -0
  182. data/lib/dynflow/version.rb +2 -1
  183. data/lib/dynflow/watchers/memory_consumption_watcher.rb +1 -0
  184. data/lib/dynflow/web.rb +1 -0
  185. data/lib/dynflow/web/console.rb +1 -0
  186. data/lib/dynflow/web/console_helpers.rb +1 -0
  187. data/lib/dynflow/web/filtering_helpers.rb +1 -0
  188. data/lib/dynflow/web/world_helpers.rb +1 -0
  189. data/lib/dynflow/web_console.rb +1 -0
  190. data/lib/dynflow/world.rb +11 -1
  191. data/lib/dynflow/world/invalidation.rb +7 -1
  192. data/test/abnormal_states_recovery_test.rb +41 -40
  193. data/test/action_test.rb +160 -110
  194. data/test/activejob_adapter_test.rb +1 -0
  195. data/test/batch_sub_tasks_test.rb +12 -11
  196. data/test/clock_test.rb +2 -1
  197. data/test/concurrency_control_test.rb +20 -19
  198. data/test/coordinator_test.rb +20 -21
  199. data/test/daemon_test.rb +2 -1
  200. data/test/dead_letter_silencer_test.rb +9 -7
  201. data/test/dispatcher_test.rb +2 -1
  202. data/test/execution_plan_cleaner_test.rb +13 -12
  203. data/test/execution_plan_hooks_test.rb +3 -2
  204. data/test/execution_plan_test.rb +33 -32
  205. data/test/executor_test.rb +533 -489
  206. data/test/future_execution_test.rb +45 -44
  207. data/test/memory_cosumption_watcher_test.rb +5 -4
  208. data/test/middleware_test.rb +55 -54
  209. data/test/persistence_test.rb +56 -53
  210. data/test/rescue_test.rb +36 -35
  211. data/test/round_robin_test.rb +13 -12
  212. data/test/semaphores_test.rb +31 -30
  213. data/test/support/code_workflow_example.rb +1 -0
  214. data/test/support/dummy_example.rb +14 -1
  215. data/test/support/middleware_example.rb +2 -1
  216. data/test/support/rails/config/environment.rb +1 -0
  217. data/test/support/rescue_example.rb +1 -0
  218. data/test/support/test_execution_log.rb +1 -0
  219. data/test/test_helper.rb +18 -17
  220. data/test/testing_test.rb +45 -44
  221. data/test/utils_test.rb +18 -17
  222. data/test/web_console_test.rb +1 -0
  223. data/test/world_test.rb +7 -6
  224. metadata +13 -4
  225. data/lib/dynflow/executors/abstract.rb +0 -40
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef3a326c234f3687c367017a5a64befabfb11075944eed324b5babc8b7adec95
4
- data.tar.gz: 615bad06c6a5223613b974e1d7d3ae5c6c9e87d53aaf4d038678ec64168cc498
3
+ metadata.gz: bb02c56f3fda535ffdc29d64826470d8bb81cf4714ac98e8316dbcb0f045ce00
4
+ data.tar.gz: 7f0553a6e9bda6a5ae8d604f5f6238b52e5b6ad45462a3199c993a30e530f499
5
5
  SHA512:
6
- metadata.gz: 1307e77ffb5874d7d7ee4bfc010d85c69de267420e6273790971a54921144114afd9d6c02885213feb8b67fca0de28a8835b149f628330ed7976139842764568
7
- data.tar.gz: ceda3668f29ff0aac123d9c767c327dda98822dfdf4d8aca9d6e03df7f28bb7c41a60300f4ee25c4348e2789c1d34cf651d692d196dfe2a0fde4be6c888825be
6
+ metadata.gz: 9d3bdd0745db1d85f1be3c1c4510a54d167d175b48d33e8a89fbeaf7fa7c115f419a8756b89af4f2f4d57bad94a2bb1c999f8d6d9d530b850b7dab5a1638b042
7
+ data.tar.gz: 022b09ce7daa8ed8a2a856d5cc16f93c9375978d9fc571350dbaebe2c7c6381dadcc8c3510e6227c08872e85657ad8e27ebfbb3c70f5e0f1df61b946dfa3f4c1
@@ -1,7 +1,7 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
3
  AllCops:
4
- TargetRubyVersion: 2.2
4
+ TargetRubyVersion: 2.3
5
5
 
6
6
  # Cop supports --auto-correct.
7
7
  # Configuration parameters: AllowForAlignment, ForceEqualSignAlignment.
@@ -1,9 +1,6 @@
1
- sudo: false
2
- language:
3
- - ruby
1
+ language: ruby
4
2
 
5
3
  services:
6
- - mysql
7
4
  - postgresql
8
5
 
9
6
  rvm:
@@ -19,6 +16,8 @@ matrix:
19
16
  include:
20
17
  - rvm: "2.4.0"
21
18
  env: "DB=mysql DB_CONN_STRING=mysql2://root@localhost/travis_ci_test"
19
+ services:
20
+ - mysql
22
21
  - rvm: "2.4.0"
23
22
  env: "DB=sqlite3 DB_CONN_STRING=sqlite:/"
24
23
  - rvm: "2.4.0"
@@ -0,0 +1,9 @@
1
+ FROM fedora:30
2
+ RUN dnf install -y curl git gcc gcc-c++ make openssl bzip2 findutils openssl-devel readline-devel \
3
+ zlib-devel sqlite-devel ruby ruby-devel rubygem-bundler redhat-rpm-config libpqxx-devel
4
+
5
+ ADD Gemfile /data/
6
+ ADD dynflow.gemspec /data/
7
+ ADD lib/dynflow/version.rb /data/lib/dynflow/version.rb
8
+ WORKDIR /data
9
+ RUN bundle install --without mysql
data/Gemfile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  source 'https://rubygems.org'
2
3
 
3
4
  gemspec
@@ -11,6 +12,11 @@ group :pry do
11
12
  gem 'pry-byebug'
12
13
  end
13
14
 
15
+ group :sidekiq do
16
+ gem 'sidekiq'
17
+ gem 'gitlab-sidekiq-fetcher', :require => 'sidekiq-reliable-fetch'
18
+ end
19
+
14
20
  group :postgresql do
15
21
  gem "pg"
16
22
  end
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rake/testtask'
2
3
  require 'fileutils'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  source 'https://rubygems.org'
2
3
 
3
4
  gem 'rake'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rubygems'
2
3
  require 'rake'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require_relative 'div_tag'
2
3
 
3
4
  module Jekyll
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Jekyll
2
3
  class DivTag < Liquid::Block
3
4
  def render(context)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # taken from https://raw.githubusercontent.com/kui/octopress-graphviz/master/graphviz_block.rb
2
3
 
3
4
  require 'open3'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # Title: PlantUML Code Blocks for Jekyll
2
3
  # Author: YJ Park (yjpark@gmail.com)
3
4
  # https://github.com/yjpark/jekyll-plantuml
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'pp'
2
3
  require 'pry'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'nuggets/range/quantile'
2
3
  require 'erb'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Jekyll
2
3
  module FancyToCFilter
3
4
  def fancytoc(input)
@@ -0,0 +1,41 @@
1
+ version: '3'
2
+ services:
3
+ postgres:
4
+ image: postgres:11-alpine
5
+ expose:
6
+ - 5432
7
+ environment:
8
+ - POSTGRES_PASSWORD=postgres
9
+ - POSTGRES_USER=postgres
10
+ - POSTGRES_DB=dynflow
11
+ redis:
12
+ image: redis:5.0.5-alpine
13
+ expose:
14
+ - 6379
15
+ client: &common
16
+ build: .
17
+ depends_on:
18
+ - postgres
19
+ - redis
20
+ environment:
21
+ - REDIS_URL=redis://redis:6379/0
22
+ - REDIS_PROVIDER=REDIS_URL
23
+ - DB_CONN_STRING=postgresql://postgres:postgres@postgres:5432/dynflow
24
+ volumes:
25
+ - ./:/data
26
+ command: |
27
+ ruby ./examples/remote_executor.rb client
28
+ observer:
29
+ <<: *common
30
+ command: |
31
+ ruby ./examples/remote_executor.rb observer
32
+ ports:
33
+ - 4567:4567
34
+ orchestrator:
35
+ <<: *common
36
+ command: |
37
+ sidekiq -r ./examples/remote_executor.rb -q dynflow_orchestrator -c 1
38
+ worker:
39
+ <<: *common
40
+ command: |
41
+ sidekiq -r ./examples/remote_executor.rb -q default
@@ -1,4 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
2
3
  $:.push File.expand_path("../lib", __FILE__)
3
4
  require "dynflow/version"
4
5
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'dynflow'
2
3
  require 'benchmark'
3
4
 
@@ -1,8 +1,13 @@
1
+ # frozen_string_literal: true
1
2
  $:.unshift(File.expand_path('../../lib', __FILE__))
2
3
 
3
4
  require 'dynflow'
4
5
 
5
6
  class ExampleHelper
7
+ CONSOLE_URL='http://localhost:4567'
8
+ DYNFLOW_URL="#{CONSOLE_URL}/dynflow"
9
+ SIDEKIQ_URL="#{CONSOLE_URL}/sidekiq"
10
+
6
11
  class << self
7
12
  def world
8
13
  @world ||= create_world
@@ -18,6 +23,7 @@ class ExampleHelper
18
23
  config.logger_adapter = logger_adapter
19
24
  config.auto_rescue = false
20
25
  config.telemetry_adapter = telemetry_adapter
26
+ config.queues.add(:slow, :pool_size => 3)
21
27
  yield config if block_given?
22
28
  Dynflow::World.new(config).tap do |world|
23
29
  puts "World #{world.id} started..."
@@ -41,7 +47,7 @@ class ExampleHelper
41
47
  end
42
48
 
43
49
  def logger_adapter
44
- Dynflow::LoggerAdapters::Simple.new $stderr, 4
50
+ Dynflow::LoggerAdapters::Simple.new $stderr, Logger::FATAL
45
51
  end
46
52
 
47
53
  def run_web_console(world = ExampleHelper.world)
@@ -49,7 +55,18 @@ class ExampleHelper
49
55
  dynflow_console = Dynflow::Web.setup do
50
56
  set :world, world
51
57
  end
52
- Rack::Server.new(:app => dynflow_console, :Port => 4567).start
58
+ apps = { '/dynflow' => dynflow_console }
59
+ puts "Starting Dynflow console at #{DYNFLOW_URL}"
60
+ begin
61
+ require 'sidekiq/web'
62
+ apps['/sidekiq'] = Sidekiq::Web
63
+ puts "Starting Sidekiq console at #{SIDEKIQ_URL}"
64
+ rescue LoadError
65
+ puts 'Sidekiq not around, not mounting the console'
66
+ end
67
+
68
+ app = Rack::URLMap.new(apps)
69
+ Rack::Server.new(:app => app, :Host => '0.0.0.0', :Port => URI.parse(CONSOLE_URL).port).start
53
70
  end
54
71
 
55
72
  # for simulation of the execution failing for the first time
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require_relative 'example_helper'
4
5
 
@@ -64,7 +65,7 @@ if $0 == __FILE__
64
65
  | #{near_future_plan.id} is delayed to execute at #{near_future} and should run successfully.
65
66
  | #{future_plan.id} is delayed to execute at #{future} and should run successfully.
66
67
  |
67
- | Visit http://localhost:4567 to see their status.
68
+ | Visit #{ExampleHelper::DYNFLOW_URL} to see their status.
68
69
  |
69
70
  MSG
70
71
 
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require_relative 'example_helper'
4
5
 
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  example_description = <<DESC
4
5
  Orchestrate Example
@@ -15,7 +16,7 @@ example_description = <<DESC
15
16
  It also simulates a failure and demonstrates the Dynflow ability to rescue
16
17
  from the error and consinue with the run.
17
18
 
18
- Once the Sinatra web console starts, you can navigate to http://localhost:4567
19
+ Once the Sinatra web console starts, you can navigate to #{ExampleHelper::DYNFLOW_URL}
19
20
  to see what's happening in the Dynflow world.
20
21
 
21
22
  DESC
@@ -135,7 +136,7 @@ module Orchestrate
135
136
  puts <<-MSG.gsub(/^.*\|/, '')
136
137
 
137
138
  | Execution plan #{execution_plan_id} is failing
138
- | You can resume it at http://localhost:4567/#{execution_plan_id}
139
+ | You can resume it at #{ExampleHelper::DYNFLOW_URL}/#{execution_plan_id}
139
140
 
140
141
  MSG
141
142
  raise "temporary unavailabe"
@@ -148,9 +149,7 @@ module Orchestrate
148
149
  end
149
150
 
150
151
  if $0 == __FILE__
151
- world = ExampleHelper.create_world do |config|
152
- config.queues.add(:slow, :pool_size => 3)
153
- end
152
+ world = ExampleHelper.create_world
154
153
  ExampleHelper.set_world(world)
155
154
  ExampleHelper.world.action_logger.level = Logger::INFO
156
155
  ExampleHelper.something_should_fail!
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require_relative 'example_helper'
4
5
 
@@ -17,7 +18,7 @@ example_description = <<DESC
17
18
  send external events to the action while it's suspended. One use case is being
18
19
  able to cancel the action while it's running.
19
20
 
20
- Once the Sinatra web console starts, you can navigate to http://localhost:4567
21
+ Once the Sinatra web console starts, you can navigate to #{ExampleHelper::DYNFLOW_URL}
21
22
  to see what's happening in the Dynflow world.
22
23
 
23
24
  DESC
@@ -154,7 +155,7 @@ module OrchestrateEvented
154
155
 
155
156
  | Execution plan #{execution_plan_id} got stuck
156
157
  | You can cancel the stucked step at
157
- | http://localhost:4567/#{execution_plan_id}
158
+ | #{ExampleHelper::DYNFLOW_URL}/#{execution_plan_id}
158
159
 
159
160
  MSG
160
161
  # we suspend the action but don't plan the wakeup event,
@@ -1,5 +1,31 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- coding: utf-8 -*-
3
+ # frozen_string_literal: true
4
+
5
+ # To run the observer:
6
+ #
7
+ # bundle exec ruby ./examples/remote_executor.rb observer
8
+ #
9
+ # To run the server:
10
+ #
11
+ # bundle exec ruby ./examples/remote_executor.rb server
12
+ #
13
+ # To run the client:
14
+ #
15
+ # bundle exec ruby ./examples/remote_executor.rb client
16
+ #
17
+ # Sidekiq
18
+ # =======
19
+ #
20
+ # In case of using Sidekiq as async job backend, use this instead of the server command
21
+ #
22
+ # To run the orchestrator:
23
+ #
24
+ # bundle exec sidekiq -r ./examples/remote_executor.rb -q dynflow_orchestrator
25
+ #
26
+ # To run the worker:
27
+ #
28
+ # bundle exec sidekiq -r ./examples/remote_executor.rb -q default
3
29
 
4
30
  require_relative 'example_helper'
5
31
  require_relative 'orchestrate_evented'
@@ -37,6 +63,34 @@ class RemoteExecutorExample
37
63
  run(world)
38
64
  end
39
65
 
66
+ def initialize_sidekiq_orchestrator
67
+ ExampleHelper.create_world do |config|
68
+ config.persistence_adapter = persistence_adapter
69
+ config.connector = connector
70
+ config.executor = ::Dynflow::Executors::Sidekiq::Core
71
+ config.auto_validity_check = false
72
+ end
73
+ end
74
+
75
+ def initialize_sidekiq_worker
76
+ Sidekiq.configure_server do |config|
77
+ require 'sidekiq-reliable-fetch'
78
+ # Use semi-reliable fetch
79
+ # for details see https://gitlab.com/gitlab-org/sidekiq-reliable-fetch/blob/master/README.md
80
+ config.options[:semi_reliable_fetch] = true
81
+ # Do not requeue jobs after sidekiq shutdown
82
+ config.options[:max_retries_after_interruption] = 0
83
+ # Do not store interrupted jobs, just discard them
84
+ config.options[:interrupted_max_jobs] = 0
85
+ Sidekiq::ReliableFetch.setup_reliable_fetch!(config)
86
+ end
87
+ ExampleHelper.create_world do |config|
88
+ config.persistence_adapter = persistence_adapter
89
+ config.connector = connector
90
+ config.executor = false
91
+ end
92
+ end
93
+
40
94
  def run(world)
41
95
  begin
42
96
  ExampleHelper.run_web_console(world)
@@ -75,7 +129,10 @@ class RemoteExecutorExample
75
129
  world.trigger(OrchestrateEvented::CreateInfrastructure, true)
76
130
 
77
131
  loop do
132
+ start_time = Time.now
78
133
  world.trigger(SampleAction).finished.wait
134
+ finished_in = Time.now - start_time
135
+ puts "Finished in #{finished_in}s"
79
136
  sleep 0.5
80
137
  end
81
138
  end
@@ -106,4 +163,15 @@ MSG
106
163
  puts "Unknown command #{comment}"
107
164
  exit 1
108
165
  end
166
+ elsif defined?(Sidekiq)
167
+ # TODO:
168
+ Sidekiq.default_worker_options = { :retry => 0, 'backtrace' => true }
169
+ # assuming the remote executor was required as part of initialization
170
+ # of the ActiveJob worker
171
+ world = if Sidekiq.options[:queues].include?("dynflow_orchestrator")
172
+ RemoteExecutorExample.initialize_sidekiq_orchestrator
173
+ elsif (Sidekiq.options[:queues] - ['dynflow_orchestrator']).any?
174
+ RemoteExecutorExample.initialize_sidekiq_worker
175
+ end
176
+ Sidekiq.options[:dynflow_world] = world
109
177
  end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  example_description = <<DESC
3
4
 
4
5
  Sub Plans Example
@@ -44,9 +45,9 @@ if $0 == __FILE__
44
45
  | #{t2.id} should fail because #{t1.id} holds the lock
45
46
  |
46
47
  | You can see the details at
47
- | http://localhost:4567/#{t1.id}
48
- | http://localhost:4567/#{t2.id}
49
- | http://localhost:4567/#{t3.id}
48
+ | #{ExampleHelper::DYNFLOW_URL}/#{t1.id}
49
+ | #{ExampleHelper::DYNFLOW_URL}/#{t2.id}
50
+ | #{ExampleHelper::DYNFLOW_URL}/#{t3.id}
50
51
  |
51
52
  MSG
52
53
  ExampleHelper.run_web_console
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  example_description = <<DESC
4
5
  Sub-plan Concurrency Control Example
@@ -62,7 +63,7 @@ if $0 == __FILE__
62
63
  puts example_description
63
64
  puts <<-MSG.gsub(/^.*\|/, '')
64
65
  | Execution plan #{triggered.id} with 10 sub plans triggered
65
- | You can see the details at http://localhost:4567/#{triggered.id}/actions/1/sub_plans
66
+ | You can see the details at #{ExampleHelper::DYNFLOW_URL}/#{triggered.id}/actions/1/sub_plans
66
67
  | Or simply watch in the console that there are never more than #{ConcurrencyControlExample::ConcurrencyLevel} running at the same time.
67
68
  |
68
69
  | The tasks are distributed over #{ConcurrencyControlExample::RunWithin} seconds.
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  example_description = <<DESC
3
4
  Sub Plans Example
4
5
  ===================
@@ -51,8 +52,8 @@ if $0 == __FILE__
51
52
  puts <<-MSG.gsub(/^.*\|/, '')
52
53
  | Execution plans #{t1.id} and #{t2.id} with sub plans triggered
53
54
  | You can see the details at
54
- | http://localhost:4567/#{t2.id}
55
- | http://localhost:4567/#{t1.id}
55
+ | #{ExampleHelper::DYNFLOW_URL}/#{t2.id}
56
+ | #{ExampleHelper::DYNFLOW_URL}/#{t1.id}
56
57
  MSG
57
58
 
58
59
  ExampleHelper.run_web_console