dynflow 1.6.11 → 1.7.0
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 +7 -15
- data/lib/dynflow/action.rb +6 -0
- data/lib/dynflow/persistence.rb +8 -0
- data/lib/dynflow/persistence_adapters/abstract.rb +16 -0
- data/lib/dynflow/persistence_adapters/sequel.rb +14 -0
- data/lib/dynflow/version.rb +1 -1
- data/test/action_test.rb +43 -0
- data/test/persistence_test.rb +54 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1fd4cb9db86befb0bfc96cd5c98f2ca9aa0f6f40249712cbbb8b250b9b9a142
|
4
|
+
data.tar.gz: 218d8a4ce5ec717f24ca4d5d730a5c0620f65ab00e6a35e0595a18876f4b9a31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80b8644418108a107c2a73481fb793647ac6ce40f9789b4efa064970bd6cccd54579ce95ff0b5a4710f033e4defaa7d0fd50ec96d9c51e91666adcd875cc9cc4
|
7
|
+
data.tar.gz: 6a28661cdfeff6555c970df957f10f28d4c23baf977b1212cf3253bac973cef967b1c40be7b77dbaa3fe6811e484be319a04417a0895dd81a32edd534ce58975
|
data/.github/workflows/ruby.yml
CHANGED
@@ -35,10 +35,9 @@ jobs:
|
|
35
35
|
fail-fast: false
|
36
36
|
matrix:
|
37
37
|
ruby_version:
|
38
|
-
- 2.5.0
|
39
|
-
- 2.6.0
|
40
38
|
- 2.7.0
|
41
39
|
- 3.0.0
|
40
|
+
- 3.2.0
|
42
41
|
concurrent_ruby_ext:
|
43
42
|
- 'true'
|
44
43
|
- 'false'
|
@@ -54,30 +53,23 @@ jobs:
|
|
54
53
|
- db: sqlite3
|
55
54
|
conn_string: sqlite:/
|
56
55
|
exclude:
|
57
|
-
- db: mysql
|
58
|
-
ruby_version: 2.5.0
|
59
|
-
- db: mysql
|
60
|
-
ruby_version: 2.6.0
|
61
56
|
- db: mysql
|
62
57
|
ruby_version: 3.0.0
|
58
|
+
- db: mysql
|
59
|
+
ruby_version: 3.2.0
|
63
60
|
- db: mysql
|
64
61
|
concurrent_ruby_ext: 'true'
|
65
|
-
- db: sqlite3
|
66
|
-
ruby_version: 2.5.0
|
67
|
-
- db: sqlite3
|
68
|
-
ruby_version: 2.6.0
|
69
62
|
- db: sqlite3
|
70
63
|
ruby_version: 3.0.0
|
64
|
+
- db: sqlite3
|
65
|
+
ruby_version: 3.2.0
|
71
66
|
- db: sqlite3
|
72
67
|
concurrent_ruby_ext: 'true'
|
73
68
|
- db: postgresql
|
74
|
-
ruby_version:
|
75
|
-
concurrent_ruby_ext: 'true'
|
76
|
-
- db: postgresql
|
77
|
-
ruby_version: 2.6.0
|
69
|
+
ruby_version: 3.0.0
|
78
70
|
concurrent_ruby_ext: 'true'
|
79
71
|
- db: postgresql
|
80
|
-
ruby_version: 3.
|
72
|
+
ruby_version: 3.2.0
|
81
73
|
concurrent_ruby_ext: 'true'
|
82
74
|
|
83
75
|
services:
|
data/lib/dynflow/action.rb
CHANGED
@@ -179,6 +179,12 @@ module Dynflow
|
|
179
179
|
@output_chunks ||= world.persistence.load_output_chunks(@execution_plan_id, @id)
|
180
180
|
end
|
181
181
|
|
182
|
+
def drop_output_chunks!
|
183
|
+
@pending_output_chunks = []
|
184
|
+
@output_chunks = []
|
185
|
+
world.persistence.delete_output_chunks(@execution_plan_id, @id)
|
186
|
+
end
|
187
|
+
|
182
188
|
def caller_action
|
183
189
|
phase! Present
|
184
190
|
return nil if @caller_action_id
|
data/lib/dynflow/persistence.rb
CHANGED
@@ -56,12 +56,20 @@ module Dynflow
|
|
56
56
|
adapter.load_output_chunks(execution_plan_id, action_id)
|
57
57
|
end
|
58
58
|
|
59
|
+
def delete_output_chunks(execution_plan_id, action_id)
|
60
|
+
adapter.delete_output_chunks(execution_plan_id, action_id)
|
61
|
+
end
|
62
|
+
|
59
63
|
def find_execution_plans(options)
|
60
64
|
adapter.find_execution_plans(options).map do |execution_plan_hash|
|
61
65
|
ExecutionPlan.new_from_hash(execution_plan_hash, @world)
|
62
66
|
end
|
63
67
|
end
|
64
68
|
|
69
|
+
def find_execution_plan_statuses(options)
|
70
|
+
adapter.find_execution_plan_statuses(options)
|
71
|
+
end
|
72
|
+
|
65
73
|
def find_execution_plan_counts(options)
|
66
74
|
adapter.find_execution_plan_counts(options)
|
67
75
|
end
|
@@ -46,6 +46,10 @@ module Dynflow
|
|
46
46
|
filter(:execution_plan, options[:filters]).count
|
47
47
|
end
|
48
48
|
|
49
|
+
def find_execution_plan_statuses(options)
|
50
|
+
raise NotImplementedError
|
51
|
+
end
|
52
|
+
|
49
53
|
# @param filters [Hash{ String => Object }] filters to determine
|
50
54
|
# what to delete
|
51
55
|
# @param batch_size the size of the chunks to iterate over when
|
@@ -104,6 +108,18 @@ module Dynflow
|
|
104
108
|
raise NotImplementedError
|
105
109
|
end
|
106
110
|
|
111
|
+
def save_output_chunks(execution_plan_id, action_id, chunks)
|
112
|
+
raise NotImplementedError
|
113
|
+
end
|
114
|
+
|
115
|
+
def load_output_chunks(execution_plan_id, action_id)
|
116
|
+
raise NotImplementedError
|
117
|
+
end
|
118
|
+
|
119
|
+
def delete_output_chunks(execution_plan_id, action_id)
|
120
|
+
raise NotImplementedError
|
121
|
+
end
|
122
|
+
|
107
123
|
# for debug purposes
|
108
124
|
def to_hash
|
109
125
|
raise NotImplementedError
|
@@ -78,6 +78,16 @@ module Dynflow
|
|
78
78
|
filter(:execution_plan, table(:execution_plan), options[:filters]).count
|
79
79
|
end
|
80
80
|
|
81
|
+
def find_execution_plan_statuses(options)
|
82
|
+
plans = filter(:execution_plan, table(:execution_plan), options[:filters])
|
83
|
+
.select(:uuid, :state, :result)
|
84
|
+
|
85
|
+
plans.each_with_object({}) do |current, acc|
|
86
|
+
uuid = current.delete(:uuid)
|
87
|
+
acc[uuid] = current
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
81
91
|
def delete_execution_plans(filters, batch_size = 1000, backup_dir = nil)
|
82
92
|
count = 0
|
83
93
|
filter(:execution_plan, table(:execution_plan), filters).each_slice(batch_size) do |plans|
|
@@ -190,6 +200,10 @@ module Dynflow
|
|
190
200
|
load_records :output_chunk, { execution_plan_uuid: execution_plan_id, action_id: action_id }, [:timestamp, :kind, :chunk]
|
191
201
|
end
|
192
202
|
|
203
|
+
def delete_output_chunks(execution_plan_id, action_id)
|
204
|
+
filter(:output_chunk, table(:output_chunk), { execution_plan_uuid: execution_plan_id, action_id: action_id }).delete
|
205
|
+
end
|
206
|
+
|
193
207
|
def connector_feature!
|
194
208
|
unless @additional_responsibilities[:connector]
|
195
209
|
raise "The sequel persistence adapter connector feature used but not enabled in additional_features"
|
data/lib/dynflow/version.rb
CHANGED
data/test/action_test.rb
CHANGED
@@ -889,5 +889,48 @@ module Dynflow
|
|
889
889
|
end
|
890
890
|
end
|
891
891
|
end
|
892
|
+
|
893
|
+
describe 'output chunks' do
|
894
|
+
include ::Dynflow::Testing::Factories
|
895
|
+
|
896
|
+
class OutputChunkAction < ::Dynflow::Action
|
897
|
+
def run(event = nil)
|
898
|
+
output[:counter] ||= 0
|
899
|
+
case event
|
900
|
+
when nil
|
901
|
+
output_chunk("Chunk #{output[:counter]}")
|
902
|
+
output[:counter] += 1
|
903
|
+
suspend
|
904
|
+
when :exit
|
905
|
+
return
|
906
|
+
end
|
907
|
+
end
|
908
|
+
|
909
|
+
def finalize
|
910
|
+
drop_output_chunks!
|
911
|
+
end
|
912
|
+
end
|
913
|
+
|
914
|
+
it 'collects and drops output chunks' do
|
915
|
+
action = create_and_plan_action(OutputChunkAction)
|
916
|
+
_(action.pending_output_chunks).must_equal nil
|
917
|
+
|
918
|
+
action = run_action(action)
|
919
|
+
_(action.pending_output_chunks.count).must_equal 1
|
920
|
+
|
921
|
+
action = run_action(action)
|
922
|
+
_(action.pending_output_chunks.count).must_equal 2
|
923
|
+
|
924
|
+
action = run_action(action, :exit)
|
925
|
+
_(action.pending_output_chunks.count).must_equal 2
|
926
|
+
|
927
|
+
persistence = mock()
|
928
|
+
persistence.expects(:delete_output_chunks).with(action.execution_plan_id, action.id)
|
929
|
+
action.world.stubs(:persistence).returns(persistence)
|
930
|
+
|
931
|
+
action = finalize_action(action)
|
932
|
+
_(action.pending_output_chunks.count).must_equal 0
|
933
|
+
end
|
934
|
+
end
|
892
935
|
end
|
893
936
|
end
|
data/test/persistence_test.rb
CHANGED
@@ -159,6 +159,46 @@ module Dynflow
|
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
162
|
+
describe '#def find_execution_plan_statuses' do
|
163
|
+
before do
|
164
|
+
# the tests expect clean field
|
165
|
+
adapter.delete_execution_plans({})
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'supports filtering' do
|
169
|
+
prepare_and_save_plans
|
170
|
+
if adapter.ordering_by.include?('state')
|
171
|
+
loaded_plans = adapter.find_execution_plan_statuses(filters: { label: ['test1'] })
|
172
|
+
_(loaded_plans).must_equal({ 'plan1' => { state: 'paused', result: nil} })
|
173
|
+
|
174
|
+
loaded_plans = adapter.find_execution_plan_statuses(filters: { state: ['paused'] })
|
175
|
+
_(loaded_plans).must_equal({"plan1"=>{:state=>"paused", :result=>nil},
|
176
|
+
"plan3"=>{:state=>"paused", :result=>nil},
|
177
|
+
"plan4"=>{:state=>"paused", :result=>nil}})
|
178
|
+
|
179
|
+
loaded_plans = adapter.find_execution_plan_statuses(filters: { state: ['stopped'] })
|
180
|
+
_(loaded_plans).must_equal({"plan2"=>{:state=>"stopped", :result=>nil}})
|
181
|
+
|
182
|
+
loaded_plans = adapter.find_execution_plan_statuses(filters: { state: [] })
|
183
|
+
_(loaded_plans).must_equal({})
|
184
|
+
|
185
|
+
loaded_plans = adapter.find_execution_plan_statuses(filters: { state: ['stopped', 'paused'] })
|
186
|
+
_(loaded_plans).must_equal({"plan1"=>{:state=>"paused", :result=>nil},
|
187
|
+
"plan2"=>{:state=>"stopped", :result=>nil},
|
188
|
+
"plan3"=>{:state=>"paused", :result=>nil}, "plan4"=>{:state=>"paused", :result=>nil}})
|
189
|
+
|
190
|
+
loaded_plans = adapter.find_execution_plan_statuses(filters: { 'state' => ['stopped', 'paused'] })
|
191
|
+
_(loaded_plans).must_equal({"plan1"=>{:state=>"paused", :result=>nil},
|
192
|
+
"plan2"=>{:state=>"stopped", :result=>nil},
|
193
|
+
"plan3"=>{:state=>"paused", :result=>nil},
|
194
|
+
"plan4"=>{:state=>"paused", :result=>nil}})
|
195
|
+
|
196
|
+
loaded_plans = adapter.find_execution_plan_statuses(filters: { label: ['test1'], :delayed => true })
|
197
|
+
_(loaded_plans).must_equal({})
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
162
202
|
describe '#def find_execution_plan_counts' do
|
163
203
|
before do
|
164
204
|
# the tests expect clean field
|
@@ -331,6 +371,20 @@ module Dynflow
|
|
331
371
|
_(plans.first[:execution_plan_uuid]).must_equal 'plan1'
|
332
372
|
end
|
333
373
|
end
|
374
|
+
|
375
|
+
describe '#delete_output_chunks' do
|
376
|
+
it 'deletes output chunks' do
|
377
|
+
prepare_plans_with_actions
|
378
|
+
|
379
|
+
adapter.save_output_chunks('plan1', 1, [{chunk: "Hello", timestamp: Time.now}, {chunk: "Bye", timestamp: Time.now}])
|
380
|
+
chunks = adapter.load_output_chunks('plan1', 1)
|
381
|
+
_(chunks.length).must_equal 2
|
382
|
+
deleted = adapter.delete_output_chunks('plan1', 1)
|
383
|
+
_(deleted).must_equal 2
|
384
|
+
chunks = adapter.load_output_chunks('plan1', 1)
|
385
|
+
_(chunks.length).must_equal 0
|
386
|
+
end
|
387
|
+
end
|
334
388
|
end
|
335
389
|
|
336
390
|
describe Dynflow::PersistenceAdapters::Sequel do
|
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.7.0
|
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: 2023-05-
|
12
|
+
date: 2023-05-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|