rbbt-util 5.26.77 → 5.26.78

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 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