dynflow 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.travis.yml +3 -4
- data/Dockerfile +9 -0
- data/Gemfile +6 -0
- data/Rakefile +1 -0
- data/doc/pages/Gemfile +1 -0
- data/doc/pages/Rakefile +1 -0
- data/doc/pages/plugins/alert_block.rb +1 -0
- data/doc/pages/plugins/div_tag.rb +1 -0
- data/doc/pages/plugins/graphviz.rb +1 -0
- data/doc/pages/plugins/plantuml.rb +1 -0
- data/doc/pages/plugins/play.rb +1 -0
- data/doc/pages/plugins/tags.rb +1 -0
- data/doc/pages/plugins/toc.rb +1 -0
- data/docker-compose.yml +41 -0
- data/dynflow.gemspec +1 -0
- data/examples/clock_benchmark.rb +1 -0
- data/examples/example_helper.rb +19 -2
- data/examples/future_execution.rb +2 -1
- data/examples/memory_limit_watcher.rb +1 -0
- data/examples/orchestrate.rb +4 -5
- data/examples/orchestrate_evented.rb +3 -2
- data/examples/remote_executor.rb +68 -0
- data/examples/singletons.rb +4 -3
- data/examples/sub_plan_concurrency_control.rb +2 -1
- data/examples/sub_plans.rb +3 -2
- data/examples/termination.rb +1 -0
- data/lib/dynflow.rb +20 -0
- data/lib/dynflow/action.rb +28 -3
- data/lib/dynflow/action/cancellable.rb +1 -0
- data/lib/dynflow/action/format.rb +1 -0
- data/lib/dynflow/action/missing.rb +1 -0
- data/lib/dynflow/action/polling.rb +3 -1
- data/lib/dynflow/action/progress.rb +1 -0
- data/lib/dynflow/action/rescue.rb +1 -0
- data/lib/dynflow/action/singleton.rb +1 -0
- data/lib/dynflow/action/suspended.rb +9 -2
- data/lib/dynflow/action/timeouts.rb +2 -1
- data/lib/dynflow/action/with_bulk_sub_plans.rb +2 -1
- data/lib/dynflow/action/with_polling_sub_plans.rb +7 -5
- data/lib/dynflow/action/with_sub_plans.rb +1 -0
- data/lib/dynflow/active_job/queue_adapter.rb +1 -0
- data/lib/dynflow/actor.rb +13 -5
- data/lib/dynflow/actors.rb +1 -0
- data/lib/dynflow/actors/execution_plan_cleaner.rb +1 -0
- data/lib/dynflow/clock.rb +27 -47
- data/lib/dynflow/config.rb +11 -2
- data/lib/dynflow/connectors.rb +1 -0
- data/lib/dynflow/connectors/abstract.rb +1 -0
- data/lib/dynflow/connectors/database.rb +1 -0
- data/lib/dynflow/connectors/direct.rb +1 -0
- data/lib/dynflow/coordinator.rb +1 -0
- data/lib/dynflow/coordinator_adapters.rb +1 -0
- data/lib/dynflow/coordinator_adapters/abstract.rb +1 -0
- data/lib/dynflow/coordinator_adapters/sequel.rb +1 -0
- data/lib/dynflow/dead_letter_silencer.rb +2 -0
- data/lib/dynflow/debug/telemetry/persistence.rb +1 -0
- data/lib/dynflow/delayed_executors.rb +1 -0
- data/lib/dynflow/delayed_executors/abstract.rb +1 -0
- data/lib/dynflow/delayed_executors/abstract_core.rb +1 -0
- data/lib/dynflow/delayed_executors/polling.rb +1 -0
- data/lib/dynflow/delayed_plan.rb +1 -0
- data/lib/dynflow/director.rb +80 -15
- data/lib/dynflow/director/execution_plan_manager.rb +17 -3
- data/lib/dynflow/director/flow_manager.rb +1 -0
- data/lib/dynflow/director/{work_queue.rb → queue_hash.rb} +9 -8
- data/lib/dynflow/director/running_steps_manager.rb +55 -18
- data/lib/dynflow/director/sequence_cursor.rb +1 -0
- data/lib/dynflow/director/sequential_manager.rb +12 -2
- data/lib/dynflow/dispatcher.rb +4 -2
- data/lib/dynflow/dispatcher/abstract.rb +1 -0
- data/lib/dynflow/dispatcher/client_dispatcher.rb +6 -4
- data/lib/dynflow/dispatcher/executor_dispatcher.rb +13 -1
- data/lib/dynflow/errors.rb +1 -0
- data/lib/dynflow/execution_history.rb +1 -0
- data/lib/dynflow/execution_plan.rb +3 -2
- data/lib/dynflow/execution_plan/dependency_graph.rb +1 -0
- data/lib/dynflow/execution_plan/hooks.rb +1 -0
- data/lib/dynflow/execution_plan/output_reference.rb +2 -1
- data/lib/dynflow/execution_plan/steps.rb +1 -0
- data/lib/dynflow/execution_plan/steps/abstract.rb +10 -5
- data/lib/dynflow/execution_plan/steps/abstract_flow_step.rb +2 -0
- data/lib/dynflow/execution_plan/steps/error.rb +1 -0
- data/lib/dynflow/execution_plan/steps/finalize_step.rb +1 -0
- data/lib/dynflow/execution_plan/steps/plan_step.rb +1 -0
- data/lib/dynflow/execution_plan/steps/run_step.rb +1 -0
- data/lib/dynflow/executors.rb +1 -1
- data/lib/dynflow/executors/abstract/core.rb +132 -0
- data/lib/dynflow/executors/parallel.rb +24 -11
- data/lib/dynflow/executors/parallel/core.rb +10 -91
- data/lib/dynflow/executors/parallel/pool.rb +4 -2
- data/lib/dynflow/executors/parallel/worker.rb +2 -1
- data/lib/dynflow/executors/sidekiq/core.rb +121 -0
- data/lib/dynflow/executors/sidekiq/internal_job_base.rb +24 -0
- data/lib/dynflow/executors/sidekiq/orchestrator_jobs.rb +60 -0
- data/lib/dynflow/executors/sidekiq/redis_locking.rb +69 -0
- data/lib/dynflow/executors/sidekiq/serialization.rb +33 -0
- data/lib/dynflow/executors/sidekiq/worker_jobs.rb +42 -0
- data/lib/dynflow/flows.rb +1 -0
- data/lib/dynflow/flows/abstract.rb +1 -0
- data/lib/dynflow/flows/abstract_composed.rb +1 -0
- data/lib/dynflow/flows/atom.rb +1 -0
- data/lib/dynflow/flows/concurrence.rb +1 -0
- data/lib/dynflow/flows/sequence.rb +1 -0
- data/lib/dynflow/logger_adapters.rb +1 -0
- data/lib/dynflow/logger_adapters/abstract.rb +1 -0
- data/lib/dynflow/logger_adapters/delegator.rb +1 -0
- data/lib/dynflow/logger_adapters/formatters.rb +1 -0
- data/lib/dynflow/logger_adapters/formatters/abstract.rb +1 -0
- data/lib/dynflow/logger_adapters/formatters/exception.rb +1 -0
- data/lib/dynflow/logger_adapters/simple.rb +1 -0
- data/lib/dynflow/middleware.rb +1 -0
- data/lib/dynflow/middleware/common/singleton.rb +1 -0
- data/lib/dynflow/middleware/common/transaction.rb +1 -0
- data/lib/dynflow/middleware/register.rb +1 -0
- data/lib/dynflow/middleware/resolver.rb +1 -0
- data/lib/dynflow/middleware/stack.rb +1 -0
- data/lib/dynflow/middleware/world.rb +1 -0
- data/lib/dynflow/persistence.rb +3 -2
- data/lib/dynflow/persistence_adapters.rb +1 -0
- data/lib/dynflow/persistence_adapters/abstract.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel.rb +10 -7
- data/lib/dynflow/persistence_adapters/sequel_migrations/001_initial.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/002_incremental_progress.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/003_parent_action.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/004_coordinator_records.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/005_envelopes.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/006_fix_data_length.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/007_future_execution.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/008_rename_scheduled_plans_to_delayed_plans.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/009_fix_mysql_data_length.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/010_add_execution_plans_label.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/011_placeholder.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/012_add_delayed_plans_serialized_args.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/013_add_action_columns.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/014_add_step_columns.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/015_add_execution_plan_columns.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/016_add_step_queue.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/017_add_delayed_plan_frozen.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/018_add_uuid_column.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/019_update_mysql_time_precision.rb +48 -0
- data/lib/dynflow/rails.rb +1 -0
- data/lib/dynflow/rails/configuration.rb +6 -3
- data/lib/dynflow/rails/daemon.rb +1 -0
- data/lib/dynflow/round_robin.rb +1 -0
- data/lib/dynflow/semaphores.rb +1 -0
- data/lib/dynflow/semaphores/abstract.rb +1 -0
- data/lib/dynflow/semaphores/aggregating.rb +1 -0
- data/lib/dynflow/semaphores/dummy.rb +1 -0
- data/lib/dynflow/semaphores/stateful.rb +1 -0
- data/lib/dynflow/serializable.rb +13 -4
- data/lib/dynflow/serializer.rb +24 -0
- data/lib/dynflow/serializers.rb +1 -0
- data/lib/dynflow/serializers/abstract.rb +1 -0
- data/lib/dynflow/serializers/noop.rb +1 -0
- data/lib/dynflow/stateful.rb +1 -0
- data/lib/dynflow/telemetry.rb +1 -0
- data/lib/dynflow/telemetry_adapters/abstract.rb +1 -0
- data/lib/dynflow/telemetry_adapters/dummy.rb +1 -0
- data/lib/dynflow/telemetry_adapters/statsd.rb +1 -0
- data/lib/dynflow/testing.rb +1 -0
- data/lib/dynflow/testing/assertions.rb +6 -5
- data/lib/dynflow/testing/dummy_execution_plan.rb +1 -0
- data/lib/dynflow/testing/dummy_executor.rb +19 -2
- data/lib/dynflow/testing/dummy_planned_action.rb +1 -0
- data/lib/dynflow/testing/dummy_step.rb +3 -1
- data/lib/dynflow/testing/dummy_world.rb +9 -0
- data/lib/dynflow/testing/factories.rb +6 -1
- data/lib/dynflow/testing/in_thread_executor.rb +22 -3
- data/lib/dynflow/testing/in_thread_world.rb +9 -0
- data/lib/dynflow/testing/managed_clock.rb +1 -0
- data/lib/dynflow/testing/mimic.rb +1 -0
- data/lib/dynflow/throttle_limiter.rb +1 -0
- data/lib/dynflow/transaction_adapters.rb +1 -0
- data/lib/dynflow/transaction_adapters/abstract.rb +1 -0
- data/lib/dynflow/transaction_adapters/active_record.rb +1 -0
- data/lib/dynflow/transaction_adapters/none.rb +1 -0
- data/lib/dynflow/utils.rb +1 -0
- data/lib/dynflow/utils/indifferent_hash.rb +1 -0
- data/lib/dynflow/utils/priority_queue.rb +1 -0
- data/lib/dynflow/version.rb +2 -1
- data/lib/dynflow/watchers/memory_consumption_watcher.rb +1 -0
- data/lib/dynflow/web.rb +1 -0
- data/lib/dynflow/web/console.rb +1 -0
- data/lib/dynflow/web/console_helpers.rb +1 -0
- data/lib/dynflow/web/filtering_helpers.rb +1 -0
- data/lib/dynflow/web/world_helpers.rb +1 -0
- data/lib/dynflow/web_console.rb +1 -0
- data/lib/dynflow/world.rb +11 -1
- data/lib/dynflow/world/invalidation.rb +7 -1
- data/test/abnormal_states_recovery_test.rb +41 -40
- data/test/action_test.rb +160 -110
- data/test/activejob_adapter_test.rb +1 -0
- data/test/batch_sub_tasks_test.rb +12 -11
- data/test/clock_test.rb +2 -1
- data/test/concurrency_control_test.rb +20 -19
- data/test/coordinator_test.rb +20 -21
- data/test/daemon_test.rb +2 -1
- data/test/dead_letter_silencer_test.rb +9 -7
- data/test/dispatcher_test.rb +2 -1
- data/test/execution_plan_cleaner_test.rb +13 -12
- data/test/execution_plan_hooks_test.rb +3 -2
- data/test/execution_plan_test.rb +33 -32
- data/test/executor_test.rb +533 -489
- data/test/future_execution_test.rb +45 -44
- data/test/memory_cosumption_watcher_test.rb +5 -4
- data/test/middleware_test.rb +55 -54
- data/test/persistence_test.rb +56 -53
- data/test/rescue_test.rb +36 -35
- data/test/round_robin_test.rb +13 -12
- data/test/semaphores_test.rb +31 -30
- data/test/support/code_workflow_example.rb +1 -0
- data/test/support/dummy_example.rb +14 -1
- data/test/support/middleware_example.rb +2 -1
- data/test/support/rails/config/environment.rb +1 -0
- data/test/support/rescue_example.rb +1 -0
- data/test/support/test_execution_log.rb +1 -0
- data/test/test_helper.rb +18 -17
- data/test/testing_test.rb +45 -44
- data/test/utils_test.rb +18 -17
- data/test/web_console_test.rb +1 -0
- data/test/world_test.rb +7 -6
- metadata +13 -4
- data/lib/dynflow/executors/abstract.rb +0 -40
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Dynflow
|
3
|
+
module Executors
|
4
|
+
module Sidekiq
|
5
|
+
module WorkerJobs
|
6
|
+
class PerformWork < InternalJobBase
|
7
|
+
def perform(work_item)
|
8
|
+
with_telemetry(work_item) do
|
9
|
+
Executors.run_user_code do
|
10
|
+
work_item.world = Dynflow.process_world
|
11
|
+
work_item.execute
|
12
|
+
end
|
13
|
+
end
|
14
|
+
rescue Errors::PersistenceError => e
|
15
|
+
OrchestratorJobs::HandlePersistenceError.perform_async(e, work_item)
|
16
|
+
ensure
|
17
|
+
step = work_item.step if work_item.is_a?(Director::StepWorkItem)
|
18
|
+
OrchestratorJobs::WorkerDone.perform_async(work_item, step && step.delayed_events)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def with_telemetry(work_item)
|
24
|
+
Dynflow::Telemetry.with_instance { |t| t.set_gauge(:dynflow_active_workers, +1, telemetry_options(work_item)) }
|
25
|
+
yield
|
26
|
+
ensure
|
27
|
+
Dynflow::Telemetry.with_instance do |t|
|
28
|
+
t.increment_counter(:dynflow_worker_events, 1, telemetry_options(work_item))
|
29
|
+
t.set_gauge(:dynflow_active_workers, -1, telemetry_options(work_item))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class DrainMarker < InternalJobBase
|
35
|
+
def perform(world_id)
|
36
|
+
OrchestratorJobs::StartupComplete.perform_async(world_id)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/dynflow/flows.rb
CHANGED
data/lib/dynflow/flows/atom.rb
CHANGED
data/lib/dynflow/middleware.rb
CHANGED
data/lib/dynflow/persistence.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'dynflow/persistence_adapters'
|
2
3
|
|
3
4
|
module Dynflow
|
@@ -117,8 +118,8 @@ module Dynflow
|
|
117
118
|
end
|
118
119
|
end
|
119
120
|
|
120
|
-
def save_step(step)
|
121
|
-
adapter.save_step(step.execution_plan_id, step.id, step.to_hash)
|
121
|
+
def save_step(step, conditions = {})
|
122
|
+
adapter.save_step(step.execution_plan_id, step.id, step.to_hash, conditions)
|
122
123
|
end
|
123
124
|
|
124
125
|
def push_envelope(envelope)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'sequel'
|
2
3
|
require 'multi_json'
|
3
4
|
require 'fileutils'
|
@@ -100,7 +101,7 @@ module Dynflow
|
|
100
101
|
end
|
101
102
|
|
102
103
|
def save_execution_plan(execution_plan_id, value)
|
103
|
-
save :execution_plan, { uuid: execution_plan_id }, value, false
|
104
|
+
save :execution_plan, { uuid: execution_plan_id }, value, with_data: false
|
104
105
|
end
|
105
106
|
|
106
107
|
def delete_delayed_plans(filters, batch_size = 1000)
|
@@ -138,7 +139,7 @@ module Dynflow
|
|
138
139
|
end
|
139
140
|
|
140
141
|
def save_delayed_plan(execution_plan_id, value)
|
141
|
-
save :delayed, { execution_plan_uuid: execution_plan_id }, value, false
|
142
|
+
save :delayed, { execution_plan_uuid: execution_plan_id }, value, with_data: false
|
142
143
|
end
|
143
144
|
|
144
145
|
def load_step(execution_plan_id, step_id)
|
@@ -149,8 +150,9 @@ module Dynflow
|
|
149
150
|
load_records :step, execution_plan_uuid: execution_plan_id
|
150
151
|
end
|
151
152
|
|
152
|
-
def save_step(execution_plan_id, step_id, value)
|
153
|
-
save :step, { execution_plan_uuid: execution_plan_id, id: step_id }, value,
|
153
|
+
def save_step(execution_plan_id, step_id, value, update_conditions = {})
|
154
|
+
save :step, { execution_plan_uuid: execution_plan_id, id: step_id }, value,
|
155
|
+
with_data: false, update_conditions: update_conditions
|
154
156
|
end
|
155
157
|
|
156
158
|
def load_action(execution_plan_id, action_id)
|
@@ -166,7 +168,7 @@ module Dynflow
|
|
166
168
|
end
|
167
169
|
|
168
170
|
def save_action(execution_plan_id, action_id, value)
|
169
|
-
save :action, { execution_plan_uuid: execution_plan_id, id: action_id }, value, false
|
171
|
+
save :action, { execution_plan_uuid: execution_plan_id, id: action_id }, value, with_data: false
|
170
172
|
end
|
171
173
|
|
172
174
|
def connector_feature!
|
@@ -286,14 +288,15 @@ module Dynflow
|
|
286
288
|
end
|
287
289
|
end
|
288
290
|
|
289
|
-
def save(what, condition, value, with_data
|
291
|
+
def save(what, condition, value, with_data: true, update_conditions: {})
|
290
292
|
table = table(what)
|
291
293
|
existing_record = with_retry { table.first condition } unless condition.empty?
|
292
294
|
|
293
295
|
if value
|
294
296
|
record = prepare_record(what, value, (existing_record || condition), with_data)
|
295
297
|
if existing_record
|
296
|
-
|
298
|
+
condition = update_conditions.merge(condition)
|
299
|
+
return with_retry { table.where(condition).update(record) }
|
297
300
|
else
|
298
301
|
with_retry { table.insert record }
|
299
302
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
Sequel.migration do
|
3
|
+
up do
|
4
|
+
alter_table(:dynflow_execution_plans) do
|
5
|
+
if @db.database_type == :mysql
|
6
|
+
set_column_type :started_at, 'datetime(3)'
|
7
|
+
set_column_type :ended_at, 'datetime(3)'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
alter_table(:dynflow_steps) do
|
12
|
+
if @db.database_type == :mysql
|
13
|
+
set_column_type :started_at, 'datetime(3)'
|
14
|
+
set_column_type :ended_at, 'datetime(3)'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
alter_table(:dynflow_delayed_plans) do
|
19
|
+
if @db.database_type == :mysql
|
20
|
+
set_column_type :start_at, 'datetime(3)'
|
21
|
+
set_column_type :start_before, 'datetime(3)'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
down do
|
27
|
+
alter_table(:dynflow_steps) do
|
28
|
+
if @db.database_type == :mysql
|
29
|
+
set_column_type :started_at, Time
|
30
|
+
set_column_type :ended_at, Time
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
alter_table(:dynflow_steps) do
|
35
|
+
if @db.database_type == :mysql
|
36
|
+
set_column_type :started_at, Time
|
37
|
+
set_column_type :ended_at, Time
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
alter_table(:dynflow_delayed_plans) do
|
42
|
+
if @db.database_type == :mysql
|
43
|
+
set_column_type :start_at, Time
|
44
|
+
set_column_type :start_before, Time
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/dynflow/rails.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rails'
|
2
3
|
require 'active_record'
|
3
4
|
|
@@ -167,9 +168,11 @@ module Dynflow
|
|
167
168
|
if remote?
|
168
169
|
false
|
169
170
|
else
|
170
|
-
::
|
171
|
-
|
172
|
-
|
171
|
+
if defined?(::Sidekiq) && !Sidekiq.options[:dynflow_world].nil?
|
172
|
+
::Dynflow::Executors::Sidekiq::Core
|
173
|
+
else
|
174
|
+
::Dynflow::Executors::Parallel::Core
|
175
|
+
end
|
173
176
|
end
|
174
177
|
end
|
175
178
|
|
data/lib/dynflow/rails/daemon.rb
CHANGED
data/lib/dynflow/round_robin.rb
CHANGED