rbbt-util 5.32.16 → 5.32.17

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,195 @@
1
+ module Workflow
2
+ def rec_dependencies(taskname, seen = [])
3
+ @rec_dependencies ||= {}
4
+ @rec_dependencies[taskname] ||= [] unless task_dependencies.include?(taskname)
5
+ @rec_dependencies[taskname] ||= begin
6
+
7
+ deps = task_dependencies[taskname]
8
+
9
+ all_deps = []
10
+ deps.each do |dep|
11
+ next if seen.include?(dep)
12
+ if DependencyBlock === dep
13
+ all_deps << dep.dependency if dep.dependency
14
+ else
15
+ all_deps << dep unless Proc === dep
16
+ end
17
+
18
+ begin
19
+ case dep
20
+ when Array
21
+ wf, t, o = dep
22
+
23
+ wf.rec_dependencies(t.to_sym, seen + [dep]).each do |d|
24
+ if Array === d
25
+ new = d.dup
26
+ else
27
+ new = [dep.first, d]
28
+ end
29
+
30
+ if Hash === o and not o.empty?
31
+ if Hash === new.last
32
+ hash = new.last.dup
33
+ o.each{|k,v| hash[k] ||= v}
34
+ new[new.length-1] = hash
35
+ else
36
+ new.push o.dup
37
+ end
38
+ end
39
+
40
+ all_deps << new
41
+ end if wf && t
42
+
43
+ when String, Symbol
44
+ rec_deps = rec_dependencies(dep.to_sym, seen + [dep])
45
+ all_deps.concat rec_deps
46
+ when DependencyBlock
47
+ dep = dep.dependency
48
+ raise TryAgain
49
+ end
50
+ rescue TryAgain
51
+ retry
52
+ end
53
+ end
54
+ all_deps.uniq
55
+ end
56
+ end
57
+
58
+ def override_dependencies(inputs)
59
+ override_dependencies = IndiferentHash.setup({})
60
+ return override_dependencies if inputs.nil?
61
+ inputs.each do |key,value|
62
+ if String === key && m = key.match(/(.*)#(.*)/)
63
+ workflow, task = m.values_at 1, 2
64
+ workflow = self.to_s if workflow.empty?
65
+ override_dependencies[workflow] ||= IndiferentHash.setup({})
66
+ override_dependencies[workflow][task] = value
67
+ end
68
+ end
69
+ override_dependencies
70
+ end
71
+
72
+ def setup_override_dependency(dep, workflow, task_name)
73
+ return [] if dep == :skip || dep == 'skip'
74
+ dep = Step === dep ? dep : Workflow.load_step(dep)
75
+ dep.workflow = workflow
76
+ dep.info[:name] = dep.name
77
+ dep.original_task_name ||= dep.task_name if dep.workflow
78
+
79
+
80
+ begin
81
+ workflow = Kernel.const_get workflow if String === workflow
82
+ dep.task = workflow.tasks[task_name] if dep.task.nil? && workflow.tasks.include?(task_name)
83
+ rescue
84
+ Log.exception $!
85
+ end
86
+ dep.task_name = task_name
87
+ dep.overriden = dep.original_task_name.to_sym
88
+
89
+ dep.extend step_module
90
+
91
+ dep
92
+ end
93
+
94
+ def real_dependencies(task, orig_jobname, inputs, dependencies)
95
+ real_dependencies = []
96
+ path_deps = {}
97
+
98
+ override_dependencies = override_dependencies(inputs)
99
+
100
+ dependencies.each do |dependency|
101
+ _inputs = IndiferentHash.setup(inputs.dup)
102
+ jobname = orig_jobname
103
+ jobname = _inputs[:jobname] if _inputs.include? :jobname
104
+
105
+ real_dep = case dependency
106
+ when Array
107
+ workflow, dep_task, options = dependency
108
+
109
+ if override_dependencies[workflow.to_s] && value = override_dependencies[workflow.to_s][dep_task]
110
+ setup_override_dependency(value, workflow, dep_task)
111
+ else
112
+
113
+ compute = options[:compute] if options
114
+
115
+ all_d = (real_dependencies + real_dependencies.flatten.collect{|d| d.rec_dependencies} ).flatten.compact.uniq
116
+
117
+ _inputs = assign_dep_inputs(_inputs, options, all_d, workflow.task_info(dep_task))
118
+ jobname = _inputs.delete :jobname if _inputs.include? :jobname
119
+
120
+ job = workflow._job(dep_task, jobname, _inputs)
121
+ ComputeDependency.setup(job, compute) if compute
122
+ job
123
+ end
124
+ when Step
125
+ dependency
126
+ when Symbol
127
+ if override_dependencies[self.to_s] && value = override_dependencies[self.to_s][dependency]
128
+ setup_override_dependency(value, self, dependency)
129
+ else
130
+ _job(dependency, jobname, _inputs)
131
+ end
132
+ when Proc
133
+ if DependencyBlock === dependency
134
+ orig_dep = dependency.dependency
135
+ wf, task_name, options = orig_dep
136
+
137
+ if override_dependencies[wf.to_s] && value = override_dependencies[wf.to_s][task_name]
138
+ dep = setup_override_dependency(value, wf, task_name)
139
+ else
140
+
141
+ options = {} if options.nil?
142
+ compute = options[:compute]
143
+
144
+ options = IndiferentHash.setup(options.dup)
145
+ dep = dependency.call jobname, _inputs.merge(options), real_dependencies
146
+
147
+ dep = [dep] unless Array === dep
148
+
149
+ new_=[]
150
+ dep.each{|d|
151
+ next if d.nil?
152
+ if Hash === d
153
+ d[:workflow] ||= wf
154
+ d[:task] ||= task_name
155
+ _override_dependencies = override_dependencies.merge(override_dependencies(d[:inputs] || {}))
156
+ d = if _override_dependencies[d[:workflow].to_s] && value = _override_dependencies[d[:workflow].to_s][d[:task]]
157
+ setup_override_dependency(value, d[:workflow], d[:task])
158
+ else
159
+ task_info = d[:workflow].task_info(d[:task])
160
+
161
+ _inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
162
+ d[:workflow]._job(d[:task], d[:jobname], _inputs)
163
+ end
164
+ end
165
+ ComputeDependency.setup(d, compute) if compute
166
+ new_ << d
167
+ }
168
+ dep = new_
169
+ end
170
+ else
171
+ _inputs = IndiferentHash.setup(_inputs.dup)
172
+ dep = dependency.call jobname, _inputs, real_dependencies
173
+ if Hash === dep
174
+ dep[:workflow] ||= wf || self
175
+ _override_dependencies = override_dependencies.merge(override_dependencies(dep[:inputs] || {}))
176
+ if _override_dependencies[dep[:workflow].to_s] && value = _override_dependencies[dep[:workflow].to_s][dep[:task]]
177
+ setup_override_dependency(value, dep[:workflow], dep[:task])
178
+ else
179
+ task_info = (dep[:task] && dep[:workflow]) ? dep[:workflow].task_info(dep[:task]) : nil
180
+ _inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
181
+ dep = dep[:workflow]._job(dep[:task], dep[:jobname], _inputs)
182
+ end
183
+ end
184
+ end
185
+
186
+ dep
187
+ else
188
+ raise "Dependency for #{task.name} not understood: #{Misc.fingerprint dependency}"
189
+ end
190
+
191
+ real_dependencies << real_dep
192
+ end
193
+ real_dependencies.flatten.compact
194
+ end
195
+ end
@@ -4,6 +4,8 @@ require 'rbbt/util/log'
4
4
  require 'rbbt/util/semaphore'
5
5
  require 'rbbt/workflow/step/accessor'
6
6
  require 'rbbt/workflow/step/prepare'
7
+ require 'rbbt/workflow/step/status'
8
+ require 'rbbt/workflow/step/info'
7
9
 
8
10
  class Step
9
11
  attr_accessor :clean_name, :path, :task, :workflow, :inputs, :dependencies, :bindings
@@ -35,41 +37,6 @@ class Step
35
37
  end
36
38
 
37
39
 
38
- def overriden?
39
- return true if @overriden
40
- return true if dependencies.select{|dep| dep.overriden? }.any?
41
- info[:archived_info].each do |f,i|
42
- return true if i[:overriden] || i["overriden"]
43
- end if info[:archived_info]
44
- return false
45
- end
46
-
47
- def overriden
48
- @overriden
49
- #if @overriden.nil?
50
- # return false if dependencies.nil?
51
- # dependencies.select{|dep| dep.overriden? }.any?
52
- #else
53
- # @overriden
54
- #end
55
- end
56
-
57
- def overriden_deps
58
- ord = []
59
- deps = dependencies.dup
60
- while dep = deps.shift
61
- case dep.overriden
62
- when FalseClass
63
- next
64
- when Symbol
65
- ord << dep
66
- else
67
- deps += dep.dependencies
68
- end
69
- end
70
- ord
71
- end
72
-
73
40
  def initialize(path, task = nil, inputs = nil, dependencies = nil, bindings = nil, clean_name = nil)
74
41
  path = Path.setup(Misc.sanitize_filename(path)) if String === path
75
42
  path = path.call if Proc === path
@@ -99,35 +66,6 @@ class Step
99
66
  end
100
67
 
101
68
 
102
- def load_inputs_from_info
103
- if info[:inputs]
104
- info_inputs = info[:inputs]
105
- if task && task.respond_to?(:inputs) && task.inputs
106
- IndiferentHash.setup info_inputs
107
- @inputs = NamedArray.setup info_inputs.values_at(*task.inputs.collect{|name| name.to_s}), task.inputs
108
- else
109
- @inputs = NamedArray.setup info_inputs.values, info_inputs.keys
110
- end
111
- else
112
- nil
113
- end
114
- end
115
-
116
- def load_dependencies_from_info
117
- relocated = nil
118
- @dependencies = (self.info[:dependencies] || []).collect do |task,name,dep_path|
119
- if Open.exists?(dep_path) || Open.exists?(dep_path + '.info')
120
- Workflow._load_step dep_path
121
- else
122
- next if FalseClass === relocated
123
- new_path = Workflow.relocate(path, dep_path)
124
- relocated = true if Open.exists?(new_path) || Open.exists?(new_path + '.info')
125
- Workflow._load_step new_path
126
- end
127
- end.compact
128
- @relocated = relocated
129
- end
130
-
131
69
 
132
70
  def inputs
133
71
  return @inputs if NamedArray === @inputs
@@ -151,54 +89,6 @@ class Step
151
89
  end
152
90
  end
153
91
 
154
- def archive_deps
155
- self.set_info :archived_info, archived_info
156
- self.set_info :archived_dependencies, info[:dependencies]
157
- end
158
-
159
- def archived_info
160
- return info[:archived_info] if info[:archived_info]
161
-
162
- archived_info = {}
163
- dependencies.each do |dep|
164
- if Symbol === dep.overriden && ! Open.exists?(dep.info_file)
165
- archived_info[dep.path] = dep.overriden
166
- else
167
- archived_info[dep.path] = dep.info
168
- end
169
- archived_info.merge!(dep.archived_info)
170
- end if dependencies
171
-
172
- archived_info
173
- end
174
-
175
- def archived_inputs
176
- return {} unless info[:archived_dependencies]
177
- archived_info = self.archived_info
178
-
179
- all_inputs = IndiferentHash.setup({})
180
- deps = info[:archived_dependencies].collect{|p| p.last}
181
- seen = []
182
- while path = deps.pop
183
- dep_info = archived_info[path]
184
- if dep_info
185
- dep_info[:inputs].each do |k,v|
186
- all_inputs[k] = v unless all_inputs.include?(k)
187
- end if dep_info[:inputs]
188
- deps.concat(dep_info[:dependencies].collect{|p| p.last } - seen) if dep_info[:dependencies]
189
- deps.concat(dep_info[:archived_dependencies].collect{|p| p.last } - seen) if dep_info[:archived_dependencies]
190
- end
191
- seen << path
192
- end
193
-
194
- all_inputs
195
- end
196
-
197
- def dependencies=(dependencies)
198
- @dependencies = dependencies
199
- set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]} if dependencies
200
- end
201
-
202
92
  def recursive_inputs
203
93
  if NamedArray === inputs
204
94
  i = {}
@@ -213,7 +103,8 @@ class Step
213
103
 
214
104
  dep.inputs.zip(dep.inputs.fields).each do |v,f|
215
105
  if i.include?(f) && i[f] != v
216
- Log.debug "Conflict in #{ f }: #{[Misc.fingerprint(i[f]), Misc.fingerprint(v)] * " <-> "}"
106
+ next
107
+ #Log.debug "Variable '#{f}' reused with different values: #{[Misc.fingerprint(i[f]), Misc.fingerprint(v)] * " <-> "}"
217
108
  else
218
109
  i[f] = v
219
110
  end
@@ -453,34 +344,6 @@ class Step
453
344
  res
454
345
  end
455
346
 
456
- def self.clean(path)
457
- info_file = Step.info_file path
458
- pid_file = Step.pid_file path
459
- md5_file = Step.md5_file path
460
- files_dir = Step.files_dir path
461
- tmp_path = Step.tmp_path path
462
-
463
- if ! (Open.writable?(path) && Open.writable?(info_file))
464
- Log.warn "Could not clean #{path}: not writable"
465
- return
466
- end
467
-
468
- 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)
469
-
470
- @result = nil
471
- @pid = nil
472
-
473
- Misc.insist do
474
- Open.rm info_file if Open.exists?(info_file)
475
- Open.rm md5_file if Open.exists?(md5_file)
476
- Open.rm path if (Open.exists?(path) || Open.broken_link?(path))
477
- Open.rm_rf files_dir if Open.exists?(files_dir) || Open.broken_link?(files_dir)
478
- Open.rm pid_file if Open.exists?(pid_file)
479
- Open.rm tmp_path if Open.exists?(tmp_path)
480
- end
481
- end
482
- end
483
-
484
347
  def update
485
348
  if dirty?
486
349
  dependencies.collect{|d| d.update } if dependencies
@@ -488,22 +351,6 @@ class Step
488
351
  end
489
352
  end
490
353
 
491
- def clean
492
- if ! Open.exists?(info_file)
493
- Log.high "Refusing to clean step with no .info file: #{path}"
494
- return self
495
- end
496
- status = []
497
- status << "dirty" if done? && dirty?
498
- status << "not running" if ! done? && ! running?
499
- status.unshift " " if status.any?
500
- Log.high "Cleaning step: #{path}#{status * " "}"
501
- Log.stack caller if RBBT_DEBUG_CLEAN
502
- abort if ! done? && running?
503
- Step.clean(path)
504
- self
505
- end
506
-
507
354
  #connected = true means that dependency searching ends when a result is done
508
355
  #but dependencies are absent, meanining that the file could have been dropped
509
356
  #in
@@ -516,7 +363,11 @@ class Step
516
363
  return [] if dependencies.nil? or dependencies.empty?
517
364
 
518
365
  new_dependencies = []
519
- archived_deps = self.info[:archived_info] ? self.info[:archived_info].keys : []
366
+ if self.overriden?
367
+ archived_deps = []
368
+ else
369
+ archived_deps = self.info[:archived_info] ? self.info[:archived_info].keys : []
370
+ end
520
371
 
521
372
  dependencies.each{|step|
522
373
  #next if self.done? && Open.exists?(info_file) && info[:dependencies] && info[:dependencies].select{|task,name,path| path == step.path }.empty?
@@ -528,6 +379,7 @@ class Step
528
379
  new_dependencies.concat r
529
380
  new_dependencies << step
530
381
  }
382
+
531
383
  new_dependencies.uniq
532
384
  end
533
385
 
@@ -26,6 +26,7 @@ class Step
26
26
  threads = jobs.collect do |j|
27
27
  Thread.new do
28
28
  begin
29
+ j.soft_grace
29
30
  j.join unless j.done?
30
31
  rescue Exception
31
32
  Log.error "Exception waiting for job: #{Log.color :blue, j.path}"
@@ -206,45 +207,6 @@ class Step
206
207
  #@status_lock
207
208
  end
208
209
 
209
- def info(check_lock = true)
210
- return {:status => :noinfo} if info_file.nil? or not Open.exists? info_file
211
- begin
212
- Misc.insist do
213
- begin
214
- return @info_cache if @info_cache and @info_cache_time and Open.ctime(info_file) < @info_cache_time
215
- rescue Exception
216
- raise $!
217
- end
218
-
219
- begin
220
- @info_cache = Misc.insist(3, 1.6, info_file) do
221
- Misc.insist(2, 1, info_file) do
222
- Misc.insist(3, 0.2, info_file) do
223
- raise TryAgain, "Info locked" if check_lock and info_lock.locked?
224
- info_lock.lock if check_lock and false
225
- begin
226
- Open.open(info_file, :mode => 'rb') do |file|
227
- Step.load_serialized_info(file)
228
- end
229
- ensure
230
- info_lock.unlock if check_lock and false
231
- end
232
- end
233
- end
234
- end
235
- @info_cache_time = Time.now
236
- @info_cache
237
- end
238
- end
239
- rescue Exception
240
- Log.debug{"Error loading info file: " + info_file}
241
- Log.exception $!
242
- Open.rm info_file
243
- Misc.sensiblewrite(info_file, Step.serialize_info({:status => :error, :messages => ["Info file lost"]}))
244
- raise $!
245
- end
246
- end
247
-
248
210
  def init_info(force = false)
249
211
  return nil if @exec || info_file.nil? || (Open.exists?(info_file) && ! force)
250
212
  Open.lock(info_file, :lock => info_lock) do
@@ -286,274 +248,6 @@ class Step
286
248
  end
287
249
  end
288
250
 
289
- def status
290
- begin
291
- info[:status]
292
- rescue Exception
293
- Log.error "Exception reading status: #{$!.message}"
294
- :error
295
- end
296
- end
297
-
298
- def status=(status)
299
- set_info(:status, status)
300
- end
301
-
302
- def messages
303
- if messages = info[:messages]
304
- messages
305
- else
306
- set_info(:messages, []) if self.respond_to?(:set_info)
307
- end
308
- end
309
-
310
- def message(message)
311
- message = Log.uncolor(message)
312
- set_info(:messages, (messages || []) << message)
313
- end
314
-
315
- def self.status_color(status)
316
- status = status.split(">").last
317
- case status
318
- when "starting"
319
- :yellow
320
- when "error", "aborted"
321
- :red
322
- when "done"
323
- :green
324
- else
325
- :cyan
326
- end
327
- end
328
-
329
- def self.log_block(status, message, path, &block)
330
- start = Time.now
331
- status = status.to_s
332
- status_color = self.status_color status
333
-
334
- Log.info do
335
- now = Time.now
336
- str = Log.color :reset
337
- str << "#{ Log.color status_color, status}"
338
- str << ": #{ message }" if message and message != :result
339
- str << " -- #{Log.color :blue, path.to_s}" if path
340
- str << " #{Log.color :yellow, Process.pid}"
341
- str
342
- end
343
- res = yield
344
- eend = Time.now
345
- Log.info do
346
- now = Time.now
347
- str = "#{ Log.color :cyan, status.to_s } +#{Log.color :green, "%.2f" % (eend - start)}"
348
- str << ": #{ res }" if message == :result
349
- str << " -- #{Log.color :blue, path.to_s}" if path
350
- str << " #{Log.color :yellow, Process.pid}"
351
- str
352
- end
353
- res
354
- end
355
-
356
- def self.log_string(status, message, path)
357
- Log.info do
358
-
359
- status = status.to_s
360
- status_color = self.status_color status
361
-
362
- str = Log.color :reset
363
- str << "#{ Log.color status_color, status}"
364
- str << ": #{ message }" if message
365
- str << " -- #{Log.color :blue, path.to_s}" if path
366
- str << " #{Log.color :yellow, Process.pid}"
367
- str
368
- end
369
- end
370
-
371
- def self.log_progress(status, options = {}, path = nil, &block)
372
- options = Misc.add_defaults options, :severity => Log::INFO, :file => (@exec ? nil : path)
373
- max = Misc.process_options options, :max
374
- Log::ProgressBar.with_bar(max, options) do |bar|
375
- begin
376
- res = yield bar
377
- raise KeepBar.new res if IO === res
378
- res
379
- rescue
380
- Log.exception $!
381
- raise $!
382
- end
383
- end
384
- end
385
-
386
- def log_progress(status, options = {}, &block)
387
- Step.log_progress(status, options, file(:progress), &block)
388
- end
389
-
390
- def progress_bar(msg = "Progress", options = nil)
391
- if Hash === msg and options.nil?
392
- options = msg
393
- msg = nil
394
- end
395
- options = {} if options.nil?
396
-
397
- max = options[:max]
398
- Log::ProgressBar.new_bar(max, {:desc => msg, :file => (@exec ? nil : file(:progress))}.merge(options))
399
- end
400
-
401
- def self.log(status, message, path, &block)
402
- if block
403
- if Hash === message
404
- log_progress(status, message, path, &block)
405
- else
406
- log_block(status, message, path, &block)
407
- end
408
- else
409
- log_string(status, message, path)
410
- end
411
- end
412
-
413
- def log(status, message = nil, &block)
414
- self.status = status
415
- if message
416
- self.message Log.uncolor(message)
417
- end
418
- Step.log(status, message, path, &block)
419
- end
420
-
421
- def exception(ex, msg = nil)
422
- ex_class = ex.class.to_s
423
- backtrace = ex.backtrace if ex.respond_to?(:backtrace)
424
- message = ex.message if ex.respond_to?(:message)
425
- set_info :backtrace, backtrace
426
- set_info :exception, {:class => ex_class, :message => message, :backtrace => backtrace}
427
- if msg.nil?
428
- log :error, "#{ex_class} -- #{message}"
429
- else
430
- log :error, "#{msg} -- #{message}"
431
- end
432
- self._abort
433
- end
434
-
435
- def get_exception
436
- if info[:exception].nil?
437
- return Aborted if aborted?
438
- return Exception.new(messages.last) if error?
439
- Exception.new ""
440
- else
441
- ex_class, ex_message, ex_backtrace = info[:exception].values_at :class, :message, :backtrace
442
- begin
443
- klass = Kernel.const_get(ex_class)
444
- ex = klass.new ex_message
445
- ex.set_backtrace ex_backtrace unless ex_backtrace.nil? or ex_backtrace.empty?
446
- ex
447
- rescue
448
- Log.exception $!
449
- Exception.new ex_message
450
- end
451
- end
452
- end
453
-
454
- def recoverable_error?
455
- return true if aborted?
456
- return false unless error?
457
- begin
458
- return true unless info[:exception]
459
- klass = Kernel.const_get(info[:exception][:class])
460
- ! (klass <= RbbtException)
461
- rescue Exception
462
- true
463
- end
464
- end
465
-
466
- def started?
467
- Open.exists?(path) or (Open.exists?(pid_file) && Open.exists?(info_file))
468
- end
469
-
470
- def waiting?
471
- Open.exists?(info_file) and not started?
472
- end
473
-
474
- def dirty_files
475
- rec_dependencies = self.rec_dependencies(true)
476
- return [] if rec_dependencies.empty?
477
- canfail_paths = self.canfail_paths
478
-
479
- dirty_files = rec_dependencies.reject{|dep|
480
- (defined?(WorkflowRemoteClient) && WorkflowRemoteClient::RemoteStep === dep) ||
481
- ! Open.exists?(dep.info_file) ||
482
- (dep.path && (Open.exists?(dep.path) || Open.remote?(dep.path))) ||
483
- ((dep.error? || dep.aborted?) && (! dep.recoverable_error? || canfail_paths.include?(dep.path)))
484
- }
485
- end
486
-
487
- def dirty?
488
- return true if Open.exists?(pid_file) && ! ( Open.exists?(info_file) || done? )
489
- return false unless done? || status == :done
490
- return false unless ENV["RBBT_UPDATE"] == "true"
491
-
492
- status = self.status
493
-
494
- if done? and not (status == :done or status == :ending or status == :producing) and not status == :noinfo
495
- return true
496
- end
497
-
498
- if status == :done and not done?
499
- return true
500
- end
501
-
502
- if dirty_files.any?
503
- Log.low "Some dirty files found for #{self.path}: #{Misc.fingerprint dirty_files}"
504
- true
505
- else
506
- ! self.updated?
507
- end
508
- end
509
-
510
- def done?
511
- path and Open.exists? path
512
- end
513
-
514
- def streaming?
515
- (IO === @result) or (not @saved_stream.nil?) or status == :streaming
516
- end
517
-
518
- def noinfo?
519
- status == :noinfo
520
- end
521
-
522
- def running?
523
- return false if ! (started? || status == :ending)
524
- return nil unless Open.exist?(self.pid_file)
525
- pid = Open.read(self.pid_file).to_i
526
-
527
- return false if done? or error? or aborted?
528
-
529
- if Misc.pid_exists?(pid)
530
- pid
531
- else
532
- done? or error? or aborted?
533
- end
534
- end
535
-
536
- def stalled?
537
- started? && ! (done? || running? || done? || error? || aborted?)
538
- end
539
-
540
- def missing?
541
- status == :done && ! Open.exists?(path)
542
- end
543
-
544
- def error?
545
- status == :error
546
- end
547
-
548
- def nopid?
549
- ! Open.exists?(pid_file) && ! (status.nil? || status == :aborted || status == :done || status == :error || status == :cleaned)
550
- end
551
-
552
- def aborted?
553
- status = self.status
554
- status == :aborted || ((status != :ending && status != :dependencies && status != :cleaned && status != :noinfo && status != :setup && status != :noinfo) && nopid?)
555
- end
556
-
557
251
  # {{{ INFO
558
252
 
559
253
  def files_dir
@@ -650,10 +344,6 @@ class Step
650
344
  provenance
651
345
  end
652
346
 
653
- def resumable?
654
- task && task.resumable
655
- end
656
-
657
347
  def config(key, *tokens)
658
348
  options = tokens.pop if Hash === tokens.last
659
349
  options ||= {}