dynflow 0.8.15 → 0.8.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +5 -1
- data/doc/pages/source/documentation/index.md +7 -5
- data/lib/dynflow/execution_plan.rb +8 -2
- data/lib/dynflow/execution_plan/steps/abstract.rb +1 -1
- data/lib/dynflow/persistence.rb +6 -0
- data/lib/dynflow/persistence_adapters/sequel.rb +15 -3
- data/lib/dynflow/version.rb +1 -1
- data/lib/dynflow/world.rb +4 -1
- data/test/abnormal_states_recovery_test.rb +3 -0
- data/web/views/layout.erb +5 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6082a4e18537f19b13eaf0409be81baaf334a5c
|
4
|
+
data.tar.gz: 5c9d56842579de336c97b7f00d4284ef254ba196
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d24e6111ffac1b44316a31784afbe1ace05fd130e9c087bff718adfb33335fe2a7c747f176557b15999fd0b7900af1367128606452a7ce94c345894f5707f02
|
7
|
+
data.tar.gz: d7d3655784db8d993018d5c5e00c3dbebaf4679ae2bacf971eb129ea3e306854b97a803fa6098694ad5d79102aea2f70b456e481ec1af4a90469da71efe0f0a4
|
data/Gemfile
CHANGED
@@ -143,8 +143,8 @@ end
|
|
143
143
|
In example above, it seems that `plan_self` is just shortcut to
|
144
144
|
`plan_action MyActions::File::Destroy, filename` but it's not entirely true.
|
145
145
|
Note that `plan_action` always triggers `plan` of a given action while `plan_self`
|
146
|
-
plans only the `run` of Action, so by using `plan_action`
|
147
|
-
endless loop.
|
146
|
+
plans only the `run` and `finalize` of Action, so by using `plan_action`
|
147
|
+
we'd end up in endless loop.
|
148
148
|
|
149
149
|
Also note, that run method does not take any input. In fact, it can use
|
150
150
|
`input` method that refers to arguments, that were used in `plan_self`.
|
@@ -154,8 +154,9 @@ After that some finalizing steps can be taken. Actions can use outputs of other
|
|
154
154
|
as parts of their inputs establishing dependency. Action's state is serialized between each phase
|
155
155
|
and survives machine/executor restarts.
|
156
156
|
|
157
|
-
As lightly touched in the previous
|
158
|
-
Plan phase starts by triggering an action.
|
157
|
+
As lightly touched in the previous paragraphs there are 3 phases: `plan`, `run` and `finalize`.
|
158
|
+
Plan phase starts by triggering an action. `run` and `finalize` are only ran if you use
|
159
|
+
`plan_self` in `plan` phase.
|
159
160
|
|
160
161
|
#### Input and Output
|
161
162
|
|
@@ -315,7 +316,8 @@ an_action.plan(*args) # an_action is AnAction
|
|
315
316
|
```
|
316
317
|
|
317
318
|
`plan` method is inherited from Dynflow::Action and by default it plans itself if
|
318
|
-
`run` method is present using first argument as input.
|
319
|
+
`run` method is present using first argument as input. It also calls `finalize`
|
320
|
+
method if it is present.
|
319
321
|
|
320
322
|
```ruby
|
321
323
|
class AnAction < Dynflow::Action
|
@@ -409,9 +409,15 @@ module Dynflow
|
|
409
409
|
end
|
410
410
|
|
411
411
|
def self.steps_from_hash(step_ids, execution_plan_id, world)
|
412
|
+
steps = world.persistence.load_steps(execution_plan_id, world)
|
413
|
+
ids_to_steps = steps.inject({}) do |hash, step|
|
414
|
+
hash[step.id.to_i] = step
|
415
|
+
hash
|
416
|
+
end
|
417
|
+
# to make sure to we preserve the order of the steps
|
412
418
|
step_ids.inject({}) do |hash, step_id|
|
413
|
-
|
414
|
-
hash
|
419
|
+
hash[step_id.to_i] = ids_to_steps[step_id.to_i]
|
420
|
+
hash
|
415
421
|
end
|
416
422
|
end
|
417
423
|
|
@@ -113,7 +113,7 @@ module Dynflow
|
|
113
113
|
# @return [Action] in presentation mode, intended for retrieving: progress information,
|
114
114
|
# details, human outputs, etc.
|
115
115
|
def action(execution_plan)
|
116
|
-
world.persistence.load_action_for_presentation(execution_plan, action_id)
|
116
|
+
world.persistence.load_action_for_presentation(execution_plan, action_id, self)
|
117
117
|
end
|
118
118
|
|
119
119
|
def skippable?
|
data/lib/dynflow/persistence.rb
CHANGED
@@ -76,6 +76,12 @@ module Dynflow
|
|
76
76
|
ExecutionPlan::Steps::Abstract.from_hash(step_hash, execution_plan_id, world)
|
77
77
|
end
|
78
78
|
|
79
|
+
def load_steps(execution_plan_id, world)
|
80
|
+
adapter.load_steps(execution_plan_id).map do |step_hash|
|
81
|
+
ExecutionPlan::Steps::Abstract.from_hash(step_hash, execution_plan_id, world)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
79
85
|
def save_step(step)
|
80
86
|
adapter.save_step(step.execution_plan_id, step.id, step.to_hash)
|
81
87
|
end
|
@@ -113,6 +113,10 @@ module Dynflow
|
|
113
113
|
load :step, execution_plan_uuid: execution_plan_id, id: step_id
|
114
114
|
end
|
115
115
|
|
116
|
+
def load_steps(execution_plan_id)
|
117
|
+
load_records :step, execution_plan_uuid: execution_plan_id
|
118
|
+
end
|
119
|
+
|
116
120
|
def save_step(execution_plan_id, step_id, value)
|
117
121
|
save :step, { execution_plan_uuid: execution_plan_id, id: step_id }, value
|
118
122
|
end
|
@@ -139,8 +143,7 @@ module Dynflow
|
|
139
143
|
def pull_envelopes(receiver_id)
|
140
144
|
connector_feature!
|
141
145
|
db.transaction do
|
142
|
-
data_set = table(:envelope).where(receiver_id: receiver_id).
|
143
|
-
|
146
|
+
data_set = table(:envelope).where(receiver_id: receiver_id).all
|
144
147
|
envelopes = data_set.map { |record| load_data(record) }
|
145
148
|
|
146
149
|
table(:envelope).where(id: data_set.map { |d| d[:id] }).delete
|
@@ -246,7 +249,7 @@ module Dynflow
|
|
246
249
|
value
|
247
250
|
end
|
248
251
|
|
249
|
-
def
|
252
|
+
def load_record(what, condition)
|
250
253
|
table = table(what)
|
251
254
|
if (record = with_retry { table.first(Utils.symbolize_keys(condition)) } )
|
252
255
|
load_data(record)
|
@@ -255,6 +258,15 @@ module Dynflow
|
|
255
258
|
end
|
256
259
|
end
|
257
260
|
|
261
|
+
alias_method :load, :load_record
|
262
|
+
|
263
|
+
def load_records(what, condition)
|
264
|
+
table = table(what)
|
265
|
+
records = with_retry { table.filter(Utils.symbolize_keys(condition)).all }
|
266
|
+
records.map { |record| load_data(record) }
|
267
|
+
end
|
268
|
+
|
269
|
+
|
258
270
|
def load_data(record)
|
259
271
|
Utils.indifferent_hash(MultiJson.load(record[:data]))
|
260
272
|
end
|
data/lib/dynflow/version.rb
CHANGED
data/lib/dynflow/world.rb
CHANGED
@@ -13,8 +13,8 @@ module Dynflow
|
|
13
13
|
@id = SecureRandom.uuid
|
14
14
|
@clock = spawn_and_wait(Clock, 'clock')
|
15
15
|
config_for_world = Config::ForWorld.new(config, self)
|
16
|
-
config_for_world.validate
|
17
16
|
@logger_adapter = config_for_world.logger_adapter
|
17
|
+
config_for_world.validate
|
18
18
|
@transaction_adapter = config_for_world.transaction_adapter
|
19
19
|
@persistence = Persistence.new(self, config_for_world.persistence_adapter)
|
20
20
|
@coordinator = Coordinator.new(config_for_world.coordinator_adapter)
|
@@ -360,6 +360,9 @@ module Dynflow
|
|
360
360
|
end
|
361
361
|
end.compact
|
362
362
|
end
|
363
|
+
rescue Coordinator::LockError => e
|
364
|
+
logger.info "auto-executor lock already aquired: #{e.message}"
|
365
|
+
[]
|
363
366
|
end
|
364
367
|
|
365
368
|
def try_spawn_delayed_executor(config_for_world)
|
@@ -104,6 +104,9 @@ module Dynflow
|
|
104
104
|
client_world.auto_execute
|
105
105
|
expected_locks = ["lock auto-execute", "unlock auto-execute"]
|
106
106
|
client_world.coordinator.adapter.lock_log.must_equal(expected_locks)
|
107
|
+
lock = Coordinator::AutoExecuteLock.new(client_world)
|
108
|
+
client_world.coordinator.acquire(lock)
|
109
|
+
client_world.auto_execute.must_equal []
|
107
110
|
end
|
108
111
|
|
109
112
|
it "re-runs the plans that were planned but not executed" do
|
data/web/views/layout.erb
CHANGED
@@ -36,6 +36,11 @@
|
|
36
36
|
<ul class="nav navbar-nav">
|
37
37
|
<li><a href="<%= url '/' %>">Execution plans</a></li>
|
38
38
|
<li><a href="<%= url '/status' %>">Status</a></li>
|
39
|
+
<% if settings.respond_to?(:custom_navigation) && settings.custom_navigation %>
|
40
|
+
<% settings.custom_navigation.each do |description, uri| %>
|
41
|
+
<li><a href="<%= uri %>"><%= description %></a></li>
|
42
|
+
<% end %>
|
43
|
+
<% end %>
|
39
44
|
</ul>
|
40
45
|
<ul class="nav navbar-nav navbar-right">
|
41
46
|
</ul>
|
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: 0.8.
|
4
|
+
version: 0.8.16
|
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: 2016-
|
12
|
+
date: 2016-10-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|