rbbt-util 5.32.16 → 5.32.21

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,146 @@
1
+ class Step
2
+ def self.clean(path)
3
+ info_file = Step.info_file path
4
+ pid_file = Step.pid_file path
5
+ md5_file = Step.md5_file path
6
+ files_dir = Step.files_dir path
7
+ tmp_path = Step.tmp_path path
8
+
9
+ if ! (Open.writable?(path) && Open.writable?(info_file))
10
+ Log.warn "Could not clean #{path}: not writable"
11
+ return
12
+ end
13
+
14
+ if ENV["RBBT_DEBUG_CLEAN"] == 'true'
15
+ raise "DO NOT CLEAN"
16
+ end
17
+
18
+ if (Open.exists?(path) or Open.broken_link?(path)) or Open.exists?(pid_file) or Open.exists?(info_file) or Open.exists?(files_dir) or Open.broken_link?(files_dir)
19
+
20
+ @result = nil
21
+ @pid = nil
22
+
23
+ Misc.insist do
24
+ Open.rm info_file if Open.exists?(info_file)
25
+ Open.rm md5_file if Open.exists?(md5_file)
26
+ Open.rm path if (Open.exists?(path) || Open.broken_link?(path))
27
+ Open.rm_rf files_dir if Open.exists?(files_dir) || Open.broken_link?(files_dir)
28
+ Open.rm pid_file if Open.exists?(pid_file)
29
+ Open.rm tmp_path if Open.exists?(tmp_path)
30
+ end
31
+ end
32
+ end
33
+
34
+ def clean
35
+ if ! Open.exists?(info_file)
36
+ Log.high "Refusing to clean step with no .info file: #{path}"
37
+ return self
38
+ end
39
+ status = []
40
+ status << "dirty" if done? && dirty?
41
+ status << "not running" if ! done? && ! running?
42
+ status.unshift " " if status.any?
43
+ Log.high "Cleaning step: #{path}#{status * " "}"
44
+ Log.stack caller if RBBT_DEBUG_CLEAN
45
+ abort if ! done? && running?
46
+ Step.clean(path)
47
+ @done = false
48
+ self
49
+ end
50
+
51
+ def resumable?
52
+ (task && task.resumable) || status == :waiting || status == :cleaned
53
+ end
54
+
55
+ def started?
56
+ Open.exists?(path) or (Open.exists?(pid_file) && Open.exists?(info_file))
57
+ end
58
+
59
+ def waiting?
60
+ Open.exists?(info_file) and not started?
61
+ end
62
+
63
+ def dirty_files
64
+ rec_dependencies = self.rec_dependencies(true)
65
+ return [] if rec_dependencies.empty?
66
+ canfail_paths = self.canfail_paths
67
+
68
+ dirty_files = rec_dependencies.reject{|dep|
69
+ (defined?(WorkflowRemoteClient) && WorkflowRemoteClient::RemoteStep === dep) ||
70
+ ! Open.exists?(dep.info_file) ||
71
+ (dep.path && (Open.exists?(dep.path) || Open.remote?(dep.path))) ||
72
+ ((dep.error? || dep.aborted?) && (! dep.recoverable_error? || canfail_paths.include?(dep.path)))
73
+ }
74
+ end
75
+
76
+ def dirty?
77
+ return true if Open.exists?(pid_file) && ! ( Open.exists?(info_file) || done? )
78
+ return false unless done? || status == :done
79
+ return false unless ENV["RBBT_UPDATE"] == "true"
80
+
81
+ status = self.status
82
+
83
+ if done? and not (status == :done or status == :ending or status == :producing) and not status == :noinfo
84
+ return true
85
+ end
86
+
87
+ if status == :done and not done?
88
+ return true
89
+ end
90
+
91
+ if dirty_files.any?
92
+ Log.low "Some dirty files found for #{self.path}: #{Misc.fingerprint dirty_files}"
93
+ true
94
+ else
95
+ ! self.updated?
96
+ end
97
+ end
98
+
99
+ def done?
100
+ @done ||= path and Open.exists? path
101
+ end
102
+
103
+ def streaming?
104
+ (IO === @result) or (not @saved_stream.nil?) or status == :streaming
105
+ end
106
+
107
+ def noinfo?
108
+ status == :noinfo
109
+ end
110
+
111
+ def running?
112
+ return false if ! (started? || status == :ending)
113
+ return nil unless Open.exist?(self.pid_file)
114
+ pid = Open.read(self.pid_file).to_i
115
+
116
+ return false if done? or error? or aborted?
117
+
118
+ if Misc.pid_exists?(pid)
119
+ pid
120
+ else
121
+ done? or error? or aborted?
122
+ end
123
+ end
124
+
125
+ def stalled?
126
+ started? && ! (done? || running? || done? || error? || aborted?)
127
+ end
128
+
129
+ def missing?
130
+ status == :done && ! Open.exists?(path)
131
+ end
132
+
133
+ def error?
134
+ status == :error
135
+ end
136
+
137
+ def nopid?
138
+ ! Open.exists?(pid_file) && ! (status.nil? || status == :aborted || status == :done || status == :error || status == :cleaned)
139
+ end
140
+
141
+ def aborted?
142
+ status = self.status
143
+ status == :aborted || ((status != :ending && status != :dependencies && status != :cleaned && status != :noinfo && status != :setup && status != :noinfo && status != :waiting) && nopid?)
144
+ end
145
+
146
+ end
@@ -67,11 +67,13 @@ end
67
67
 
68
68
  module Workflow
69
69
 
70
- def dep_tree(name)
70
+ def dep_tree(name, seen = [])
71
71
  @dep_tree ||= {}
72
72
  @dep_tree[name] ||= begin
73
73
  dep_tree = {}
74
74
  self.task_dependencies[name.to_sym].reverse.each do |dep|
75
+ next if seen.include? dep
76
+ seen << dep
75
77
  dep = dep.first if Array === dep && dep.length == 1
76
78
  dep = dep.dependency if DependencyBlock === dep
77
79
 
@@ -87,7 +89,7 @@ module Workflow
87
89
 
88
90
  key = [workflow, task]
89
91
 
90
- dep_tree[key] = workflow.dep_tree(task)
92
+ dep_tree[key] = workflow.dep_tree(task, seen)
91
93
  end if name && self.task_dependencies[name.to_sym]
92
94
  dep_tree
93
95
  end
@@ -81,7 +81,7 @@ module Workflow
81
81
  def self.candidates(workload, rules)
82
82
  if rules.empty?
83
83
  candidates = workload.select{|k,v| v.empty? }.
84
- collect{|k,v| k}.
84
+ collect{|k,v| k }.
85
85
  reject{|k| k.done? }
86
86
  else
87
87
  candidates = workload. #select{|k,v| Orchestrator.job_rules(rules, k) }.
@@ -47,6 +47,8 @@ class Step
47
47
  if input.nil? || input.empty?
48
48
  input_str = nil
49
49
  else
50
+ input = input.reject{|dep,name| (input & dep.dependencies.collect{|d| [d,name]}).any? }
51
+ input = input.reject{|dep,name| (input & dep.input_dependencies.collect{|d| [d,name]}).any? }
50
52
  input_str = Log.color(:magenta, "-> ") + input.collect{|dep,name| Log.color(:yellow, dep.task_name.to_s) + ":" + Log.color(:yellow, name) }.uniq * " "
51
53
  end
52
54
 
@@ -91,21 +93,28 @@ class Step
91
93
  status = :unsync if status == :done and not Open.exist?(path)
92
94
  status = :notfound if status == :noinfo and not Open.exist?(path)
93
95
 
94
- str = " " * offset
95
- str << prov_report_msg(status, name, path, info, input)
96
+
97
+ this_step_msg = prov_report_msg(status, name, path, info, input)
96
98
 
97
99
  input_dependencies = {}
98
100
  step.dependencies.each do |dep|
99
101
  if dep.input_dependencies.any?
100
102
  dep.input_dependencies.each do |id|
101
- input_name = dep.inputs.fields.zip(dep.inputs).select{|f,d| d == id || String === d && d.start_with?(id.files_dir) }.first.first
103
+ input_name = dep.recursive_inputs.fields.zip(dep.recursive_inputs).select{|f,d|
104
+ d == id || (String === d && d.start_with?(id.files_dir)) || (Array === d && d.include?(id))
105
+ }.last.first
102
106
  input_dependencies[id] ||= []
103
107
  input_dependencies[id] << [dep, input_name]
104
108
  end
105
109
  end
106
110
  end
107
111
 
108
- step.dependencies.reverse.each do |dep|
112
+ str = ""
113
+ str = " " * offset + this_step_msg if ENV["RBBT_ORIGINAL_STACK"] == 'true'
114
+
115
+ step.dependencies.dup.tap{|l|
116
+ l.reverse! if ENV["RBBT_ORIGINAL_STACK"] == 'true'
117
+ }.each do |dep|
109
118
  path = dep.path
110
119
  new = ! seen.include?(path)
111
120
  if new
@@ -126,6 +135,9 @@ class Step
126
135
  end
127
136
  end
128
137
  end if step.dependencies
138
+
139
+ str += (" " * offset) + this_step_msg unless ENV["RBBT_ORIGINAL_STACK"] == 'true'
140
+
129
141
  str
130
142
  end
131
143
  end
@@ -34,6 +34,7 @@ force = options.delete :force
34
34
  dirty = options.delete :dirty
35
35
  time = options.delete :older
36
36
 
37
+ ENV["RBBT_DEBUG_CLEAN"] = 'false'
37
38
  ENV["RBBT_UPDATE"] = 'true' if dirty
38
39
 
39
40
  time = Misc.timespan time, 'd' if time
@@ -131,6 +131,6 @@ if options[:plot]
131
131
  end
132
132
 
133
133
  else
134
- puts Step.prov_report(step, 0, nil, [], options[:expand_repeats]).strip
134
+ puts Step.prov_report(step, 0, nil, [], options[:expand_repeats])
135
135
  end
136
136
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbt-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.32.16
4
+ version: 5.32.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-05 00:00:00.000000000 Z
11
+ date: 2021-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -322,6 +322,7 @@ files:
322
322
  - lib/rbbt/workflow/accessor.rb
323
323
  - lib/rbbt/workflow/annotate.rb
324
324
  - lib/rbbt/workflow/definition.rb
325
+ - lib/rbbt/workflow/dependencies.rb
325
326
  - lib/rbbt/workflow/doc.rb
326
327
  - lib/rbbt/workflow/examples.rb
327
328
  - lib/rbbt/workflow/integration/ansible.rb
@@ -339,8 +340,10 @@ files:
339
340
  - lib/rbbt/workflow/step.rb
340
341
  - lib/rbbt/workflow/step/accessor.rb
341
342
  - lib/rbbt/workflow/step/dependencies.rb
343
+ - lib/rbbt/workflow/step/info.rb
342
344
  - lib/rbbt/workflow/step/prepare.rb
343
345
  - lib/rbbt/workflow/step/run.rb
346
+ - lib/rbbt/workflow/step/status.rb
344
347
  - lib/rbbt/workflow/task.rb
345
348
  - lib/rbbt/workflow/usage.rb
346
349
  - lib/rbbt/workflow/util/archive.rb