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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -1
- data/.rubocop.yml +11 -5
- data/.rubocop_todo.yml +777 -345
- data/Gemfile +4 -3
- data/Rakefile +1 -0
- data/doc/pages/Gemfile +4 -3
- 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 +6 -6
- data/doc/pages/plugins/plantuml.rb +2 -3
- data/doc/pages/plugins/play.rb +1 -2
- data/doc/pages/plugins/tags.rb +2 -8
- data/doc/pages/plugins/toc.rb +1 -1
- data/dynflow.gemspec +11 -10
- data/examples/clock_benchmark.rb +1 -0
- data/examples/example_helper.rb +4 -3
- data/examples/future_execution.rb +0 -2
- data/examples/memory_limit_watcher.rb +8 -8
- data/examples/orchestrate.rb +9 -21
- data/examples/orchestrate_evented.rb +18 -33
- data/examples/remote_executor.rb +13 -14
- data/examples/singletons.rb +1 -0
- data/examples/sub_plan_concurrency_control.rb +0 -1
- data/examples/sub_plans.rb +1 -0
- data/examples/sub_plans_v2.rb +1 -0
- data/lib/dynflow/action/cancellable.rb +1 -0
- data/lib/dynflow/action/format.rb +1 -4
- data/lib/dynflow/action/missing.rb +4 -4
- data/lib/dynflow/action/polling.rb +2 -3
- data/lib/dynflow/action/progress.rb +1 -4
- data/lib/dynflow/action/rescue.rb +1 -2
- data/lib/dynflow/action/singleton.rb +1 -0
- data/lib/dynflow/action/suspended.rb +1 -0
- data/lib/dynflow/action/timeouts.rb +2 -1
- data/lib/dynflow/action/with_bulk_sub_plans.rb +1 -0
- data/lib/dynflow/action/with_polling_sub_plans.rb +1 -1
- data/lib/dynflow/action/with_sub_plans.rb +20 -19
- data/lib/dynflow/action.rb +37 -37
- data/lib/dynflow/active_job/queue_adapter.rb +2 -1
- data/lib/dynflow/actor.rb +2 -2
- data/lib/dynflow/actors/execution_plan_cleaner.rb +1 -0
- data/lib/dynflow/actors.rb +1 -0
- data/lib/dynflow/clock.rb +3 -4
- data/lib/dynflow/config.rb +6 -5
- data/lib/dynflow/connectors/abstract.rb +11 -10
- data/lib/dynflow/connectors/database.rb +2 -2
- data/lib/dynflow/connectors/direct.rb +2 -3
- data/lib/dynflow/connectors.rb +1 -0
- data/lib/dynflow/coordinator.rb +2 -6
- data/lib/dynflow/coordinator_adapters/abstract.rb +1 -0
- data/lib/dynflow/coordinator_adapters/sequel.rb +1 -0
- data/lib/dynflow/coordinator_adapters.rb +1 -2
- data/lib/dynflow/dead_letter_silencer.rb +1 -0
- data/lib/dynflow/debug/telemetry/persistence.rb +3 -2
- data/lib/dynflow/delayed_executors/abstract.rb +1 -2
- data/lib/dynflow/delayed_executors/abstract_core.rb +1 -1
- data/lib/dynflow/delayed_executors/polling.rb +1 -2
- data/lib/dynflow/delayed_executors.rb +1 -2
- data/lib/dynflow/delayed_plan.rb +6 -6
- data/lib/dynflow/director/execution_plan_manager.rb +1 -1
- data/lib/dynflow/director/flow_manager.rb +1 -0
- data/lib/dynflow/director/queue_hash.rb +2 -1
- data/lib/dynflow/director/running_steps_manager.rb +3 -2
- data/lib/dynflow/director/sequence_cursor.rb +1 -2
- data/lib/dynflow/director/sequential_manager.rb +1 -0
- data/lib/dynflow/director.rb +12 -11
- data/lib/dynflow/dispatcher/abstract.rb +1 -0
- data/lib/dynflow/dispatcher/client_dispatcher.rb +33 -33
- data/lib/dynflow/dispatcher/executor_dispatcher.rb +7 -6
- data/lib/dynflow/dispatcher.rb +8 -7
- data/lib/dynflow/errors.rb +1 -0
- data/lib/dynflow/execution_history.rb +2 -1
- data/lib/dynflow/execution_plan/dependency_graph.rb +1 -2
- data/lib/dynflow/execution_plan/hooks.rb +1 -1
- data/lib/dynflow/execution_plan/output_reference.rb +4 -4
- data/lib/dynflow/execution_plan/steps/abstract.rb +21 -20
- data/lib/dynflow/execution_plan/steps/abstract_flow_step.rb +1 -1
- data/lib/dynflow/execution_plan/steps/error.rb +10 -9
- data/lib/dynflow/execution_plan/steps/finalize_step.rb +1 -2
- data/lib/dynflow/execution_plan/steps/plan_step.rb +12 -11
- data/lib/dynflow/execution_plan/steps/run_step.rb +1 -1
- data/lib/dynflow/execution_plan/steps.rb +1 -2
- data/lib/dynflow/execution_plan.rb +46 -46
- data/lib/dynflow/executors/abstract/core.rb +4 -3
- data/lib/dynflow/executors/parallel/core.rb +3 -2
- data/lib/dynflow/executors/parallel/pool.rb +1 -4
- data/lib/dynflow/executors/parallel/worker.rb +1 -0
- data/lib/dynflow/executors/parallel.rb +3 -2
- data/lib/dynflow/executors/sidekiq/core.rb +3 -1
- data/lib/dynflow/executors/sidekiq/internal_job_base.rb +1 -0
- data/lib/dynflow/executors/sidekiq/orchestrator_jobs.rb +1 -0
- data/lib/dynflow/executors/sidekiq/redis_locking.rb +1 -0
- data/lib/dynflow/executors/sidekiq/serialization.rb +1 -0
- data/lib/dynflow/executors/sidekiq/worker_jobs.rb +1 -0
- data/lib/dynflow/executors.rb +1 -1
- data/lib/dynflow/extensions/msgpack.rb +5 -4
- data/lib/dynflow/extensions.rb +1 -0
- data/lib/dynflow/flows/abstract.rb +1 -1
- data/lib/dynflow/flows/abstract_composed.rb +1 -2
- data/lib/dynflow/flows/atom.rb +1 -2
- data/lib/dynflow/flows/concurrence.rb +1 -1
- data/lib/dynflow/flows/registry.rb +1 -0
- data/lib/dynflow/flows/sequence.rb +1 -1
- data/lib/dynflow/flows.rb +1 -2
- data/lib/dynflow/logger_adapters/abstract.rb +1 -1
- data/lib/dynflow/logger_adapters/delegator.rb +1 -1
- 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/formatters.rb +1 -0
- data/lib/dynflow/logger_adapters/simple.rb +6 -5
- data/lib/dynflow/logger_adapters.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 +2 -3
- data/lib/dynflow/middleware/stack.rb +1 -0
- data/lib/dynflow/middleware/world.rb +1 -2
- data/lib/dynflow/middleware.rb +1 -0
- data/lib/dynflow/persistence.rb +4 -5
- data/lib/dynflow/persistence_adapters/abstract.rb +1 -1
- data/lib/dynflow/persistence_adapters/sequel.rb +14 -14
- data/lib/dynflow/persistence_adapters/sequel_migrations/001_initial.rb +2 -1
- 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 -1
- 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 -1
- 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 +37 -30
- data/lib/dynflow/persistence_adapters/sequel_migrations/019_update_mysql_time_precision.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/020_drop_duplicate_indices.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/021_create_output_chunks.rb +4 -3
- data/lib/dynflow/persistence_adapters/sequel_migrations/023_sqlite_workarounds.rb +1 -0
- data/lib/dynflow/persistence_adapters.rb +1 -0
- data/lib/dynflow/rails/configuration.rb +5 -4
- data/lib/dynflow/rails/daemon.rb +1 -1
- data/lib/dynflow/rails.rb +3 -2
- data/lib/dynflow/round_robin.rb +2 -2
- data/lib/dynflow/semaphores/abstract.rb +1 -1
- data/lib/dynflow/semaphores/aggregating.rb +1 -2
- data/lib/dynflow/semaphores/dummy.rb +1 -1
- data/lib/dynflow/semaphores/stateful.rb +1 -1
- data/lib/dynflow/semaphores.rb +1 -0
- data/lib/dynflow/serializable.rb +1 -0
- data/lib/dynflow/serializer.rb +2 -2
- data/lib/dynflow/serializers/abstract.rb +1 -2
- data/lib/dynflow/serializers/noop.rb +1 -2
- data/lib/dynflow/serializers.rb +1 -2
- data/lib/dynflow/stateful.rb +1 -0
- data/lib/dynflow/telemetry.rb +11 -10
- 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 +2 -1
- data/lib/dynflow/testing/assertions.rb +7 -7
- data/lib/dynflow/testing/dummy_coordinator.rb +1 -0
- data/lib/dynflow/testing/dummy_execution_plan.rb +1 -0
- data/lib/dynflow/testing/dummy_executor.rb +1 -0
- data/lib/dynflow/testing/dummy_planned_action.rb +3 -1
- data/lib/dynflow/testing/dummy_step.rb +1 -0
- data/lib/dynflow/testing/dummy_world.rb +1 -0
- data/lib/dynflow/testing/factories.rb +42 -37
- data/lib/dynflow/testing/in_thread_executor.rb +1 -0
- data/lib/dynflow/testing/in_thread_world.rb +1 -0
- data/lib/dynflow/testing/managed_clock.rb +1 -1
- data/lib/dynflow/testing/mimic.rb +4 -4
- data/lib/dynflow/testing.rb +1 -0
- data/lib/dynflow/throttle_limiter.rb +1 -1
- 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/transaction_adapters.rb +1 -2
- data/lib/dynflow/utils/indifferent_hash.rb +7 -1
- data/lib/dynflow/utils/priority_queue.rb +1 -0
- data/lib/dynflow/utils.rb +1 -1
- data/lib/dynflow/version.rb +2 -1
- data/lib/dynflow/watchers/memory_consumption_watcher.rb +1 -1
- data/lib/dynflow/web/console.rb +1 -3
- data/lib/dynflow/web/console_helpers.rb +5 -4
- data/lib/dynflow/web/filtering_helpers.rb +1 -0
- data/lib/dynflow/web/world_helpers.rb +1 -0
- data/lib/dynflow/web.rb +3 -3
- data/lib/dynflow/web_console.rb +1 -0
- data/lib/dynflow/world/invalidation.rb +1 -0
- data/lib/dynflow/world.rb +19 -19
- data/lib/dynflow.rb +3 -6
- data/test/abnormal_states_recovery_test.rb +4 -8
- data/test/action_test.rb +10 -18
- data/test/activejob_adapter_test.rb +2 -2
- data/test/batch_sub_tasks_test.rb +1 -1
- data/test/clock_test.rb +2 -3
- data/test/concurrency_control_test.rb +6 -7
- data/test/coordinator_test.rb +1 -0
- data/test/daemon_test.rb +3 -2
- data/test/dead_letter_silencer_test.rb +2 -1
- data/test/dispatcher_test.rb +4 -5
- data/test/execution_plan_cleaner_test.rb +1 -0
- data/test/execution_plan_hooks_test.rb +1 -0
- data/test/execution_plan_test.rb +10 -32
- data/test/executor_test.rb +20 -37
- data/test/extensions_test.rb +1 -0
- data/test/flows_test.rb +2 -2
- data/test/future_execution_test.rb +2 -3
- data/test/memory_cosumption_watcher_test.rb +1 -0
- data/test/middleware_test.rb +4 -6
- data/test/persistence_test.rb +26 -26
- data/test/redis_locking_test.rb +1 -0
- data/test/rescue_test.rb +3 -11
- data/test/round_robin_test.rb +1 -0
- data/test/semaphores_test.rb +5 -7
- data/test/support/code_workflow_example.rb +11 -28
- data/test/support/dummy_example.rb +20 -19
- data/test/support/middleware_example.rb +2 -8
- data/test/support/rescue_example.rb +1 -14
- data/test/support/test_execution_log.rb +1 -2
- data/test/test_helper.rb +3 -7
- data/test/testing_test.rb +6 -8
- data/test/utils_test.rb +1 -0
- data/test/v2_sub_plans_test.rb +1 -0
- data/test/web_console_test.rb +4 -4
- data/test/world_test.rb +4 -3
- metadata +43 -43
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
module Debug
|
4
5
|
module Telemetry
|
@@ -32,7 +33,7 @@ module Dynflow
|
|
32
33
|
|
33
34
|
methods.each do |name|
|
34
35
|
define_method(name) do |*args|
|
35
|
-
Dynflow::Telemetry.measure(:dynflow_persistence, :method => name, :world => @world.id) { super
|
36
|
+
Dynflow::Telemetry.measure(:dynflow_persistence, :method => name, :world => @world.id) { super(*args) }
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
@@ -40,4 +41,4 @@ module Dynflow
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
|
-
::Dynflow::Persistence.
|
44
|
+
::Dynflow::Persistence.prepend ::Dynflow::Debug::Persistence
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
module DelayedExecutors
|
4
5
|
class Abstract
|
5
|
-
|
6
6
|
attr_reader :core
|
7
7
|
|
8
8
|
def initialize(world, options = {})
|
@@ -39,7 +39,6 @@ module Dynflow
|
|
39
39
|
def core_class
|
40
40
|
raise NotImplementedError
|
41
41
|
end
|
42
|
-
|
43
42
|
end
|
44
43
|
end
|
45
44
|
end
|
data/lib/dynflow/delayed_plan.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
class DelayedPlan < Serializable
|
4
|
-
|
5
5
|
include Algebrick::TypeCheck
|
6
6
|
|
7
7
|
attr_reader :execution_plan_uuid, :start_before
|
@@ -72,11 +72,11 @@ module Dynflow
|
|
72
72
|
def self.new_from_hash(world, hash, *args)
|
73
73
|
serializer = Utils.constantize(hash[:args_serializer]).new(nil, hash[:serialized_args])
|
74
74
|
self.new(world,
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
hash[:execution_plan_uuid],
|
76
|
+
string_to_time(hash[:start_at]),
|
77
|
+
string_to_time(hash[:start_before]),
|
78
|
+
serializer,
|
79
|
+
hash[:frozen] || false)
|
80
80
|
rescue NameError => e
|
81
81
|
error(e.message)
|
82
82
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
class Director
|
4
5
|
class QueueHash
|
@@ -7,7 +8,7 @@ module Dynflow
|
|
7
8
|
def initialize(key_type = Object, value_type = Object)
|
8
9
|
@key_type = key_type
|
9
10
|
@value_type = value_type
|
10
|
-
@stash
|
11
|
+
@stash = Hash.new { |hash, key| hash[key] = [] }
|
11
12
|
end
|
12
13
|
|
13
14
|
def push(key, value)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
class Director
|
4
5
|
# Handles the events generated while running actions, makes sure
|
@@ -50,13 +51,13 @@ module Dynflow
|
|
50
51
|
while (work = @work_items.shift(step.id))
|
51
52
|
@world.logger.debug "step #{step.execution_plan_id}:#{step.id} dropping event #{work.request_id}/#{work.event}"
|
52
53
|
finish_event_result(work) do |f|
|
53
|
-
f.reject
|
54
|
+
f.reject(UnprocessableEvent.new("Message dropped").tap { |e| e.set_backtrace(caller) })
|
54
55
|
end
|
55
56
|
end
|
56
57
|
while (event = @events.shift(step.id))
|
57
58
|
@world.logger.debug "step #{step.execution_plan_id}:#{step.id} dropping event #{event.request_id}/#{event}"
|
58
59
|
if event.result
|
59
|
-
event.result.reject
|
60
|
+
event.result.reject(UnprocessableEvent.new("Message dropped").tap { |e| e.set_backtrace(caller) })
|
60
61
|
end
|
61
62
|
end
|
62
63
|
unless @work_items.empty?(step.id) && @events.empty?(step.id)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
class Director
|
4
5
|
class SequenceCursor
|
5
|
-
|
6
6
|
def initialize(flow_manager, sequence, parent_cursor = nil)
|
7
7
|
@flow_manager = flow_manager
|
8
8
|
@sequence = sequence
|
@@ -86,7 +86,6 @@ module Dynflow
|
|
86
86
|
@todo << @flow_manager.execution_plan.steps[flow.step_id]
|
87
87
|
end
|
88
88
|
end
|
89
|
-
|
90
89
|
end
|
91
90
|
end
|
92
91
|
end
|
data/lib/dynflow/director.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
# Director is responsible for telling what to do next when:
|
4
5
|
# * new execution starts
|
@@ -75,9 +76,9 @@ module Dynflow
|
|
75
76
|
|
76
77
|
def self.new_from_hash(hash, *_args)
|
77
78
|
self.new(hash[:execution_plan_id],
|
78
|
-
|
79
|
-
|
80
|
-
|
79
|
+
Serializable.from_hash(hash[:step], hash[:execution_plan_id], Dynflow.process_world),
|
80
|
+
hash[:queue],
|
81
|
+
hash[:sender_orchestrator_id])
|
81
82
|
end
|
82
83
|
end
|
83
84
|
|
@@ -100,11 +101,11 @@ module Dynflow
|
|
100
101
|
|
101
102
|
def self.new_from_hash(hash, *_args)
|
102
103
|
self.new(hash[:request_id],
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
104
|
+
hash[:execution_plan_id],
|
105
|
+
Serializable.from_hash(hash[:step], hash[:execution_plan_id], Dynflow.process_world),
|
106
|
+
Dynflow.serializer.load(hash[:event]),
|
107
|
+
hash[:queue],
|
108
|
+
hash[:sender_orchestrator_id])
|
108
109
|
end
|
109
110
|
end
|
110
111
|
|
@@ -301,16 +302,16 @@ module Dynflow
|
|
301
302
|
|
302
303
|
if @execution_plan_managers[execution_plan_id]
|
303
304
|
raise Dynflow::Error,
|
304
|
-
|
305
|
+
"cannot execute execution_plan_id:#{execution_plan_id} it's already running"
|
305
306
|
end
|
306
307
|
|
307
308
|
if execution_plan.state == :stopped
|
308
309
|
raise Dynflow::Error,
|
309
|
-
|
310
|
+
"cannot execute execution_plan_id:#{execution_plan_id} it's stopped"
|
310
311
|
end
|
311
312
|
|
312
313
|
@execution_plan_managers[execution_plan_id] =
|
313
|
-
|
314
|
+
ExecutionPlanManager.new(@world, execution_plan, finished)
|
314
315
|
rescue Dynflow::Error => e
|
315
316
|
finished.reject e
|
316
317
|
nil
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
module Dispatcher
|
4
5
|
class ClientDispatcher < Abstract
|
5
|
-
|
6
6
|
TrackedRequest = Algebrick.type do
|
7
7
|
fields! id: String, request: Request,
|
8
8
|
accepted: Concurrent::Promises::ResolvableFuture, finished: Concurrent::Promises::ResolvableFuture
|
@@ -134,16 +134,16 @@ module Dynflow
|
|
134
134
|
def dispatch_request(request, client_world_id, request_id)
|
135
135
|
ignore_unknown = false
|
136
136
|
executor_id = match request,
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
137
|
+
(on ~Execution | ~Planning do |execution|
|
138
|
+
AnyExecutor
|
139
|
+
end),
|
140
|
+
(on ~Event do |event|
|
141
|
+
ignore_unknown = event.optional
|
142
|
+
find_executor(event.execution_plan_id)
|
143
|
+
end),
|
144
|
+
(on Ping.(~any, ~any) | Status.(~any, ~any) do |receiver_id, _|
|
145
|
+
receiver_id
|
146
|
+
end)
|
147
147
|
envelope = Envelope[request_id, client_world_id, executor_id, request]
|
148
148
|
if Dispatcher::UnknownWorld === envelope.receiver_id
|
149
149
|
raise Dynflow::Error, "Could not find an executor for #{envelope}" unless ignore_unknown
|
@@ -161,22 +161,22 @@ module Dynflow
|
|
161
161
|
def dispatch_response(envelope)
|
162
162
|
return unless @tracked_requests.key?(envelope.request_id)
|
163
163
|
match envelope.message,
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
164
|
+
(on ~Accepted do
|
165
|
+
@tracked_requests[envelope.request_id].accept!
|
166
|
+
end),
|
167
|
+
(on ~Failed do |msg|
|
168
|
+
resolve_tracked_request(envelope.request_id, Dynflow::Error.new(msg.error))
|
169
|
+
end),
|
170
|
+
(on Done do
|
171
|
+
resolve_tracked_request(envelope.request_id)
|
172
|
+
end),
|
173
|
+
(on Pong do
|
174
|
+
add_ping_cache_record(envelope.sender_id)
|
175
|
+
resolve_tracked_request(envelope.request_id)
|
176
|
+
end),
|
177
|
+
(on ExecutionStatus.(~any) do |steps|
|
178
|
+
@tracked_requests.delete(envelope.request_id).success! steps
|
179
|
+
end)
|
180
180
|
end
|
181
181
|
|
182
182
|
# Records when was the world with provided id last seen using a PingCache
|
@@ -233,12 +233,12 @@ module Dynflow
|
|
233
233
|
else
|
234
234
|
tracked_request = @tracked_requests[id]
|
235
235
|
resolve_to = match tracked_request.request,
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
236
|
+
(on Execution.(execution_plan_id: ~any) do |uuid|
|
237
|
+
@world.persistence.load_execution_plan(uuid)
|
238
|
+
end),
|
239
|
+
(on Event | Ping do
|
240
|
+
true
|
241
|
+
end)
|
242
242
|
@tracked_requests.delete(id).success! resolve_to
|
243
243
|
end
|
244
244
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
module Dispatcher
|
4
5
|
class ExecutorDispatcher < Abstract
|
@@ -9,10 +10,10 @@ module Dynflow
|
|
9
10
|
|
10
11
|
def handle_request(envelope)
|
11
12
|
match(envelope.message,
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
on(Planning) { perform_planning(envelope, envelope.message) },
|
14
|
+
on(Execution) { perform_execution(envelope, envelope.message) },
|
15
|
+
on(Event) { perform_event(envelope, envelope.message) },
|
16
|
+
on(Status) { get_execution_status(envelope, envelope.message) })
|
16
17
|
end
|
17
18
|
|
18
19
|
protected
|
@@ -61,13 +62,13 @@ module Dynflow
|
|
61
62
|
end
|
62
63
|
if event_request.time.nil? || event_request.time < Time.now
|
63
64
|
@world.executor.event(envelope.request_id, event_request.execution_plan_id, event_request.step_id, event_request.event, future,
|
64
|
-
|
65
|
+
optional: event_request.optional)
|
65
66
|
else
|
66
67
|
@world.clock.ping(
|
67
68
|
@world.executor,
|
68
69
|
event_request.time,
|
69
70
|
Director::Event[envelope.request_id, event_request.execution_plan_id, event_request.step_id, event_request.event, Concurrent::Promises.resolvable_future,
|
70
|
-
|
71
|
+
event_request.optional],
|
71
72
|
:delayed_event
|
72
73
|
)
|
73
74
|
# resolves the future right away - currently we do not wait for the clock ping
|
data/lib/dynflow/dispatcher.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
module Dispatcher
|
4
5
|
Request = Algebrick.type do
|
@@ -33,10 +34,10 @@ module Dynflow
|
|
33
34
|
|
34
35
|
Response = Algebrick.type do
|
35
36
|
variants Accepted = atom,
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
Failed = type { fields! error: String },
|
38
|
+
Done = atom,
|
39
|
+
Pong = atom,
|
40
|
+
ExecutionStatus = type { fields! execution_status: Hash }
|
40
41
|
end
|
41
42
|
|
42
43
|
Envelope = Algebrick.type do
|
@@ -49,9 +50,9 @@ module Dynflow
|
|
49
50
|
module Envelope
|
50
51
|
def build_response_envelope(response_message, sender)
|
51
52
|
Envelope[self.request_id,
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
sender.id,
|
54
|
+
self.sender_id,
|
55
|
+
response_message]
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
data/lib/dynflow/errors.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
class ExecutionHistory
|
4
5
|
include Algebrick::TypeCheck
|
@@ -35,7 +36,7 @@ module Dynflow
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def inspect
|
38
|
-
"ExecutionHistory: #{
|
39
|
+
"ExecutionHistory: #{@events.inspect}"
|
39
40
|
end
|
40
41
|
|
41
42
|
def self.new_from_hash(value)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
class ExecutionPlan::DependencyGraph
|
4
|
-
|
5
5
|
def initialize
|
6
6
|
@graph = Hash.new { |h, k| h[k] = Set.new }
|
7
7
|
end
|
@@ -25,6 +25,5 @@ module Dynflow
|
|
25
25
|
def unresolved?
|
26
26
|
@graph.any? { |step_id, required_step_ids| required_step_ids.any? }
|
27
27
|
end
|
28
|
-
|
29
28
|
end
|
30
29
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
class ExecutionPlan::OutputReference < Serializable
|
4
5
|
include Algebrick::TypeCheck
|
@@ -77,10 +78,9 @@ module Dynflow
|
|
77
78
|
def self.new_from_hash(hash)
|
78
79
|
check_class_matching hash
|
79
80
|
new(hash.fetch(:execution_plan_id),
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
hash.fetch(:step_id),
|
82
|
+
hash.fetch(:action_id),
|
83
|
+
hash.fetch(:subkeys))
|
83
84
|
end
|
84
|
-
|
85
85
|
end
|
86
86
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
module ExecutionPlan::Steps
|
4
5
|
class Abstract < Serializable
|
@@ -6,7 +7,7 @@ module Dynflow
|
|
6
7
|
include Stateful
|
7
8
|
|
8
9
|
attr_reader :execution_plan_id, :id, :state, :action_class, :action_id, :world, :started_at,
|
9
|
-
|
10
|
+
:ended_at, :execution_time, :real_time, :queue, :delayed_events
|
10
11
|
attr_accessor :error
|
11
12
|
|
12
13
|
# rubocop:disable Metrics/ParameterLists
|
@@ -37,7 +38,7 @@ module Dynflow
|
|
37
38
|
@progress_done = Type! progress_done, Numeric, NilClass
|
38
39
|
@progress_weight = Type! progress_weight, Numeric, NilClass
|
39
40
|
|
40
|
-
@queue
|
41
|
+
@queue = Type! queue, Symbol, NilClass
|
41
42
|
|
42
43
|
self.state = state.to_sym
|
43
44
|
|
@@ -144,25 +145,25 @@ module Dynflow
|
|
144
145
|
def self.new_from_hash(hash, execution_plan_id, world)
|
145
146
|
check_class_matching hash
|
146
147
|
new(execution_plan_id,
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
148
|
+
hash[:id],
|
149
|
+
hash[:state],
|
150
|
+
Action.constantize(hash[:action_class]),
|
151
|
+
hash[:action_id],
|
152
|
+
hash_to_error(hash[:error]),
|
153
|
+
world,
|
154
|
+
string_to_time(hash[:started_at]),
|
155
|
+
string_to_time(hash[:ended_at]),
|
156
|
+
hash[:execution_time].to_f,
|
157
|
+
hash[:real_time].to_f,
|
158
|
+
hash[:progress_done].to_f,
|
159
|
+
hash[:progress_weight].to_f,
|
160
|
+
(hash[:queue] && hash[:queue].to_sym))
|
160
161
|
end
|
161
162
|
|
162
163
|
private
|
163
164
|
|
164
165
|
def with_meta_calculation(action, &block)
|
165
|
-
start
|
166
|
+
start = Time.now.utc
|
166
167
|
@started_at ||= start
|
167
168
|
block.call
|
168
169
|
ensure
|
@@ -186,12 +187,12 @@ module Dynflow
|
|
186
187
|
Dynflow::Telemetry.with_instance do |t|
|
187
188
|
if [:success, :skipped].include?(state)
|
188
189
|
t.observe_histogram(:dynflow_step_real_time,
|
189
|
-
|
190
|
-
|
190
|
+
real_time * 1000,
|
191
|
+
:action => action_class.to_s, :phase => phase.to_s_humanized)
|
191
192
|
end
|
192
193
|
t.observe_histogram(:dynflow_step_execution_time,
|
193
|
-
|
194
|
-
|
194
|
+
current_execution_time * 1000,
|
195
|
+
:action => action_class.to_s, :phase => phase.to_s_humanized)
|
195
196
|
end
|
196
197
|
end
|
197
198
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
module ExecutionPlan::Steps
|
4
5
|
class AbstractFlowStep < Abstract
|
5
|
-
|
6
6
|
# Method called when initializing the step to customize the behavior based on the
|
7
7
|
# action definition during the planning phase
|
8
8
|
def update_from_action(action)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
module ExecutionPlan::Steps
|
4
5
|
class Error < Serializable
|
@@ -11,12 +12,12 @@ module Dynflow
|
|
11
12
|
case args.size
|
12
13
|
when 1
|
13
14
|
match obj = args.first,
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
(on String do
|
16
|
+
super(StandardError, obj, caller, nil)
|
17
|
+
end),
|
18
|
+
(on Exception do
|
19
|
+
super(obj.class, obj.message, obj.backtrace, obj)
|
20
|
+
end)
|
20
21
|
when 3, 4
|
21
22
|
super(*args.values_at(0..3))
|
22
23
|
else
|
@@ -49,9 +50,9 @@ module Dynflow
|
|
49
50
|
|
50
51
|
def to_s
|
51
52
|
format '%s (%s)\n%s',
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
(@exception || self).message,
|
54
|
+
(@exception ? @exception.class : exception_class),
|
55
|
+
(@exception || self).backtrace
|
55
56
|
end
|
56
57
|
|
57
58
|
def exception
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dynflow
|
3
4
|
module ExecutionPlan::Steps
|
4
5
|
class FinalizeStep < AbstractFlowStep
|
5
|
-
|
6
6
|
def self.state_transitions
|
7
7
|
@state_transitions ||= {
|
8
8
|
pending: [:running, :skipped], # :skipped when its run_step is skipped
|
@@ -27,7 +27,6 @@ module Dynflow
|
|
27
27
|
self.state = :skipped
|
28
28
|
self.save
|
29
29
|
end
|
30
|
-
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|