rbbt-util 5.26.77 → 5.26.78

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a692bb25efd5eec786a9aa7ed436abdd30f663850570631cd116f4cba01a144
4
- data.tar.gz: 1128c92e4b23b7b5d69e619e1b0a368c8025e136d8e292e16ec26a9364ff9af6
3
+ metadata.gz: fa385d029073f92c7d003f8dd139ffd76f256cf50e8b6f9eb48146b8624c1d0f
4
+ data.tar.gz: 1e9d23cd39e36dcebf0d2e61f269593f031cb7a8c8b4ff900993aa10fd7b11a6
5
5
  SHA512:
6
- metadata.gz: e8c8bc0cf7bfda033b36aa6817a86fa78812356e892af458889fefc1628688d406c19dadf2f99fb791bf416b7f42d142d11c569c9dde538822c62497ce8b4b23
7
- data.tar.gz: 429bde72bf0b7d61f3f5089cf0ce90445406dd120fce2d4d0c0b8fc9a20c5f5796623b066335b12f6355bf50dc0bae5f88e43231237ab53ad6029623475fe943
6
+ metadata.gz: 3f7f0f8aef95c5f79832f18c741f6751e24ff78aa59e739fa44b38d5ae88c5be7f77ae1c293fb07c025e6ed9ed6030354b8b279ed379a01bf970a0efb9d5bd99
7
+ data.tar.gz: 02070acbc4a9ab3925f0bbf85bc2b07069241d46e8ffdf72085e09bd952b3e24d73eceed255c267d2b1de9ed63fb214142413a9d3e0badb3f19b409c5880a4b6
@@ -22,7 +22,7 @@ module Annotated
22
22
  @info = nil
23
23
  @id = nil
24
24
  @self_md5 = nil
25
- @annotation_values.instance_variable_set(:@annotation_md5, nil)
25
+ annotation_values.instance_variable_set(:@annotation_md5, nil)
26
26
  end
27
27
 
28
28
  def annotation_types
data/lib/rbbt/monitor.rb CHANGED
@@ -138,28 +138,32 @@ module Rbbt
138
138
  dirs.collect do |dir|
139
139
  next unless Open.exists? dir
140
140
 
141
+ task_dir_workflows = {}
141
142
  tasks_dirs = if dir == '.'
142
143
  ["."]
143
- else
144
- workflowdirs = if (dir_sub_path = Open.find_repo_dir(workflowdir))
144
+ else
145
+ workflowdirs = if (dir_sub_path = Open.find_repo_dir(workflowdir))
146
+ repo_dir, sub_path = dir_sub_path
147
+ Open.list_repo_files(*dir_sub_path).collect{|f| f.split("/").first}.uniq.collect{|f| File.join(repo_dir, f)}.uniq
148
+ else
149
+ dir.glob("*")
150
+ end
151
+
152
+ workflowdirs.collect do |workflowdir|
153
+ workflow = File.basename(workflowdir)
154
+ next if workflows and not workflows.include? workflow
155
+
156
+ task_dirs = if (dir_sub_path = Open.find_repo_dir(workflowdir))
145
157
  repo_dir, sub_path = dir_sub_path
146
158
  Open.list_repo_files(*dir_sub_path).collect{|f| f.split("/").first}.uniq.collect{|f| File.join(repo_dir, f)}.uniq
147
159
  else
148
- dir.glob("*")
160
+ workflowdir.glob("*")
149
161
  end
150
-
151
- workflowdirs.collect do |workflowdir|
152
- workflow = File.basename(workflowdir)
153
- next if workflows and not workflows.include? workflow
154
-
155
- if (dir_sub_path = Open.find_repo_dir(workflowdir))
156
- repo_dir, sub_path = dir_sub_path
157
- Open.list_repo_files(*dir_sub_path).collect{|f| f.split("/").first}.uniq.collect{|f| File.join(repo_dir, f)}.uniq
158
- else
159
- workflowdir.glob("*")
160
- end
161
- end.compact.flatten
162
- end
162
+ task_dirs.each do |tasks_dir|
163
+ task_dir_workflows[tasks_dir] = workflow
164
+ end
165
+ end.compact.flatten
166
+ end
163
167
 
164
168
  tasks_dirs.collect do |taskdir|
165
169
  task = File.basename(taskdir)
@@ -184,6 +188,7 @@ module Rbbt
184
188
  end
185
189
 
186
190
  files = files.sort_by{|f| Open.mtime(f) || Time.now}
191
+ workflow = task_dir_workflows[taskdir]
187
192
  TSV.traverse files, :type => :array, :into => jobs, :_bar => "Finding jobs in #{ taskdir }" do |file|
188
193
  _files << file
189
194
  if m = file.match(/(.*)\.(info|pid|files)$/)
data/lib/rbbt/resource.rb CHANGED
@@ -281,5 +281,22 @@ url='#{url}'
281
281
 
282
282
  path
283
283
  end
284
+
285
+ def identify(path)
286
+ path = File.expand_path(path)
287
+ resource ||= Rbbt
288
+ (Path::STANDARD_SEARCH + resource.search_order + resource.search_paths.keys).uniq.each do |name|
289
+ pattern = resource.search_paths[name]
290
+ next if patterns.nil?
291
+ if String === pattern and pattern.include?('{')
292
+ regexp = "^" + pattern.gsub(/{([^}]+)}/,'(?<\1>[^/]+)') + "(?:/(?<REST>.*))?/?$"
293
+ if m = path.match(regexp)
294
+ if m["PKGDIR"] == resource.pkgdir
295
+ return self[m["TOPLEVEL"]][m["SUBPATH"]][m["REST"]]
296
+ end
297
+ end
298
+ end
299
+ end
300
+ end
284
301
  end
285
302
 
@@ -83,10 +83,8 @@ module Resource
83
83
  Misc.env_add('CLASSPATH', "#{dir}")
84
84
  end if File.exist? File.join(opt_dir, '.java-classpaths')
85
85
 
86
- Dir.glob(File.join opt_dir, 'jars', '*').each do |file|
87
- dir = line.chomp
88
- dir = File.join(opt_dir, dir) unless dir[0] == "/"
89
- Misc.env_add('CLASSPATH', "#{dir}")
86
+ Dir.glob(File.join opt_dir, 'jars', '*.jar').each do |file|
87
+ Misc.env_add('CLASSPATH', "#{file}")
90
88
  end
91
89
 
92
90
  if File.exist?(File.join(opt_dir, '.post_install')) and File.directory?(File.join(opt_dir, '.post_install'))
data/lib/rbbt/util/cmd.rb CHANGED
@@ -150,14 +150,18 @@ module CMD
150
150
  pids = [pid]
151
151
 
152
152
  if pipe
153
+
154
+ ConcurrentStream.setup sout, :pids => pids, :autojoin => no_wait, :no_fail => no_fail
155
+
153
156
  err_thread = Thread.new do
154
157
  while line = serr.gets
158
+ sout.log = line
155
159
  Log.log "STDERR [#{pid}]: " + line, stderr
156
160
  end if Integer === stderr and log
157
161
  serr.close
158
162
  end
159
163
 
160
- ConcurrentStream.setup sout, :pids => pids, :threads => [in_thread, err_thread, wait_thr].compact, :autojoin => no_wait, :no_fail => no_fail
164
+ sout.threads = [in_thread, err_thread, wait_thr].compact
161
165
 
162
166
  sout
163
167
  else
@@ -7,7 +7,7 @@ module AbortedStream
7
7
  end
8
8
 
9
9
  module ConcurrentStream
10
- attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin, :lockfile, :no_fail, :pair, :thread, :stream_exception
10
+ attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin, :lockfile, :no_fail, :pair, :thread, :stream_exception, :log
11
11
 
12
12
  def self.setup(stream, options = {}, &block)
13
13
 
@@ -81,7 +81,12 @@ module ConcurrentStream
81
81
  begin
82
82
  t.join
83
83
  if Process::Status === t.value
84
- raise ProcessFailed.new "Error joining process #{t.pid} in #{self.filename || self.inspect}" if ! (t.value.success? || no_fail)
84
+ if log
85
+ raise ProcessFailed.new "Error joining process #{t.pid} in #{self.filename || self.inspect}. Last log line: #{log}" if ! (t.value.success? || no_fail)
86
+ else
87
+ raise ProcessFailed.new "Error joining process #{t.pid} in #{self.filename || self.inspect}" if ! (t.value.success? || no_fail)
88
+ end
89
+ raise ProcessFailed.new "Error joining process #{t.pid} in #{self.filename || self.inspect}. Last log line: #{log}" if ! (t.value.success? || no_fail)
85
90
  end
86
91
  rescue Exception
87
92
  if no_fail
@@ -101,7 +106,11 @@ module ConcurrentStream
101
106
  @pids.each do |pid|
102
107
  begin
103
108
  Process.waitpid(pid, Process::WUNTRACED)
104
- stream_raise_exception ProcessFailed.new "Error joining process #{pid} in #{self.filename || self.inspect}" unless $?.success? or no_fail
109
+ if log
110
+ stream_raise_exception ProcessFailed.new "Error joining process #{pid} in #{self.filename || self.inspect}. Last log line: #{log}" unless $?.success? or no_fail
111
+ else
112
+ stream_raise_exception ProcessFailed.new "Error joining process #{pid} in #{self.filename || self.inspect}" unless $?.success? or no_fail
113
+ end
105
114
  rescue Errno::ECHILD
106
115
  end
107
116
  end
@@ -299,6 +299,13 @@ module Open
299
299
  end
300
300
  end
301
301
 
302
+ def self.ssh_open(file)
303
+ m = file.match(/ssh:\/\/([^:]+):(.*)/)
304
+ server = m[1]
305
+ file = m[2]
306
+ CMD.cmd("ssh '#{server}' cat '#{file}'", :pipe => true)
307
+ end
308
+
302
309
  def self.file_write(file, content, mode = 'w')
303
310
  if (dir_sub_path = find_repo_dir(file))
304
311
  dir_sub_path.push content
@@ -507,6 +514,10 @@ module Open
507
514
  !! (file =~ /^(?:https?|ftp):\/\//)
508
515
  end
509
516
 
517
+ def self.ssh?(file)
518
+ !! (file =~ /^ssh:\/\//)
519
+ end
520
+
510
521
  def self.gzip?(file)
511
522
  file = file.find if Path === file
512
523
  !! (file =~ /\.gz$/)
@@ -571,15 +582,23 @@ module Open
571
582
  io = case
572
583
  when (IO === url or StringIO === url)
573
584
  url
574
- when (not remote?(url))
585
+ when (not remote?(url) and not ssh?(url))
575
586
  file_open(url, options[:grep], mode, options[:invert_grep])
576
587
  when (options[:nocache] and options[:nocache] != :update)
577
588
  # What about grep?
578
- wget(url, wget_options)
589
+ if ssh?(url)
590
+ ssh_open(url)
591
+ else
592
+ wget(url, wget_options)
593
+ end
579
594
  when (options[:nocache] != :update and in_cache(url, wget_options))
580
595
  file_open(in_cache(url, wget_options), options[:grep], mode, options[:invert_grep])
581
596
  else
582
- io = wget(url, wget_options)
597
+ io = if ssh?(url)
598
+ ssh_open(url)
599
+ else
600
+ wget(url, wget_options)
601
+ end
583
602
  add_cache(url, io, wget_options)
584
603
  file_open(in_cache(url, wget_options), options[:grep], mode, options[:invert_grep])
585
604
  end
data/lib/rbbt/workflow.rb CHANGED
@@ -4,7 +4,9 @@ require 'rbbt/workflow/step'
4
4
  require 'rbbt/workflow/accessor'
5
5
  require 'rbbt/workflow/doc'
6
6
  require 'rbbt/workflow/examples'
7
- require 'rbbt/workflow/archive'
7
+
8
+ require 'rbbt/workflow/util/archive'
9
+ require 'rbbt/workflow/util/provenance'
8
10
 
9
11
  module Workflow
10
12
 
@@ -48,6 +50,11 @@ module Workflow
48
50
  eval "Object::#{wf_name} = WorkflowRESTClient.new '#{ url }', '#{wf_name}'"
49
51
  end
50
52
 
53
+ def self.require_remote_workflow(wf_name, url)
54
+ require 'rbbt/workflow/remote/client'
55
+ eval "Object::#{wf_name} = WorkflowRemoteClient.new '#{ url }', '#{wf_name}'"
56
+ end
57
+
51
58
  def self.load_workflow_libdir(filename)
52
59
  workflow_lib_dir = File.join(File.dirname(File.expand_path(filename)), 'lib')
53
60
  if File.directory? workflow_lib_dir
@@ -159,9 +166,15 @@ module Workflow
159
166
  end
160
167
  end
161
168
 
162
- if Open.remote? wf_name
169
+ if Open.remote?(wf_name) or Open.ssh?(wf_name)
163
170
  url = wf_name
164
- wf_name = File.basename(url)
171
+
172
+ if Open.ssh?(wf_name)
173
+ wf_name = File.basename(url.split(":").last)
174
+ else
175
+ wf_name = File.basename(url)
176
+ end
177
+
165
178
  begin
166
179
  return require_remote_workflow(wf_name, url)
167
180
  ensure
@@ -13,684 +13,6 @@ module ComputeDependency
13
13
  end
14
14
  end
15
15
 
16
- class Step
17
-
18
- INFO_SERIALIAZER = Marshal
19
-
20
- def self.wait_for_jobs(jobs)
21
- jobs = [jobs] if Step === jobs
22
- begin
23
- threads = []
24
-
25
- threads = jobs.collect do |j|
26
- Thread.new do
27
- begin
28
- j.join unless j.done?
29
- rescue Exception
30
- Log.error "Exception waiting for job: #{Log.color :blue, j.path}"
31
- raise $!
32
- end
33
- end
34
- end
35
-
36
- threads.each{|t| t.join }
37
- rescue Exception
38
- threads.each{|t| t.exit }
39
- jobs.each do |j| j.abort end
40
- raise $!
41
- end
42
- end
43
-
44
- def self.files_dir(path)
45
- path.nil? ? nil : path + '.files'
46
- end
47
-
48
- def self.info_file(path)
49
- path.nil? ? nil : path + '.info'
50
- end
51
-
52
- def self.tmp_path(path)
53
- path = path.find if Path === path
54
- path = File.expand_path(path)
55
- dir = File.dirname(path)
56
- filename = File.basename(path)
57
- File.join(dir, '.' << filename)
58
- end
59
-
60
- def self.md5_file(path)
61
- path.nil? ? nil : path + '.md5'
62
- end
63
-
64
- def self.pid_file(path)
65
- path.nil? ? nil : path + '.pid'
66
- end
67
-
68
- def self.step_info(path)
69
- begin
70
- Open.open(info_file(path), :mode => 'rb') do |f|
71
- INFO_SERIALIAZER.load(f)
72
- end
73
- rescue Exception
74
- Log.exception $!
75
- {}
76
- end
77
- end
78
-
79
- def self.job_name_for_info_file(info_file, extension = nil)
80
- if extension and not extension.empty?
81
- info_file.sub(/\.#{extension}\.info$/,'')
82
- else
83
- info_file.sub(/\.info$/,'')
84
- end
85
- end
86
-
87
- def self.save_job_inputs(job, dir, options = nil)
88
- options = IndiferentHash.setup options.dup if options
89
-
90
- task_name = job.task_name
91
- workflow = job.workflow
92
- workflow = Kernel.const_get workflow if String === workflow
93
- task_info = workflow.task_info(task_name)
94
- input_types = task_info[:input_types]
95
- task_inputs = task_info[:inputs]
96
-
97
- saved = false
98
- job.recursive_inputs.zip(job.recursive_inputs.fields).each do |value,name|
99
- next unless task_inputs.include? name.to_sym
100
- next if options and ! options.include?(name)
101
- next if value.nil?
102
- saved = true
103
- path = File.join(dir, name.to_s)
104
- type = input_types[name].to_s
105
- Log.debug "Saving job input #{name} (#{type}) into #{path}"
106
- case
107
- when Array === value
108
- Open.write(path, value * "\n")
109
- when IO === value
110
- Open.write(path, value)
111
- when type == "file"
112
- if String === value && File.exists?(value)
113
- Open.link(value, path)
114
- else
115
- Open.write(path + '.read', value.to_s)
116
- end
117
- else
118
- Open.write(path, value.to_s)
119
- end
120
- end
121
-
122
- saved
123
- end
124
-
125
- def name
126
- @name ||= path.sub(/.*\/#{Regexp.quote task_name.to_s}\/(.*)/, '\1')
127
- end
128
-
129
- def short_path
130
- [task_name, name] * "/"
131
- end
132
-
133
- def task_name
134
- @task_name ||= task.name
135
- end
136
-
137
- # {{{ INFO
138
-
139
- def info_file
140
- @info_file ||= Step.info_file(path)
141
- end
142
-
143
- def pid_file
144
- @pid_file ||= Step.pid_file(path)
145
- end
146
-
147
- def info_lock
148
- @info_lock = begin
149
- path = Persist.persistence_path(info_file + '.lock', {:dir => Step.lock_dir})
150
- #Lockfile.new path, :refresh => false, :dont_use_lock_id => true
151
- Lockfile.new path
152
- end if @info_lock.nil?
153
- @info_lock
154
- end
155
-
156
- def status_lock
157
- return @mutex
158
- #@status_lock = begin
159
- # path = Persist.persistence_path(info_file + '.status.lock', {:dir => Step.lock_dir})
160
- # Lockfile.new path, :refresh => false, :dont_use_lock_id => true
161
- # end if @status_lock.nil?
162
- #@status_lock
163
- end
164
-
165
- def info(check_lock = true)
166
- return {:status => :noinfo} if info_file.nil? or not Open.exists? info_file
167
- begin
168
- Misc.insist do
169
- begin
170
- return @info_cache if @info_cache and @info_cache_time and Open.ctime(info_file) < @info_cache_time
171
- rescue Exception
172
- raise $!
173
- end
174
-
175
- begin
176
- @info_cache = Misc.insist(3, 1.6, info_file) do
177
- Misc.insist(2, 1, info_file) do
178
- Misc.insist(3, 0.2, info_file) do
179
- raise TryAgain, "Info locked" if check_lock and info_lock.locked?
180
- info_lock.lock if check_lock and false
181
- begin
182
- Open.open(info_file, :mode => 'rb') do |file|
183
- INFO_SERIALIAZER.load(file) #|| {}
184
- end
185
- ensure
186
- info_lock.unlock if check_lock and false
187
- end
188
- end
189
- end
190
- end
191
- @info_cache_time = Time.now
192
- @info_cache
193
- end
194
- end
195
- rescue Exception
196
- Log.debug{"Error loading info file: " + info_file}
197
- Log.exception $!
198
- Open.rm info_file
199
- Misc.sensiblewrite(info_file, INFO_SERIALIAZER.dump({:status => :error, :messages => ["Info file lost"]}))
200
- raise $!
201
- end
202
- end
203
-
204
- def init_info(force = false)
205
- return nil if @exec or info_file.nil? or (Open.exists?(info_file) and ! force)
206
- Open.lock(info_file, :lock => info_lock) do
207
- i = {:status => :waiting, :pid => Process.pid, :path => path}
208
- i[:dependencies] = dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]} if dependencies
209
- @info_cache = i
210
- Misc.sensiblewrite(info_file, INFO_SERIALIAZER.dump(i), :force => true, :lock => false)
211
- @info_cache_time = Time.now
212
- end
213
- end
214
-
215
- def set_info(key, value)
216
- return nil if @exec or info_file.nil?
217
- return nil if ! writable?
218
- value = Annotated.purge value if defined? Annotated
219
- Open.lock(info_file, :lock => info_lock) do
220
- i = info(false).dup
221
- i[key] = value
222
- @info_cache = i
223
- dump = INFO_SERIALIAZER.dump(i)
224
- Misc.sensiblewrite(info_file, dump, :force => true, :lock => false)
225
- @info_cache_time = Time.now
226
- value
227
- end
228
- end
229
-
230
- def merge_info(hash)
231
- return nil if @exec or info_file.nil?
232
- return nil if ! writable?
233
- value = Annotated.purge value if defined? Annotated
234
- Open.lock(info_file, :lock => info_lock) do
235
- i = info(false)
236
- i.merge! hash
237
- @info_cache = i
238
- dump = INFO_SERIALIAZER.dump(i)
239
- Misc.sensiblewrite(info_file, dump, :force => true, :lock => false)
240
- @info_cache_time = Time.now
241
- value
242
- end
243
- end
244
-
245
- def status
246
- begin
247
- info[:status]
248
- rescue Exception
249
- Log.error "Exception reading status: #{$!.message}"
250
- :error
251
- end
252
- end
253
-
254
- def status=(status)
255
- set_info(:status, status)
256
- end
257
-
258
- def messages
259
- if messages = info[:messages]
260
- messages
261
- else
262
- set_info(:messages, []) if self.respond_to?(:set_info)
263
- end
264
- end
265
-
266
- def message(message)
267
- message = Log.uncolor(message)
268
- set_info(:messages, (messages || []) << message)
269
- end
270
-
271
- def self.status_color(status)
272
- status = status.split(">").last
273
- case status
274
- when "starting"
275
- :yellow
276
- when "error", "aborted"
277
- :red
278
- when "done"
279
- :green
280
- else
281
- :cyan
282
- end
283
- end
284
-
285
- def self.log_block(status, message, path, &block)
286
- start = Time.now
287
- status = status.to_s
288
- status_color = self.status_color status
289
-
290
- Log.info do
291
- now = Time.now
292
- str = Log.color :reset
293
- str << "#{ Log.color status_color, status}"
294
- str << ": #{ message }" if message
295
- str << " -- #{Log.color :blue, path.to_s}" if path
296
- str << " #{Log.color :yellow, Process.pid}"
297
- str
298
- end
299
- res = yield
300
- eend = Time.now
301
- Log.info do
302
- now = Time.now
303
- str = "#{ Log.color :cyan, status.to_s } +#{Log.color :green, "%.2f" % (eend - start)}"
304
- str << " -- #{Log.color :blue, path.to_s}" if path
305
- str << " #{Log.color :yellow, Process.pid}"
306
- str
307
- end
308
- res
309
- end
310
-
311
- def self.log_string(status, message, path)
312
- Log.info do
313
-
314
- status = status.to_s
315
- status_color = self.status_color status
316
-
317
- str = Log.color :reset
318
- str << "#{ Log.color status_color, status}"
319
- str << ": #{ message }" if message
320
- str << " -- #{Log.color :blue, path.to_s}" if path
321
- str << " #{Log.color :yellow, Process.pid}"
322
- str
323
- end
324
- end
325
-
326
- def self.log_progress(status, options = {}, path = nil, &block)
327
- options = Misc.add_defaults options, :severity => Log::INFO, :file => path
328
- max = Misc.process_options options, :max
329
- Log::ProgressBar.with_bar(max, options) do |bar|
330
- begin
331
- res = yield bar
332
- raise KeepBar.new res if IO === res
333
- res
334
- rescue
335
- Log.exception $!
336
- raise $!
337
- end
338
- end
339
- end
340
-
341
- def log_progress(status, options = {}, &block)
342
- Step.log_progress(status, options, file(:progress), &block)
343
- end
344
-
345
- def progress_bar(msg = "Progress", options = nil)
346
- if Hash === msg and options.nil?
347
- options = msg
348
- msg = nil
349
- end
350
- options = {} if options.nil?
351
-
352
- max = options[:max]
353
- Log::ProgressBar.new_bar(max, {:desc => msg, :file => file(:progress)}.merge(options))
354
- end
355
-
356
- def self.log(status, message, path, &block)
357
- if block
358
- if Hash === message
359
- log_progress(status, message, path, &block)
360
- else
361
- log_block(status, message, path, &block)
362
- end
363
- else
364
- log_string(status, message, path)
365
- end
366
- end
367
-
368
- def log(status, message = nil, &block)
369
- self.status = status
370
- if message
371
- self.message Log.uncolor(message)
372
- end
373
- Step.log(status, message, path, &block)
374
- end
375
-
376
- def exception(ex, msg = nil)
377
- ex_class = ex.class.to_s
378
- backtrace = ex.backtrace if ex.respond_to?(:backtrace)
379
- message = ex.message if ex.respond_to?(:message)
380
- set_info :backtrace, backtrace
381
- set_info :exception, {:class => ex_class, :message => message, :backtrace => backtrace}
382
- if msg.nil?
383
- log :error, "#{ex_class} -- #{message}"
384
- else
385
- log :error, "#{msg} -- #{message}"
386
- end
387
- self._abort
388
- end
389
-
390
- def get_exception
391
- if info[:exception].nil?
392
- return Aborted if aborted?
393
- return Exception.new(messages.last) if error?
394
- Exception.new ""
395
- else
396
- ex_class, ex_message, ex_backtrace = info[:exception].values_at :class, :message, :backtrace
397
- begin
398
- klass = Kernel.const_get(ex_class)
399
- ex = klass.new ex_message
400
- ex.set_backtrace ex_backtrace unless ex_backtrace.nil? or ex_backtrace.empty?
401
- ex
402
- rescue
403
- Log.exception $!
404
- Exception.new ex_message
405
- end
406
- end
407
- end
408
-
409
- def recoverable_error?
410
- return true if aborted?
411
- return false unless error?
412
- begin
413
- return true unless info[:exception]
414
- klass = Kernel.const_get(info[:exception][:class])
415
- ! (klass <= RbbtException)
416
- rescue Exception
417
- true
418
- end
419
- end
420
-
421
- def started?
422
- Open.exists?(path) or (Open.exists?(pid_file) && Open.exists?(info_file))
423
- end
424
-
425
- def waiting?
426
- Open.exists?(info_file) and not started?
427
- end
428
-
429
- def dirty_files
430
- rec_dependencies = self.rec_dependencies
431
- return [] if rec_dependencies.empty?
432
- canfail_paths = self.canfail_paths
433
- dirty_files = rec_dependencies.reject{|dep|
434
- (defined?(WorkflowRESTClient) && WorkflowRESTClient::RemoteStep === dep) ||
435
- ! Open.exists?(dep.info_file) ||
436
- (dep.path && (Open.exists?(dep.path) || Open.remote?(dep.path))) ||
437
- ((dep.error? || dep.aborted? || dep.waiting?) && (! dep.recoverable_error? || canfail_paths.include?(dep.path)))
438
- }
439
- end
440
-
441
- def dirty?
442
- return true if Open.exists?(pid_file) && ! ( Open.exists?(info_file) || done? )
443
- return false unless done? || status == :done
444
- return false unless ENV["RBBT_UPDATE"] == "true"
445
-
446
- status = self.status
447
-
448
- if done? and not (status == :done or status == :ending or status == :producing) and not status == :noinfo
449
- return true
450
- end
451
-
452
- if status == :done and not done?
453
- return true
454
- end
455
-
456
- if dirty_files.any?
457
- Log.low "Some dirty files found for #{self.path}: #{Misc.fingerprint dirty_files}"
458
- true
459
- else
460
- ! self.updated?
461
- end
462
- end
463
-
464
- def done?
465
- path and Open.exists? path
466
- end
467
-
468
- def streaming?
469
- (IO === @result) or (not @saved_stream.nil?) or status == :streaming
470
- end
471
-
472
- def noinfo?
473
- status == :noinfo
474
- end
475
-
476
- def running?
477
- return false if ! (started? || status == :ending)
478
- pid = info[:pid]
479
- return nil if pid.nil?
480
-
481
- return false if done? or error? or aborted?
482
-
483
- if Misc.pid_exists?(pid)
484
- pid
485
- else
486
- done? or error? or aborted?
487
- end
488
- end
489
-
490
- def stalled?
491
- started? && ! (done? || running? || done? || error? || aborted?)
492
- end
493
-
494
- def missing?
495
- status == :done && ! Open.exists?(path)
496
- end
497
-
498
- def error?
499
- status == :error
500
- end
501
-
502
- def nopid?
503
- pid = info[:pid] || Open.exists?(pid_file)
504
- ! pid && ! (status.nil? || status == :aborted || status == :done || status == :error)
505
- end
506
-
507
- def aborted?
508
- status = self.status
509
- status == :aborted || ((status != :noinfo && status != :setup && status != :noinfo) && nopid?)
510
- end
511
-
512
- # {{{ INFO
513
-
514
- def files_dir
515
- @files_dir ||= Step.files_dir path
516
- end
517
-
518
- def tmp_path
519
- @tmp_path ||= Step.tmp_path path
520
- end
521
-
522
- def files
523
- files = Dir.glob(File.join(files_dir, '**', '*')).reject{|path| File.directory? path}.collect do |path|
524
- Misc.path_relative_to(files_dir, path)
525
- end
526
- files
527
- end
528
-
529
- def file(name)
530
- Path.setup(File.join(files_dir, name.to_s))
531
- end
532
-
533
- def save_file(name, content)
534
- content = case
535
- when String === content
536
- content
537
- when Array === content
538
- content * "\n"
539
- when TSV === content
540
- content.to_s
541
- when Hash === content
542
- content.collect{|*p| p * "\t"} * "\n"
543
- else
544
- content.to_s
545
- end
546
- Open.write(file(name), content)
547
- end
548
-
549
- def load_file(name, type = nil, options = {})
550
- if type.nil? and name =~ /.*\.(\w+)$/
551
- extension = name.match(/.*\.(\w+)$/)[1]
552
- case extension
553
- when "tc"
554
- type = :tc
555
- when "tsv"
556
- type = :tsv
557
- when "list", "ary", "array"
558
- type = :array
559
- when "yaml"
560
- type = :yaml
561
- when "marshal"
562
- type = :marshal
563
- else
564
- type = :other
565
- end
566
- else
567
- type ||= :other
568
- end
569
-
570
- case type.to_sym
571
- when :tc
572
- Persist.open_tokyocabinet(file(name), false)
573
- when :tsv
574
- TSV.open Open.open(file(name)), options
575
- when :array
576
- #Open.read(file(name)).split /\n|,\s*/
577
- Open.read(file(name)).split "\n"
578
- when :yaml
579
- YAML.load(Open.open(file(name)))
580
- when :marshal
581
- Marshal.load(Open.open(file(name)))
582
- else
583
- Open.read(file(name))
584
- end
585
- end
586
-
587
- def provenance
588
- provenance = {}
589
- dependencies.each do |dep|
590
- next unless dep.path.exists?
591
- if Open.exists? dep.info_file
592
- provenance[dep.path] = dep.provenance if Open.exists? dep.path
593
- else
594
- provenance[dep.path] = nil
595
- end
596
- end
597
- {:inputs => info[:inputs], :provenance => provenance}
598
- end
599
-
600
- def provenance_paths
601
- provenance = {}
602
- dependencies.each do |dep|
603
- provenance[dep.path] = dep.provenance_paths if Open.exists? dep.path
604
- end
605
- provenance
606
- end
607
-
608
- def config(key, *tokens)
609
- options = tokens.pop if Hash === tokens.last
610
- options ||= {}
611
-
612
- new_tokens = []
613
- if workflow
614
- workflow_name = workflow.to_s
615
- new_tokens << ("workflow:" << workflow_name)
616
- new_tokens << ("task:" << workflow_name << "#" << task_name.to_s)
617
- end
618
- new_tokens << ("task:" << task_name.to_s)
619
-
620
- Rbbt::Config.get(key, tokens + new_tokens, options)
621
- end
622
-
623
- def access
624
- CMD.cmd("touch -c -h -a #{self.path} #{self.info_file}")
625
- end
626
-
627
- def rec_access
628
- access
629
- rec_dependencies.each do |dep|
630
- dep.access
631
- end
632
- end
633
-
634
- def monitor_stream(stream, options = {}, &block)
635
- case options[:bar]
636
- when TrueClass
637
- bar = progress_bar
638
- when Hash
639
- bar = progress_bar options[:bar]
640
- when Numeric
641
- bar = progress_bar :max => options[:bar]
642
- else
643
- bar = options[:bar]
644
- end
645
-
646
- out = if bar.nil?
647
- Misc.line_monitor_stream stream, &block
648
- elsif (block.nil? || block.arity == 0)
649
- Misc.line_monitor_stream stream do
650
- bar.tick
651
- end
652
- elsif block.arity == 1
653
- Misc.line_monitor_stream stream do |line|
654
- bar.tick
655
- block.call line
656
- end
657
- elsif block.arity == 2
658
- Misc.line_monitor_stream stream do |line|
659
- block.call line, bar
660
- end
661
- end
662
-
663
- ConcurrentStream.setup(out, :abort_callback => Proc.new{
664
- Log::ProgressBar.remove_bar(bar, true) if bar
665
- }, :callback => Proc.new{
666
- Log::ProgressBar.remove_bar(bar) if bar
667
- })
668
-
669
- bgzip = (options[:compress] || options[:gzip]).to_s == 'bgzip'
670
- bgzip = true if options[:bgzip]
671
-
672
- gzip = true if options[:compress] || options[:gzip]
673
- if bgzip
674
- Open.bgzip(out)
675
- elsif gzip
676
- Open.gzip(out)
677
- else
678
- out
679
- end
680
- end
681
-
682
- def relocated?
683
- done? && info[:path] && info[:path] != path
684
- end
685
-
686
- def knowledge_base(organism = nil)
687
- @_kb ||= begin
688
- kb_dir = self.file('knowledge_base')
689
- KnowledgeBase.new kb_dir, organism
690
- end
691
- end
692
-
693
- end
694
16
 
695
17
  module Workflow
696
18
 
@@ -1162,6 +484,4 @@ module Workflow
1162
484
  def task_exports
1163
485
  [exec_exports, synchronous_exports, asynchronous_exports, stream_exports].compact.flatten.uniq
1164
486
  end
1165
-
1166
-
1167
487
  end