dynflow 1.9.3 → 2.0.1
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/bats.yml +50 -0
- data/.github/workflows/release-rubygems.yml +20 -0
- data/.github/workflows/release.yml +1 -1
- data/.github/workflows/ruby.yml +27 -46
- data/.gitignore +2 -0
- data/.rubocop.yml +3 -0
- data/Dockerfile +1 -1
- data/Gemfile +7 -8
- data/README.md +4 -4
- data/doc/pages/source/documentation/index.md +4 -4
- data/dynflow.gemspec +2 -3
- data/examples/example_helper.rb +1 -1
- data/examples/execution_plan_chaining.rb +56 -0
- data/examples/remote_executor.rb +5 -8
- data/extras/expand/go.mod +3 -1
- data/extras/expand/go.sum +4 -1
- data/lib/dynflow/action/format.rb +4 -33
- data/lib/dynflow/debug/telemetry/persistence.rb +1 -1
- data/lib/dynflow/delayed_executors/abstract_core.rb +1 -1
- data/lib/dynflow/delayed_plan.rb +6 -0
- data/lib/dynflow/director.rb +9 -1
- data/lib/dynflow/executors/sidekiq/core.rb +1 -1
- data/lib/dynflow/executors/sidekiq/redis_locking.rb +10 -3
- data/lib/dynflow/extensions/msgpack.rb +4 -0
- data/lib/dynflow/persistence.rb +14 -2
- data/lib/dynflow/persistence_adapters/abstract.rb +9 -1
- data/lib/dynflow/persistence_adapters/sequel.rb +91 -48
- data/lib/dynflow/persistence_adapters/sequel_migrations/025_create_execution_plan_dependencies.rb +22 -0
- data/lib/dynflow/rails/configuration.rb +19 -13
- data/lib/dynflow/rails/daemon.rb +16 -7
- data/lib/dynflow/testing.rb +1 -1
- data/lib/dynflow/version.rb +1 -1
- data/lib/dynflow/world.rb +34 -13
- data/lib/dynflow.rb +0 -1
- data/test/action_test.rb +3 -3
- data/test/bats/helpers/common.bash +67 -0
- data/test/bats/helpers/containers.bash +146 -0
- data/test/bats/setup_suite.bash +46 -0
- data/test/bats/sidekiq-orchestrator.bats +178 -0
- data/test/bats/teardown_suite.bash +16 -0
- data/test/concurrency_control_test.rb +0 -1
- data/test/daemon_test.rb +21 -2
- data/test/extensions_test.rb +3 -3
- data/test/future_execution_test.rb +150 -3
- data/test/persistence_test.rb +70 -3
- data/test/support/dummy_example.rb +4 -0
- data/test/test_helper.rb +19 -4
- data/web/views/show.erb +24 -0
- metadata +14 -56
- data/.github/install_dependencies.sh +0 -35
data/test/persistence_test.rb
CHANGED
|
@@ -342,7 +342,7 @@ module Dynflow
|
|
|
342
342
|
end
|
|
343
343
|
end
|
|
344
344
|
|
|
345
|
-
describe '#
|
|
345
|
+
describe '#find_ready_delayed_plans' do
|
|
346
346
|
it 'finds plans with start_before in past' do
|
|
347
347
|
start_time = Time.now.utc
|
|
348
348
|
prepare_and_save_plans
|
|
@@ -352,7 +352,7 @@ module Dynflow
|
|
|
352
352
|
adapter.save_delayed_plan('plan3', :execution_plan_uuid => 'plan3', :frozen => false, :start_at => format_time(start_time + 60))
|
|
353
353
|
adapter.save_delayed_plan('plan4', :execution_plan_uuid => 'plan4', :frozen => false, :start_at => format_time(start_time - 60),
|
|
354
354
|
:start_before => format_time(start_time - 60))
|
|
355
|
-
plans = adapter.
|
|
355
|
+
plans = adapter.find_ready_delayed_plans(start_time)
|
|
356
356
|
_(plans.length).must_equal 3
|
|
357
357
|
_(plans.map { |plan| plan[:execution_plan_uuid] }).must_equal %w(plan2 plan4 plan1)
|
|
358
358
|
end
|
|
@@ -366,10 +366,77 @@ module Dynflow
|
|
|
366
366
|
adapter.save_delayed_plan('plan2', :execution_plan_uuid => 'plan2', :frozen => true, :start_at => format_time(start_time + 60),
|
|
367
367
|
:start_before => format_time(start_time - 60))
|
|
368
368
|
|
|
369
|
-
plans = adapter.
|
|
369
|
+
plans = adapter.find_ready_delayed_plans(start_time)
|
|
370
370
|
_(plans.length).must_equal 1
|
|
371
371
|
_(plans.first[:execution_plan_uuid]).must_equal 'plan1'
|
|
372
372
|
end
|
|
373
|
+
|
|
374
|
+
it 'finds plans with null start_at' do
|
|
375
|
+
start_time = Time.now.utc
|
|
376
|
+
prepare_and_save_plans
|
|
377
|
+
|
|
378
|
+
adapter.save_delayed_plan('plan1', :execution_plan_uuid => 'plan1', :frozen => false)
|
|
379
|
+
|
|
380
|
+
plans = adapter.find_ready_delayed_plans(start_time)
|
|
381
|
+
_(plans.length).must_equal 1
|
|
382
|
+
_(plans.first[:execution_plan_uuid]).must_equal 'plan1'
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
it 'properly stored execution plan dependencies' do
|
|
386
|
+
prepare_and_save_plans
|
|
387
|
+
|
|
388
|
+
adapter.save_delayed_plan('plan1', :execution_plan_uuid => 'plan1', :frozen => false)
|
|
389
|
+
adapter.chain_execution_plan('plan2', 'plan1')
|
|
390
|
+
adapter.chain_execution_plan('plan3', 'plan1')
|
|
391
|
+
dependencies = adapter.find_execution_plan_dependencies('plan1')
|
|
392
|
+
_(dependencies.to_set).must_equal ['plan2', 'plan3'].to_set
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
it 'does not find blocked plans' do
|
|
396
|
+
start_time = Time.now.utc
|
|
397
|
+
prepare_and_save_plans
|
|
398
|
+
|
|
399
|
+
adapter.save_delayed_plan('plan1', :execution_plan_uuid => 'plan1', :frozen => false)
|
|
400
|
+
adapter.chain_execution_plan('plan2', 'plan1')
|
|
401
|
+
adapter.chain_execution_plan('plan3', 'plan1')
|
|
402
|
+
|
|
403
|
+
plans = adapter.find_ready_delayed_plans(start_time)
|
|
404
|
+
_(plans.length).must_equal 0
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
it 'finds plans which are no longer blocked' do
|
|
408
|
+
start_time = Time.now.utc
|
|
409
|
+
prepare_and_save_plans
|
|
410
|
+
|
|
411
|
+
adapter.save_delayed_plan('plan1', :execution_plan_uuid => 'plan1', :frozen => false)
|
|
412
|
+
adapter.chain_execution_plan('plan2', 'plan1')
|
|
413
|
+
|
|
414
|
+
plans = adapter.find_ready_delayed_plans(start_time)
|
|
415
|
+
_(plans.length).must_equal 1
|
|
416
|
+
_(plans.first[:execution_plan_uuid]).must_equal 'plan1'
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it 'does not find plans which are no longer blocked but are frozen' do
|
|
420
|
+
start_time = Time.now.utc
|
|
421
|
+
prepare_and_save_plans
|
|
422
|
+
|
|
423
|
+
adapter.save_delayed_plan('plan1', :execution_plan_uuid => 'plan1', :frozen => true)
|
|
424
|
+
adapter.chain_execution_plan('plan2', 'plan1')
|
|
425
|
+
|
|
426
|
+
plans = adapter.find_ready_delayed_plans(start_time)
|
|
427
|
+
_(plans.length).must_equal 0
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
it 'does not find plans which are no longer blocked but their start_at is in the future' do
|
|
431
|
+
start_time = Time.now.utc
|
|
432
|
+
prepare_and_save_plans
|
|
433
|
+
|
|
434
|
+
adapter.save_delayed_plan('plan1', :execution_plan_uuid => 'plan1', :frozen => false, :start_at => start_time + 60)
|
|
435
|
+
adapter.chain_execution_plan('plan2', 'plan1') # plan2 is already stopped
|
|
436
|
+
|
|
437
|
+
plans = adapter.find_ready_delayed_plans(start_time)
|
|
438
|
+
_(plans.length).must_equal 0
|
|
439
|
+
end
|
|
373
440
|
end
|
|
374
441
|
|
|
375
442
|
describe '#delete_output_chunks' do
|
data/test/test_helper.rb
CHANGED
|
@@ -20,7 +20,9 @@ require 'support/rescue_example'
|
|
|
20
20
|
require 'support/dummy_example'
|
|
21
21
|
require 'support/test_execution_log'
|
|
22
22
|
|
|
23
|
-
Concurrent.
|
|
23
|
+
Concurrent.global_logger = lambda do |level, progname, message = nil, &block|
|
|
24
|
+
::Dynflow::Testing.logger_adapter.logger.add level, message, progname, &block
|
|
25
|
+
end
|
|
24
26
|
|
|
25
27
|
# To be able to stop a process in some step and perform assertions while paused
|
|
26
28
|
class TestPause
|
|
@@ -109,12 +111,19 @@ module WorldFactory
|
|
|
109
111
|
# This world survives though the whole run of the test suite: careful with it, it can
|
|
110
112
|
# introduce unnecessary test dependencies
|
|
111
113
|
def self.logger_adapter
|
|
112
|
-
|
|
114
|
+
::Dynflow::Testing.logger_adapter
|
|
113
115
|
end
|
|
114
116
|
|
|
115
117
|
def self.persistence_adapter
|
|
116
118
|
@persistence_adapter ||= begin
|
|
117
|
-
db_config = ENV
|
|
119
|
+
db_config = ENV.fetch('DB_CONN_STRING') do
|
|
120
|
+
case ENV['DB']
|
|
121
|
+
when 'postgresql'
|
|
122
|
+
"postgres://postgres@localhost/#{ENV.fetch('POSTGRES_DB', 'ci_test')}"
|
|
123
|
+
else
|
|
124
|
+
'sqlite:/'
|
|
125
|
+
end
|
|
126
|
+
end
|
|
118
127
|
puts "Using database configuration: #{db_config}"
|
|
119
128
|
Dynflow::PersistenceAdapters::Sequel.new(db_config)
|
|
120
129
|
end
|
|
@@ -127,7 +136,7 @@ module WorldFactory
|
|
|
127
136
|
def self.clean_coordinator_records
|
|
128
137
|
persistence_adapter = WorldFactory.persistence_adapter
|
|
129
138
|
persistence_adapter.find_coordinator_records({}).each do |w|
|
|
130
|
-
warn "Unexpected coordinator record: #{w}"
|
|
139
|
+
::Dynflow::Testing.logger_adapter.logger.warn "Unexpected coordinator record: #{w}"
|
|
131
140
|
persistence_adapter.delete_coordinator_record(w[:class], w[:id])
|
|
132
141
|
end
|
|
133
142
|
end
|
|
@@ -234,12 +243,18 @@ module TestHelpers
|
|
|
234
243
|
end
|
|
235
244
|
|
|
236
245
|
class MiniTest::Test
|
|
246
|
+
def logger
|
|
247
|
+
::Dynflow::Testing.logger_adapter.logger
|
|
248
|
+
end
|
|
249
|
+
|
|
237
250
|
def setup
|
|
251
|
+
logger.info(">>>>> #{location}")
|
|
238
252
|
WorldFactory.clean_coordinator_records
|
|
239
253
|
end
|
|
240
254
|
|
|
241
255
|
def teardown
|
|
242
256
|
WorldFactory.terminate_worlds
|
|
257
|
+
logger.info("<<<<< #{location}")
|
|
243
258
|
end
|
|
244
259
|
end
|
|
245
260
|
|
data/web/views/show.erb
CHANGED
|
@@ -43,6 +43,30 @@
|
|
|
43
43
|
<%= h(@plan.ended_at) %>
|
|
44
44
|
</p>
|
|
45
45
|
|
|
46
|
+
<% dependencies = @plan.world.persistence.find_execution_plan_dependencies(@plan.id) %>
|
|
47
|
+
<% if dependencies.any? %>
|
|
48
|
+
<p>
|
|
49
|
+
<b>Depends on execution plans:</b>
|
|
50
|
+
<ul>
|
|
51
|
+
<% dependencies.each do |dep_id| %>
|
|
52
|
+
<li><a href="<%= url("/#{dep_id}") %>"><%= h(dep_id) %></a></li>
|
|
53
|
+
<% end %>
|
|
54
|
+
</ul>
|
|
55
|
+
</p>
|
|
56
|
+
<% end %>
|
|
57
|
+
|
|
58
|
+
<% blocked_plans = @plan.world.persistence.find_blocked_execution_plans(@plan.id) %>
|
|
59
|
+
<% if blocked_plans.any? %>
|
|
60
|
+
<p>
|
|
61
|
+
<b>Blocks execution plans:</b>
|
|
62
|
+
<ul>
|
|
63
|
+
<% blocked_plans.each do |dep_id| %>
|
|
64
|
+
<li><a href="<%= url("/#{dep_id}") %>"><%= h(dep_id) %></a></li>
|
|
65
|
+
<% end %>
|
|
66
|
+
</ul>
|
|
67
|
+
</p>
|
|
68
|
+
<% end %>
|
|
69
|
+
|
|
46
70
|
<ul class="phases nav nav-tabs" id="myTab">
|
|
47
71
|
<li><a href="#plan">Plan</a></li>
|
|
48
72
|
<li class="active"><a href="#run">Run</a></li>
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dynflow
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ivan Necas
|
|
8
8
|
- Petr Chalupa
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 1980-01-
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: algebrick
|
|
@@ -24,20 +24,6 @@ dependencies:
|
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 0.7.0
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: apipie-params
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :runtime
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
27
|
- !ruby/object:Gem::Dependency
|
|
42
28
|
name: concurrent-ruby
|
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -331,7 +317,8 @@ executables: []
|
|
|
331
317
|
extensions: []
|
|
332
318
|
extra_rdoc_files: []
|
|
333
319
|
files:
|
|
334
|
-
- ".github/
|
|
320
|
+
- ".github/workflows/bats.yml"
|
|
321
|
+
- ".github/workflows/release-rubygems.yml"
|
|
335
322
|
- ".github/workflows/release.yml"
|
|
336
323
|
- ".github/workflows/ruby.yml"
|
|
337
324
|
- ".gitignore"
|
|
@@ -480,6 +467,7 @@ files:
|
|
|
480
467
|
- examples/chunked_output_benchmark.rb
|
|
481
468
|
- examples/clock_benchmark.rb
|
|
482
469
|
- examples/example_helper.rb
|
|
470
|
+
- examples/execution_plan_chaining.rb
|
|
483
471
|
- examples/future_execution.rb
|
|
484
472
|
- examples/halt.rb
|
|
485
473
|
- examples/memory_limit_watcher.rb
|
|
@@ -621,6 +609,7 @@ files:
|
|
|
621
609
|
- lib/dynflow/persistence_adapters/sequel_migrations/022_store_flows_as_msgpack.rb
|
|
622
610
|
- lib/dynflow/persistence_adapters/sequel_migrations/023_sqlite_workarounds.rb
|
|
623
611
|
- lib/dynflow/persistence_adapters/sequel_migrations/024_store_execution_plan_data_as_msgpack.rb
|
|
612
|
+
- lib/dynflow/persistence_adapters/sequel_migrations/025_create_execution_plan_dependencies.rb
|
|
624
613
|
- lib/dynflow/persistence_adapters/sequel_migrations/msgpack_migration_helper.rb
|
|
625
614
|
- lib/dynflow/rails.rb
|
|
626
615
|
- lib/dynflow/rails/configuration.rb
|
|
@@ -676,6 +665,11 @@ files:
|
|
|
676
665
|
- test/action_test.rb
|
|
677
666
|
- test/activejob_adapter_test.rb
|
|
678
667
|
- test/batch_sub_tasks_test.rb
|
|
668
|
+
- test/bats/helpers/common.bash
|
|
669
|
+
- test/bats/helpers/containers.bash
|
|
670
|
+
- test/bats/setup_suite.bash
|
|
671
|
+
- test/bats/sidekiq-orchestrator.bats
|
|
672
|
+
- test/bats/teardown_suite.bash
|
|
679
673
|
- test/clock_test.rb
|
|
680
674
|
- test/concurrency_control_test.rb
|
|
681
675
|
- test/coordinator_test.rb
|
|
@@ -744,50 +738,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
744
738
|
requirements:
|
|
745
739
|
- - ">="
|
|
746
740
|
- !ruby/object:Gem::Version
|
|
747
|
-
version:
|
|
741
|
+
version: 3.0.0
|
|
748
742
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
749
743
|
requirements:
|
|
750
744
|
- - ">="
|
|
751
745
|
- !ruby/object:Gem::Version
|
|
752
746
|
version: '0'
|
|
753
747
|
requirements: []
|
|
754
|
-
rubygems_version:
|
|
748
|
+
rubygems_version: 4.0.6
|
|
755
749
|
specification_version: 4
|
|
756
750
|
summary: DYNamic workFLOW engine
|
|
757
|
-
test_files:
|
|
758
|
-
- test/abnormal_states_recovery_test.rb
|
|
759
|
-
- test/action_test.rb
|
|
760
|
-
- test/activejob_adapter_test.rb
|
|
761
|
-
- test/batch_sub_tasks_test.rb
|
|
762
|
-
- test/clock_test.rb
|
|
763
|
-
- test/concurrency_control_test.rb
|
|
764
|
-
- test/coordinator_test.rb
|
|
765
|
-
- test/daemon_test.rb
|
|
766
|
-
- test/dead_letter_silencer_test.rb
|
|
767
|
-
- test/dispatcher_test.rb
|
|
768
|
-
- test/execution_plan_cleaner_test.rb
|
|
769
|
-
- test/execution_plan_hooks_test.rb
|
|
770
|
-
- test/execution_plan_test.rb
|
|
771
|
-
- test/executor_test.rb
|
|
772
|
-
- test/extensions_test.rb
|
|
773
|
-
- test/flows_test.rb
|
|
774
|
-
- test/future_execution_test.rb
|
|
775
|
-
- test/memory_cosumption_watcher_test.rb
|
|
776
|
-
- test/middleware_test.rb
|
|
777
|
-
- test/persistence_test.rb
|
|
778
|
-
- test/redis_locking_test.rb
|
|
779
|
-
- test/rescue_test.rb
|
|
780
|
-
- test/round_robin_test.rb
|
|
781
|
-
- test/semaphores_test.rb
|
|
782
|
-
- test/support/code_workflow_example.rb
|
|
783
|
-
- test/support/dummy_example.rb
|
|
784
|
-
- test/support/middleware_example.rb
|
|
785
|
-
- test/support/rails/config/environment.rb
|
|
786
|
-
- test/support/rescue_example.rb
|
|
787
|
-
- test/support/test_execution_log.rb
|
|
788
|
-
- test/test_helper.rb
|
|
789
|
-
- test/testing_test.rb
|
|
790
|
-
- test/utils_test.rb
|
|
791
|
-
- test/v2_sub_plans_test.rb
|
|
792
|
-
- test/web_console_test.rb
|
|
793
|
-
- test/world_test.rb
|
|
751
|
+
test_files: []
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
set -x
|
|
4
|
-
|
|
5
|
-
echo "Setting the environment to use ${DB} database"
|
|
6
|
-
|
|
7
|
-
BUNDLE_CONFIG=.bundle/config
|
|
8
|
-
mkdir -p $(dirname $BUNDLE_CONFIG)
|
|
9
|
-
cat <<EOF > $BUNDLE_CONFIG
|
|
10
|
-
---
|
|
11
|
-
BUNDLE_WITHOUT: pry:mysql:postgresql:concurrent_ruby_ext
|
|
12
|
-
EOF
|
|
13
|
-
|
|
14
|
-
case $DB in
|
|
15
|
-
mysql)
|
|
16
|
-
sed -i 's/:mysql//'g $BUNDLE_CONFIG
|
|
17
|
-
;;
|
|
18
|
-
postgresql)
|
|
19
|
-
sed -i 's/:postgresql//'g $BUNDLE_CONFIG
|
|
20
|
-
;;
|
|
21
|
-
sqlite3)
|
|
22
|
-
# the tests are by default using sqlite3: do nothing
|
|
23
|
-
;;
|
|
24
|
-
*)
|
|
25
|
-
echo "Unsupported database ${DB}"
|
|
26
|
-
exit 1
|
|
27
|
-
;;
|
|
28
|
-
esac
|
|
29
|
-
|
|
30
|
-
if [ "$CONCURRENT_RUBY_EXT" = "true" ]; then
|
|
31
|
-
echo "Enabling concurrent-ruby-ext"
|
|
32
|
-
sed -i 's/:concurrent_ruby_ext//'g $BUNDLE_CONFIG
|
|
33
|
-
fi
|
|
34
|
-
gem update bundler
|
|
35
|
-
bundle install
|