dynflow 1.4.9 → 1.6.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/{test/prepare_travis_env.sh → .github/install_dependencies.sh} +2 -2
- data/.github/workflows/release.yml +48 -0
- data/.github/workflows/ruby.yml +116 -0
- data/Gemfile +1 -1
- data/dynflow.gemspec +1 -0
- data/examples/chunked_output_benchmark.rb +77 -0
- data/extras/expand/Dockerfile +9 -0
- data/extras/expand/README.md +25 -0
- data/extras/expand/go.mod +5 -0
- data/extras/expand/go.sum +11 -0
- data/extras/expand/main.go +66 -0
- data/lib/dynflow/action.rb +11 -1
- data/lib/dynflow/delayed_executors/abstract_core.rb +11 -9
- data/lib/dynflow/director.rb +37 -4
- data/lib/dynflow/dispatcher/client_dispatcher.rb +1 -1
- data/lib/dynflow/dispatcher/executor_dispatcher.rb +8 -0
- data/lib/dynflow/dispatcher.rb +5 -1
- data/lib/dynflow/execution_history.rb +1 -1
- data/lib/dynflow/execution_plan/hooks.rb +1 -1
- data/lib/dynflow/execution_plan/steps/abstract_flow_step.rb +1 -0
- data/lib/dynflow/execution_plan.rb +16 -5
- data/lib/dynflow/executors/abstract/core.rb +9 -0
- data/lib/dynflow/executors/parallel.rb +4 -0
- data/lib/dynflow/extensions/msgpack.rb +41 -0
- data/lib/dynflow/extensions.rb +6 -0
- data/lib/dynflow/flows/abstract.rb +14 -0
- data/lib/dynflow/flows/abstract_composed.rb +2 -7
- data/lib/dynflow/flows/atom.rb +2 -2
- data/lib/dynflow/flows/concurrence.rb +2 -0
- data/lib/dynflow/flows/registry.rb +32 -0
- data/lib/dynflow/flows/sequence.rb +2 -0
- data/lib/dynflow/flows.rb +1 -0
- data/lib/dynflow/persistence.rb +10 -0
- data/lib/dynflow/persistence_adapters/sequel.rb +51 -16
- data/lib/dynflow/persistence_adapters/sequel_migrations/021_create_output_chunks.rb +30 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/022_store_flows_as_msgpack.rb +90 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/023_sqlite_workarounds.rb +19 -0
- data/lib/dynflow/serializable.rb +2 -2
- data/lib/dynflow/testing/dummy_coordinator.rb +10 -0
- data/lib/dynflow/testing/dummy_planned_action.rb +4 -0
- data/lib/dynflow/testing/dummy_world.rb +2 -1
- data/lib/dynflow/testing.rb +1 -0
- data/lib/dynflow/version.rb +1 -1
- data/lib/dynflow/world.rb +12 -0
- data/lib/dynflow.rb +2 -1
- data/test/execution_plan_hooks_test.rb +36 -0
- data/test/extensions_test.rb +42 -0
- data/test/flows_test.rb +44 -0
- data/test/future_execution_test.rb +6 -3
- data/test/persistence_test.rb +2 -2
- data/web/views/flow_step.erb +1 -0
- metadata +42 -5
- data/.travis.yml +0 -33
data/lib/dynflow.rb
CHANGED
@@ -72,11 +72,12 @@ module Dynflow
|
|
72
72
|
require 'dynflow/throttle_limiter'
|
73
73
|
require 'dynflow/telemetry'
|
74
74
|
require 'dynflow/config'
|
75
|
+
require 'dynflow/extensions'
|
75
76
|
|
76
77
|
if defined? ::ActiveJob
|
77
78
|
require 'dynflow/active_job/queue_adapter'
|
78
79
|
|
79
|
-
class Railtie < Rails::Railtie
|
80
|
+
class Railtie < ::Rails::Railtie
|
80
81
|
config.before_initialize do
|
81
82
|
::ActiveJob::QueueAdapters.send(
|
82
83
|
:include,
|
@@ -60,6 +60,18 @@ module Dynflow
|
|
60
60
|
execution_plan_hooks.use :raise_flag_root_only, :on => :stopped
|
61
61
|
end
|
62
62
|
|
63
|
+
class PendingAction < ::Dynflow::Action
|
64
|
+
include FlagHook
|
65
|
+
|
66
|
+
execution_plan_hooks.use :raise_flag, :on => :pending
|
67
|
+
end
|
68
|
+
|
69
|
+
class AllTransitionsAction < ::Dynflow::Action
|
70
|
+
include FlagHook
|
71
|
+
|
72
|
+
execution_plan_hooks.use :raise_flag
|
73
|
+
end
|
74
|
+
|
63
75
|
class ComposedAction < RootOnlyAction
|
64
76
|
def plan
|
65
77
|
plan_action(RootOnlyAction)
|
@@ -161,6 +173,30 @@ module Dynflow
|
|
161
173
|
plan.finished.wait!
|
162
174
|
_(Flag.raised_count).must_equal 1
|
163
175
|
end
|
176
|
+
|
177
|
+
it 'runs the pending hooks when execution plan is created' do
|
178
|
+
refute Flag.raised?
|
179
|
+
plan = world.trigger(PendingAction)
|
180
|
+
plan.finished.wait!
|
181
|
+
_(Flag.raised_count).must_equal 1
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'runs the pending hooks when execution plan is created' do
|
185
|
+
refute Flag.raised?
|
186
|
+
delay = world.delay(PendingAction, { :start_at => Time.now.utc + 180 })
|
187
|
+
delayed_plan = world.persistence.load_delayed_plan(delay.execution_plan_id)
|
188
|
+
delayed_plan.execution_plan.cancel.each(&:wait)
|
189
|
+
_(Flag.raised_count).must_equal 1
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'runs the hook on every state transition' do
|
193
|
+
refute Flag.raised?
|
194
|
+
plan = world.trigger(AllTransitionsAction)
|
195
|
+
plan.finished.wait!
|
196
|
+
# There should be 5 transitions
|
197
|
+
# nothing -> pending -> planning -> planned -> running -> stopped
|
198
|
+
_(Flag.raised_count).must_equal 5
|
199
|
+
end
|
164
200
|
end
|
165
201
|
end
|
166
202
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'test_helper'
|
3
|
+
require 'active_support/time'
|
4
|
+
|
5
|
+
module Dynflow
|
6
|
+
module ExtensionsTest
|
7
|
+
describe 'msgpack extensions' do
|
8
|
+
before do
|
9
|
+
Thread.current[:time_zone] = ActiveSupport::TimeZone['Europe/Prague']
|
10
|
+
end
|
11
|
+
after { Thread.current[:time_zone] = nil }
|
12
|
+
|
13
|
+
it 'allows {de,}serializing Time' do
|
14
|
+
time = Time.now
|
15
|
+
transformed = MessagePack.unpack(time.to_msgpack)
|
16
|
+
assert_equal transformed, time
|
17
|
+
assert_equal transformed.class, time.class
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'allows {de,}serializing ActiveSupport::TimeWithZone' do
|
21
|
+
time = Time.zone.now
|
22
|
+
transformed = MessagePack.unpack(time.to_msgpack)
|
23
|
+
assert_equal transformed, time
|
24
|
+
assert_equal transformed.class, time.class
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'allows {de,}serializing DateTime' do
|
28
|
+
time = DateTime.now
|
29
|
+
transformed = MessagePack.unpack(time.to_msgpack)
|
30
|
+
assert_equal transformed, time
|
31
|
+
assert_equal transformed.class, time.class
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'allows {de,}serializing Date' do
|
35
|
+
date = DateTime.current
|
36
|
+
transformed = MessagePack.unpack(date.to_msgpack)
|
37
|
+
assert_equal transformed, date
|
38
|
+
assert_equal transformed.class, date.class
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/test/flows_test.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'test_helper'
|
3
|
+
require 'mocha/minitest'
|
4
|
+
|
5
|
+
module Dynflow
|
6
|
+
describe 'flow' do
|
7
|
+
|
8
|
+
class TestRegistry < Flows::Registry
|
9
|
+
class << self
|
10
|
+
def reset!
|
11
|
+
@serialization_map = {}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
TestRegistry.reset!
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "registry" do
|
21
|
+
it "allows registering values" do
|
22
|
+
TestRegistry.register!(TestRegistry, 'TS')
|
23
|
+
TestRegistry.register!(Integer, 'I')
|
24
|
+
map = TestRegistry.instance_variable_get("@serialization_map")
|
25
|
+
_(map).must_equal({'TS' => TestRegistry, 'I' => Integer})
|
26
|
+
end
|
27
|
+
|
28
|
+
it "prevents overwriting values" do
|
29
|
+
TestRegistry.register!(Integer, 'I')
|
30
|
+
_(-> { TestRegistry.register!(Float, 'I') }).must_raise Flows::Registry::IdentifierTaken
|
31
|
+
end
|
32
|
+
|
33
|
+
it "encodes and decodes values" do
|
34
|
+
TestRegistry.register!(Integer, 'I')
|
35
|
+
_(TestRegistry.encode(Integer)).must_equal 'I'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raises an exception when unknown key is requested" do
|
39
|
+
_(-> { TestRegistry.encode(Float) }).must_raise Flows::Registry::UnknownIdentifier
|
40
|
+
_(-> { TestRegistry.decode('F') }).must_raise Flows::Registry::UnknownIdentifier
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -29,14 +29,17 @@ module Dynflow
|
|
29
29
|
describe 'abstract executor' do
|
30
30
|
let(:abstract_delayed_executor) { DelayedExecutors::AbstractCore.new(world) }
|
31
31
|
|
32
|
-
it 'handles
|
32
|
+
it 'handles plan in planning state' do
|
33
33
|
delayed_plan.execution_plan.state = :planning
|
34
34
|
abstract_delayed_executor.send(:process, [delayed_plan], @start_at)
|
35
|
-
_(delayed_plan.execution_plan.state).must_equal :
|
35
|
+
_(delayed_plan.execution_plan.state).must_equal :scheduled
|
36
|
+
end
|
36
37
|
|
38
|
+
it 'handles plan in running state' do
|
37
39
|
delayed_plan.execution_plan.set_state(:running, true)
|
38
40
|
abstract_delayed_executor.send(:process, [delayed_plan], @start_at)
|
39
41
|
_(delayed_plan.execution_plan.state).must_equal :running
|
42
|
+
_(world.persistence.load_delayed_plan(delayed_plan.execution_plan_uuid)).must_be :nil?
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
@@ -55,7 +58,7 @@ module Dynflow
|
|
55
58
|
|
56
59
|
it 'delays the action' do
|
57
60
|
_(execution_plan.steps.count).must_equal 1
|
58
|
-
_(delayed_plan.start_at.
|
61
|
+
_(delayed_plan.start_at.to_i).must_equal(@start_at.to_i)
|
59
62
|
_(history_names.call(execution_plan)).must_equal ['delay']
|
60
63
|
end
|
61
64
|
|
data/test/persistence_test.rb
CHANGED
@@ -86,7 +86,7 @@ module Dynflow
|
|
86
86
|
original.each do |key, value|
|
87
87
|
loaded_value = loaded[key.to_s]
|
88
88
|
if value.is_a?(Time)
|
89
|
-
_(loaded_value
|
89
|
+
_(loaded_value).must_be_within_delta(value, 0.5)
|
90
90
|
elsif value.is_a?(Hash)
|
91
91
|
assert_equal_attributes!(value, loaded_value)
|
92
92
|
elsif value.nil?
|
@@ -348,7 +348,7 @@ module Dynflow
|
|
348
348
|
if value.nil?
|
349
349
|
assert_nil stored.fetch(name.to_sym)
|
350
350
|
elsif value.is_a?(Time)
|
351
|
-
_(stored.fetch(name.to_sym)
|
351
|
+
_(stored.fetch(name.to_sym)).must_be_within_delta(value, 0.5)
|
352
352
|
else
|
353
353
|
_(stored.fetch(name.to_sym)).must_equal value
|
354
354
|
end
|
data/web/views/flow_step.erb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Necas
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-01-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
@@ -25,6 +25,26 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: msgpack
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.3'
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.3.3
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - "~>"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '1.3'
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.3.3
|
28
48
|
- !ruby/object:Gem::Dependency
|
29
49
|
name: apipie-params
|
30
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -242,10 +262,12 @@ executables: []
|
|
242
262
|
extensions: []
|
243
263
|
extra_rdoc_files: []
|
244
264
|
files:
|
265
|
+
- ".github/install_dependencies.sh"
|
266
|
+
- ".github/workflows/release.yml"
|
267
|
+
- ".github/workflows/ruby.yml"
|
245
268
|
- ".gitignore"
|
246
269
|
- ".rubocop.yml"
|
247
270
|
- ".rubocop_todo.yml"
|
248
|
-
- ".travis.yml"
|
249
271
|
- Dockerfile
|
250
272
|
- Gemfile
|
251
273
|
- MIT-LICENSE
|
@@ -386,6 +408,7 @@ files:
|
|
386
408
|
- doc/pages/source/projects/index.md
|
387
409
|
- docker-compose.yml
|
388
410
|
- dynflow.gemspec
|
411
|
+
- examples/chunked_output_benchmark.rb
|
389
412
|
- examples/clock_benchmark.rb
|
390
413
|
- examples/example_helper.rb
|
391
414
|
- examples/future_execution.rb
|
@@ -397,6 +420,11 @@ files:
|
|
397
420
|
- examples/sub_plan_concurrency_control.rb
|
398
421
|
- examples/sub_plans.rb
|
399
422
|
- examples/termination.rb
|
423
|
+
- extras/expand/Dockerfile
|
424
|
+
- extras/expand/README.md
|
425
|
+
- extras/expand/go.mod
|
426
|
+
- extras/expand/go.sum
|
427
|
+
- extras/expand/main.go
|
400
428
|
- extras/statsd_mapping.conf
|
401
429
|
- lib/dynflow.rb
|
402
430
|
- lib/dynflow/action.rb
|
@@ -469,11 +497,14 @@ files:
|
|
469
497
|
- lib/dynflow/executors/sidekiq/redis_locking.rb
|
470
498
|
- lib/dynflow/executors/sidekiq/serialization.rb
|
471
499
|
- lib/dynflow/executors/sidekiq/worker_jobs.rb
|
500
|
+
- lib/dynflow/extensions.rb
|
501
|
+
- lib/dynflow/extensions/msgpack.rb
|
472
502
|
- lib/dynflow/flows.rb
|
473
503
|
- lib/dynflow/flows/abstract.rb
|
474
504
|
- lib/dynflow/flows/abstract_composed.rb
|
475
505
|
- lib/dynflow/flows/atom.rb
|
476
506
|
- lib/dynflow/flows/concurrence.rb
|
507
|
+
- lib/dynflow/flows/registry.rb
|
477
508
|
- lib/dynflow/flows/sequence.rb
|
478
509
|
- lib/dynflow/logger_adapters.rb
|
479
510
|
- lib/dynflow/logger_adapters/abstract.rb
|
@@ -513,6 +544,9 @@ files:
|
|
513
544
|
- lib/dynflow/persistence_adapters/sequel_migrations/018_add_uuid_column.rb
|
514
545
|
- lib/dynflow/persistence_adapters/sequel_migrations/019_update_mysql_time_precision.rb
|
515
546
|
- lib/dynflow/persistence_adapters/sequel_migrations/020_drop_duplicate_indices.rb
|
547
|
+
- lib/dynflow/persistence_adapters/sequel_migrations/021_create_output_chunks.rb
|
548
|
+
- lib/dynflow/persistence_adapters/sequel_migrations/022_store_flows_as_msgpack.rb
|
549
|
+
- lib/dynflow/persistence_adapters/sequel_migrations/023_sqlite_workarounds.rb
|
516
550
|
- lib/dynflow/rails.rb
|
517
551
|
- lib/dynflow/rails/configuration.rb
|
518
552
|
- lib/dynflow/rails/daemon.rb
|
@@ -534,6 +568,7 @@ files:
|
|
534
568
|
- lib/dynflow/telemetry_adapters/statsd.rb
|
535
569
|
- lib/dynflow/testing.rb
|
536
570
|
- lib/dynflow/testing/assertions.rb
|
571
|
+
- lib/dynflow/testing/dummy_coordinator.rb
|
537
572
|
- lib/dynflow/testing/dummy_execution_plan.rb
|
538
573
|
- lib/dynflow/testing/dummy_executor.rb
|
539
574
|
- lib/dynflow/testing/dummy_planned_action.rb
|
@@ -576,11 +611,12 @@ files:
|
|
576
611
|
- test/execution_plan_hooks_test.rb
|
577
612
|
- test/execution_plan_test.rb
|
578
613
|
- test/executor_test.rb
|
614
|
+
- test/extensions_test.rb
|
615
|
+
- test/flows_test.rb
|
579
616
|
- test/future_execution_test.rb
|
580
617
|
- test/memory_cosumption_watcher_test.rb
|
581
618
|
- test/middleware_test.rb
|
582
619
|
- test/persistence_test.rb
|
583
|
-
- test/prepare_travis_env.sh
|
584
620
|
- test/redis_locking_test.rb
|
585
621
|
- test/rescue_test.rb
|
586
622
|
- test/round_robin_test.rb
|
@@ -659,11 +695,12 @@ test_files:
|
|
659
695
|
- test/execution_plan_hooks_test.rb
|
660
696
|
- test/execution_plan_test.rb
|
661
697
|
- test/executor_test.rb
|
698
|
+
- test/extensions_test.rb
|
699
|
+
- test/flows_test.rb
|
662
700
|
- test/future_execution_test.rb
|
663
701
|
- test/memory_cosumption_watcher_test.rb
|
664
702
|
- test/middleware_test.rb
|
665
703
|
- test/persistence_test.rb
|
666
|
-
- test/prepare_travis_env.sh
|
667
704
|
- test/redis_locking_test.rb
|
668
705
|
- test/rescue_test.rb
|
669
706
|
- test/round_robin_test.rb
|
data/.travis.yml
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
services:
|
4
|
-
- postgresql
|
5
|
-
- redis
|
6
|
-
|
7
|
-
rvm:
|
8
|
-
- "2.3.1"
|
9
|
-
- "2.4.0"
|
10
|
-
- "2.5.0"
|
11
|
-
|
12
|
-
env:
|
13
|
-
global:
|
14
|
-
- "TESTOPTS=--verbose DB=postgresql DB_CONN_STRING=postgres://postgres@localhost/travis_ci_test"
|
15
|
-
|
16
|
-
matrix:
|
17
|
-
include:
|
18
|
-
- rvm: "2.4.0"
|
19
|
-
env: "DB=mysql DB_CONN_STRING=mysql2://root@localhost/travis_ci_test"
|
20
|
-
services:
|
21
|
-
- mysql
|
22
|
-
- redis
|
23
|
-
- rvm: "2.4.0"
|
24
|
-
env: "DB=sqlite3 DB_CONN_STRING=sqlite:/"
|
25
|
-
- rvm: "2.4.0"
|
26
|
-
env: "CONCURRENT_RUBY_EXT=true"
|
27
|
-
|
28
|
-
install:
|
29
|
-
- test/prepare_travis_env.sh
|
30
|
-
|
31
|
-
script:
|
32
|
-
- bundle exec rubocop
|
33
|
-
- bundle exec rake test
|