rbbt-util 5.23.21 → 5.23.22

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
  SHA1:
3
- metadata.gz: '08b49f3913846e398ef9edb5607ffed78089e2ff'
4
- data.tar.gz: 775643f2bad7a86d757adbc41c7393a5cbb5f8af
3
+ metadata.gz: f00bbaf07372fc3c72d60b438ce701b6336e21bb
4
+ data.tar.gz: f5e9cbffdc19992c1f2d606e7cef8963f84df2b0
5
5
  SHA512:
6
- metadata.gz: 98ec1677f453ffcaae30565bf6fdc497e1b96bb53dc6972e2ce50a6989aa25b817bc960cb9d4d52e937464c8a11989dc3cd1b53324773d7fa376a0c5f1a7cfb2
7
- data.tar.gz: d3b5a410013005ef9ade2b2aa234f895b5c6490090fbbc97b2082e4a8b25e5a4a11031487db3fd6d43d81dde384abb3b5fe565dd55f83dca908b94335067821d
6
+ metadata.gz: 8d087babf2c286d041e1585db266cd8abd1a39672eab0a965f772b00b9866eafb0ab27bb36242bb4fe4e344733d4f7a5a26033013a20d4f64524daeae0a493db
7
+ data.tar.gz: 28b6c11840f431d28c6e6bd32b75d72ce6eced2cf12d4f53661e5d316ff893c6c1e9e8d19d73cc78a235798ed9faf64dd389300e9be6e12decf743b335e31266
data/lib/rbbt/persist.rb CHANGED
@@ -29,8 +29,8 @@ module Persist
29
29
  return true if not Open.exists? file
30
30
  path = path.find if Path === path
31
31
  file = file.find if Path === file
32
- patht = File.mtime(path)
33
- filet = File.mtime(file)
32
+ patht = Open.mtime(path)
33
+ filet = Open.mtime(file)
34
34
  diff = patht - filet
35
35
  return diff if diff < 0
36
36
  return false
@@ -109,7 +109,7 @@ module Persist
109
109
  when :string, :text
110
110
  Open.read(path)
111
111
  when :binary
112
- f = File.open(path, 'rb')
112
+ f = Open.open(path, 'rb')
113
113
  res = f.read
114
114
  f.close
115
115
  res.force_encoding("ASCII-8BIT") if res.respond_to? :force_encoding
@@ -1,3 +1,4 @@
1
+ require 'base64'
1
2
  module TSV
2
3
 
3
4
  class CleanSerializer
@@ -5,6 +6,11 @@ module TSV
5
6
  def self.load(o); o end
6
7
  end
7
8
 
9
+ class BinarySerializer
10
+ def self.dump(o); [o].pack('m'); end
11
+ def self.load(str); str.unpack('m').first; end
12
+ end
13
+
8
14
  class IntegerSerializer
9
15
  def self.dump(i); [i].pack("l"); end
10
16
  def self.load(str); str.unpack("l").first; end
@@ -103,6 +109,7 @@ module TSV
103
109
  :flat => StringArraySerializer,
104
110
  :double => StringDoubleArraySerializer,
105
111
  :clean => CleanSerializer,
112
+ :binary => BinarySerializer,
106
113
  :tsv => TSVSerializer,
107
114
  :marshal_tsv => TSVMarshalSerializer
108
115
  }
data/lib/rbbt/tsv/util.rb CHANGED
@@ -106,7 +106,7 @@ module TSV
106
106
  end
107
107
  file
108
108
  when String
109
- if Open.remote?(file) or File.exist? file
109
+ if Open.remote?(file) or Open.exist? file
110
110
  Open.open(file, open_options)
111
111
  else
112
112
  StringIO.new file
@@ -80,6 +80,7 @@ module Log
80
80
  max_history ||= case
81
81
  when @ticks > 20
82
82
  count = @ticks - @last_count
83
+ count = 1 if count == 0
83
84
  if @max
84
85
  times = @max / count
85
86
  num = times / 20
@@ -162,6 +162,7 @@ def self.add_libdir(dir=nil)
162
162
  end
163
163
  raise $!
164
164
  rescue Exception
165
+ Log.exception $! if ENV["RBBT_LOG_INSIST"] == 'true'
165
166
  if msg
166
167
  Log.warn("Insisting after exception: #{$!.class} #{$!.message} -- #{msg}")
167
168
  elsif FalseClass === msg
@@ -45,7 +45,7 @@ module Misc
45
45
  when nil
46
46
  "nil"
47
47
  when (defined? Step and Step)
48
- "<Step:" << (obj.path || Misc.fingerprint([obj.task.name, obj.inputs])) << ">"
48
+ "<Step:" << (obj.short_path || Misc.fingerprint([obj.task.name, obj.inputs])) << ">"
49
49
  when TrueClass
50
50
  "true"
51
51
  when FalseClass
@@ -295,7 +295,7 @@ module Misc
295
295
  "<IO:" << obj.path << "--" << mtime_str(obj.path) << ">"
296
296
  end
297
297
  when (defined? Step and Step)
298
- "<IO:" << obj.path << ">"
298
+ "<IO:" << obj.short_path << ">"
299
299
  when IO
300
300
  if obj.respond_to? :filename and obj.filename
301
301
  "<IO:" << obj.filename << "--" << mtime_str(obj.filename) << ">"
@@ -304,7 +304,7 @@ module Misc
304
304
  into = into.find if Path === into
305
305
  if String === into
306
306
  dir = File.dirname(into)
307
- FileUtils.mkdir_p dir unless Open.exists?(dir)
307
+ Open.mkdir dir unless Open.exists?(dir)
308
308
  into_path, into = into, Open.open(into, :mode => 'w')
309
309
  end
310
310
  into.sync = true if IO === into
@@ -405,10 +405,10 @@ module Misc
405
405
  Open.mv tmp_path, path, lock_options
406
406
  end
407
407
  rescue Exception
408
- raise $! unless File.exist? path
408
+ raise $! unless Open.exists? path
409
409
  end
410
410
 
411
- FileUtils.touch path if File.exist? path
411
+ Open.touch path if Open.exists? path
412
412
  content.join if content.respond_to? :join and not (content.respond_to?(:joined?) and content.joined?)
413
413
 
414
414
  Open.notify_write(path)
@@ -137,11 +137,14 @@ module Open
137
137
  end
138
138
  end
139
139
 
140
+ def self.clear_dir_repos
141
+ @@repos.clear if defined? @@repos and @@repos
142
+ end
140
143
  def self.get_repo_from_dir(dir)
141
- @repos ||= {}
142
- @repos[dir] ||= begin
144
+ @@repos ||= {}
145
+ @@repos[dir] ||= begin
143
146
  repo_path = File.join(dir, '.file_repo')
144
- Persist.open_tokyocabinet(repo_path, false, :clean,TokyoCabinet::BDB )
147
+ Persist.open_tokyocabinet(repo_path, false, :clean, TokyoCabinet::BDB )
145
148
  end
146
149
  end
147
150
 
@@ -149,13 +152,45 @@ module Open
149
152
  repo = get_repo_from_dir(dir)
150
153
  repo.read_and_close do
151
154
  content = repo[sub_path]
152
- content.nil? ? nil : StringIO.new(content)
155
+ content.nil? ? nil : StringIO.new(content).tap{|o| o.binmode }
156
+ end
157
+ end
158
+
159
+ def self.get_time_from_repo(dir, sub_path)
160
+ repo = get_repo_from_dir(dir)
161
+ time = repo.read_and_close do
162
+ Time.at(repo['.time.' + sub_path].to_i)
163
+ end
164
+ time
165
+ end
166
+
167
+ def self.get_atime_from_repo(dir, sub_path)
168
+ repo = get_repo_from_dir(dir)
169
+ File.atime(repo.persistance_path)
170
+ end
171
+
172
+ def self.writable_repo?(dir, sub_path)
173
+ repo = get_repo_from_dir(dir)
174
+ begin
175
+ repo.write_and_close do
176
+ end
177
+ true
178
+ rescue
179
+ false
180
+ end
181
+ end
182
+
183
+ def self.set_time_from_repo(dir, sub_path)
184
+ repo = get_repo_from_dir(dir)
185
+ repo.read_and_close do
186
+ repo['.time.' + sub_path] = Time.now.to_i.to_s
153
187
  end
154
188
  end
155
189
 
156
190
  def self.save_content_in_repo(dir, sub_path, content)
157
191
  repo = get_repo_from_dir(dir)
158
192
  repo.write_and_close do
193
+ repo['.time.' + sub_path] = Time.now.to_i.to_s
159
194
  repo[sub_path] = content
160
195
  end
161
196
  end
@@ -174,15 +209,24 @@ module Open
174
209
  def self.exists_in_repo(dir, sub_path, content)
175
210
  repo = get_repo_from_dir(dir)
176
211
  repo.read_and_close do
177
- repo.include? sub_path
212
+ repo.include?(sub_path) && ! repo[sub_path].nil?
178
213
  end
179
214
  end
180
215
 
181
216
  def self.find_repo_dir(file)
182
217
  self.repository_dirs.each do |dir|
183
- if file.start_with? dir
184
- sub_path = file.to_s[dir.length..-1]
185
- return [dir, sub_path]
218
+ dir = dir + '/' unless dir[-1] == "/"
219
+
220
+ begin
221
+ if file.start_with? dir
222
+ sub_path = file.to_s[dir.length..-1]
223
+ return [dir, sub_path]
224
+ else
225
+ if Path === file and (ffile = file.find).start_with? dir
226
+ sub_path = ffile.to_s[dir.length..-1]
227
+ return [dir, sub_path]
228
+ end
229
+ end
186
230
  end
187
231
  end
188
232
  nil
@@ -206,7 +250,21 @@ module Open
206
250
 
207
251
  def self.file_open(file, grep, mode = 'r', invert_grep = false)
208
252
  if (dir_sub_path = find_repo_dir(file))
209
- stream = get_stream_from_repo(*dir_sub_path)
253
+ if mode.include? 'w'
254
+
255
+ stream = StringIO.new
256
+ class << stream
257
+ attr_accessor :dir_sub_path
258
+ def close
259
+ self.rewind
260
+ Open.save_content_in_repo(*dir_sub_path, self.read)
261
+ end
262
+ end
263
+ stream.dir_sub_path = dir_sub_path
264
+
265
+ else
266
+ stream = get_stream_from_repo(*dir_sub_path)
267
+ end
210
268
  else
211
269
  file = file.find if Path === file
212
270
  stream = File.open(file, mode)
@@ -237,9 +295,13 @@ module Open
237
295
  end
238
296
 
239
297
  def self.mkdir(target)
240
- target = target.find if Path === target
241
- if not File.exists?(target)
242
- FileUtils.mkdir_p target
298
+ if (dir_sub_path = find_repo_dir(target))
299
+ nil
300
+ else
301
+ target = target.find if Path === target
302
+ if ! File.exists?(target)
303
+ FileUtils.mkdir_p target
304
+ end
243
305
  end
244
306
  end
245
307
 
@@ -279,13 +341,47 @@ module Open
279
341
  end
280
342
  end
281
343
 
344
+ #def self.cp(source, target, options = {})
345
+ # source = source.find if Path === source
346
+ # target = target.find if Path === target
347
+
348
+ # FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
349
+ # FileUtils.rm target if File.exists?(target)
350
+ # FileUtils.cp source, target
351
+ #end
352
+
282
353
  def self.cp(source, target, options = {})
283
- source = source.find if Path === source
284
- target = target.find if Path === target
354
+ dir_sub_path_source = find_repo_dir(source)
355
+ dir_sub_path_target = find_repo_dir(target)
285
356
 
286
- FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
287
- FileUtils.rm target if File.exists?(target)
288
- FileUtils.cp source, target
357
+ if dir_sub_path_source.nil? and dir_sub_path_target.nil?
358
+ FileUtils.mkdir_p File.dirname(target) unless File.exist? File.dirname(target)
359
+ tmp_target = File.join(File.dirname(target), '.tmp_mv.' + File.basename(target))
360
+ FileUtils.cp source, tmp_target
361
+ FileUtils.cp tmp_target, target
362
+ return
363
+ end
364
+
365
+ if dir_sub_path_source.nil?
366
+ save_content_in_repo(dir_sub_path_target[0], dir_sub_path_target[1], Open.read(source, :mode => 'rb', :nofix => true))
367
+ return nil
368
+ end
369
+
370
+ if dir_sub_path_target.nil?
371
+ Open.write(target, get_stream_from_repo(dir_sub_path_source))
372
+ return nil
373
+ end
374
+
375
+ repo_source = get_repo_from_dir(dir_sub_path_source[0])
376
+ repo_target = get_repo_from_dir(dir_sub_path_target[0])
377
+
378
+ repo_source.read_and_close do
379
+ repo_target.write_and_close do
380
+ repo_source[dir_sub_path_source[1]] = repo_target[dir_sub_path_target[1]]
381
+ end
382
+ end
383
+
384
+ return nil
289
385
  end
290
386
 
291
387
  def self.mv(source, target, options = {})
@@ -301,7 +397,7 @@ module Open
301
397
  end
302
398
 
303
399
  if dir_sub_path_source.nil?
304
- save_content_in_repo(dir_sub_path_target[0], dir_sub_path_target[1], Open.read(source))
400
+ save_content_in_repo(dir_sub_path_target[0], dir_sub_path_target[1], Open.read(source, :mode => 'rb', :nofix => true))
305
401
  return nil
306
402
  end
307
403
 
@@ -317,6 +413,7 @@ module Open
317
413
  repo_target.write_and_close do
318
414
  repo_source[dir_sub_path_source[1]] = repo_target[dir_sub_path_target[1]]
319
415
  end
416
+ repo_source.delete dir_sub_path_source[1]
320
417
  end
321
418
 
322
419
  return nil
@@ -331,6 +428,9 @@ module Open
331
428
  File.exist?(file) || File.symlink?(file)
332
429
  end
333
430
  end
431
+ class << self
432
+ alias exist? exists?
433
+ end
334
434
 
335
435
  def self.lock(file, options = {}, &block)
336
436
  if file and (dir_sub_path = find_repo_dir(file))
@@ -485,7 +585,7 @@ module Open
485
585
  end
486
586
 
487
587
  def self.can_open?(file)
488
- String === file and (File.exist?(file) or remote?(file))
588
+ String === file and (Open.exist?(file) or remote?(file))
489
589
  end
490
590
 
491
591
  def self.read(file, options = {}, &block)
@@ -511,13 +611,14 @@ module Open
511
611
  def self.notify_write(file)
512
612
  begin
513
613
  notification_file = file + '.notify'
514
- if File.exist? notification_file
614
+ if Open.exists? notification_file
515
615
  key = Open.read(notification_file).strip
516
616
  key = nil if key.empty?
517
617
  Misc.notify("Wrote " << file, nil, key)
518
- FileUtils.rm notification_file
618
+ Open.rm notification_file
519
619
  end
520
620
  rescue
621
+ Log.exception $!
521
622
  Log.warn "Error notifying write of #{ file }"
522
623
  end
523
624
  end
@@ -528,48 +629,106 @@ module Open
528
629
  file = file.find(options[:where]) if Path === file
529
630
  mode = Misc.process_options options, :mode
530
631
 
531
- FileUtils.mkdir_p File.dirname(file)
532
- case
533
- when block_given?
534
- begin
535
- f = File.open(file, mode)
632
+ if (dir_sub_path = find_repo_dir(file))
633
+ content = case content
634
+ when String
635
+ content
636
+ when nil
637
+ if block_given?
638
+ yield
639
+ else
640
+ ""
641
+ end
642
+ else
643
+ content.read
644
+ end
645
+ dir_sub_path.push content
646
+ save_content_in_repo(*dir_sub_path)
647
+ else
648
+ FileUtils.mkdir_p File.dirname(file)
649
+ case
650
+ when block_given?
536
651
  begin
537
- yield f
538
- ensure
539
- f.close unless f.closed?
652
+ f = File.open(file, mode)
653
+ begin
654
+ yield f
655
+ ensure
656
+ f.close unless f.closed?
657
+ end
658
+ rescue Exception
659
+ FileUtils.rm file if File.exist? file
660
+ raise $!
540
661
  end
541
- rescue Exception
542
- FileUtils.rm file if File.exist? file
543
- raise $!
544
- end
545
- when content.nil?
546
- File.open(file, mode){|f| f.write "" }
547
- when String === content
548
- file_write(file, content, mode)
549
- else
550
- begin
551
- File.open(file, mode) do |f|
552
- f.flock(File::LOCK_EX)
553
- while block = content.read(Misc::BLOCK_SIZE)
554
- f.write block
662
+ when content.nil?
663
+ File.open(file, mode){|f| f.write "" }
664
+ when String === content
665
+ file_write(file, content, mode)
666
+ else
667
+ begin
668
+ File.open(file, mode) do |f|
669
+ f.flock(File::LOCK_EX)
670
+ while block = content.read(Misc::BLOCK_SIZE)
671
+ f.write block
672
+ end
673
+ f.flock(File::LOCK_UN)
555
674
  end
556
- f.flock(File::LOCK_UN)
675
+ rescue Exception
676
+ FileUtils.rm_rf file if File.exist? file
677
+ raise $!
557
678
  end
558
- rescue Exception
559
- FileUtils.rm_rf file if File.exist? file
560
- raise $!
679
+ content.close
561
680
  end
562
- content.close
563
681
  end
682
+
564
683
  notify_write(file)
565
684
  end
566
685
 
567
686
  def self.writable?(path)
568
687
  path = path.find if Path === path
569
- if File.exists?(path)
570
- File.writable?(path)
688
+ if (dir_sub_path = find_repo_dir(path))
689
+ writable_repo?(*dir_sub_path)
690
+ else
691
+ if File.exists?(path)
692
+ File.writable?(path)
693
+ else
694
+ File.writable?(File.dirname(File.expand_path(path)))
695
+ end
696
+ end
697
+ end
698
+
699
+ def self.ctime(file)
700
+ if (dir_sub_path = find_repo_dir(file))
701
+ get_time_from_repo(*dir_sub_path)
702
+ else
703
+ file = file.find if Path === file
704
+ File.ctime(file)
705
+ end
706
+ end
707
+
708
+ def self.mtime(file)
709
+ if (dir_sub_path = find_repo_dir(file))
710
+ get_time_from_repo(*dir_sub_path)
711
+ else
712
+ file = file.find if Path === file
713
+ File.mtime(file)
714
+ end
715
+ end
716
+
717
+ def self.atime(file)
718
+ if (dir_sub_path = find_repo_dir(file))
719
+ get_atime_from_repo(*dir_sub_path)
571
720
  else
572
- File.writable?(File.dirname(File.expand_path(path)))
721
+ file = file.find if Path === file
722
+ File.atime(file)
723
+ end
724
+ end
725
+
726
+ def self.touch(file)
727
+ if (dir_sub_path = find_repo_dir(file))
728
+ set_time_from_repo(*dir_sub_path)
729
+ else
730
+ file = file.find if Path === file
731
+ FileUtils.touch(file)
573
732
  end
574
733
  end
575
734
  end
@@ -15,7 +15,6 @@ end
15
15
 
16
16
  class Step
17
17
 
18
-
19
18
  INFO_SERIALIAZER = Marshal
20
19
 
21
20
  def self.wait_for_jobs(jobs)
@@ -64,7 +63,7 @@ class Step
64
63
 
65
64
  def self.step_info(path)
66
65
  begin
67
- Open.open(info_file(path)) do |f|
66
+ Open.open(info_file(path), :mode => 'rb') do |f|
68
67
  INFO_SERIALIAZER.load(f)
69
68
  end
70
69
  rescue Exception
@@ -126,7 +125,7 @@ class Step
126
125
  begin
127
126
  Misc.insist do
128
127
  begin
129
- return @info_cache if @info_cache and @info_cache_time and File.ctime(info_file) < @info_cache_time
128
+ return @info_cache if @info_cache and @info_cache_time and Open.ctime(info_file) < @info_cache_time
130
129
  rescue Exception
131
130
  raise $!
132
131
  end
@@ -138,7 +137,7 @@ class Step
138
137
  raise TryAgain, "Info locked" if check_lock and info_lock.locked?
139
138
  info_lock.lock if check_lock and false
140
139
  begin
141
- Open.open(info_file) do |file|
140
+ Open.open(info_file, :mode => 'rb') do |file|
142
141
  INFO_SERIALIAZER.load(file) #|| {}
143
142
  end
144
143
  ensure
@@ -179,12 +178,8 @@ class Step
179
178
  i = info(false).dup
180
179
  i[key] = value
181
180
  @info_cache = i
182
- Misc.sensiblewrite(info_file, INFO_SERIALIAZER.dump(i), :force => true, :lock => false)
183
- Misc.insist do
184
- Open.open(info_file) do |file|
185
- INFO_SERIALIAZER.load(file)
186
- end
187
- end
181
+ dump = INFO_SERIALIAZER.dump(i)
182
+ Misc.sensiblewrite(info_file, dump, :force => true, :lock => false)
188
183
  @info_cache_time = Time.now
189
184
  value
190
185
  end
@@ -192,12 +187,14 @@ class Step
192
187
 
193
188
  def merge_info(hash)
194
189
  return nil if @exec or info_file.nil?
190
+ return nil if ! writable?
195
191
  value = Annotated.purge value if defined? Annotated
196
192
  Open.lock(info_file, :lock => info_lock) do
197
193
  i = info(false)
198
194
  i.merge! hash
199
195
  @info_cache = i
200
- Misc.sensiblewrite(info_file, INFO_SERIALIAZER.dump(i), :force => true, :lock => false)
196
+ dump = INFO_SERIALIAZER.dump(i)
197
+ Misc.sensiblewrite(info_file, dump, :force => true, :lock => false)
201
198
  @info_cache_time = Time.now
202
199
  value
203
200
  end
@@ -546,8 +543,8 @@ class Step
546
543
  provenance = {}
547
544
  dependencies.each do |dep|
548
545
  next unless dep.path.exists?
549
- if File.exist? dep.info_file
550
- provenance[dep.path] = dep.provenance if File.exist? dep.path
546
+ if Open.exists? dep.info_file
547
+ provenance[dep.path] = dep.provenance if Open.exists? dep.path
551
548
  else
552
549
  provenance[dep.path] = nil
553
550
  end
@@ -558,7 +555,7 @@ class Step
558
555
  def provenance_paths
559
556
  provenance = {}
560
557
  dependencies.each do |dep|
561
- provenance[dep.path] = dep.provenance_paths if File.exist? dep.path
558
+ provenance[dep.path] = dep.provenance_paths if Open.exists? dep.path
562
559
  end
563
560
  provenance
564
561
  end
@@ -180,7 +180,7 @@ class Step
180
180
  raise $!
181
181
  rescue Exception
182
182
  Log.error "Exception in dep. #{ Log.color :red, dependency.task_name.to_s } -- #{$!.message}"
183
- raise $!
183
+ raise $! unless canfail_paths.include? dependency.path
184
184
  end
185
185
  end
186
186
 
@@ -300,9 +300,9 @@ class Step
300
300
  end
301
301
 
302
302
  def canfail_paths
303
- return Set.new if ! File.exists?(info_file)
303
+ return Set.new if ! Open.exists?(info_file)
304
304
 
305
- if info[:canfail_paths]
305
+ if !relocated && info[:canfail_paths]
306
306
  Set.new(info[:canfail_paths])
307
307
  else
308
308
  canfail_paths = Set.new
@@ -145,7 +145,8 @@ class Step
145
145
  next unless dep.updatable?
146
146
 
147
147
  begin
148
- if dep.done? && self.done? && Open.exists?(dep.path) && Open.exists?(self.path) && (File.mtime(dep.path) > File.mtime(self.path))
148
+
149
+ if dep.done? && self.done? && Open.exists?(dep.path) && Open.exists?(self.path) && (Open.mtime(dep.path) > Open.mtime(self.path))
149
150
  outdated_time << dep
150
151
  end
151
152
  rescue
@@ -223,7 +224,7 @@ class Step
223
224
  begin
224
225
  run_dependencies
225
226
  rescue Exception
226
- FileUtils.rm pid_file if File.exist?(pid_file)
227
+ Open.rm pid_file if Open.exists?(pid_file)
227
228
  stop_dependencies
228
229
  raise $!
229
230
  end
@@ -346,7 +347,7 @@ class Step
346
347
  ensure
347
348
  Step.purge_stream_cache
348
349
  set_info :pid, nil
349
- FileUtils.rm pid_file if File.exist?(pid_file)
350
+ Open.rm pid_file if Open.exist?(pid_file)
350
351
  end
351
352
  end
352
353
 
@@ -361,7 +362,7 @@ class Step
361
362
  rescue
362
363
  stop_dependencies
363
364
  set_info :pid, nil
364
- FileUtils.rm pid_file if File.exist?(pid_file)
365
+ Open.rm pid_file if Open.exist?(pid_file)
365
366
  end
366
367
  end
367
368
 
@@ -381,13 +382,13 @@ class Step
381
382
  })
382
383
  log :ending
383
384
  Step.purge_stream_cache
384
- FileUtils.rm pid_file if File.exist?(pid_file)
385
+ Open.rm pid_file if Open.exist?(pid_file)
385
386
  end
386
387
 
387
388
  set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]}
388
389
 
389
390
  if result.nil? && File.exists?(self.tmp_path) && ! File.exists?(self.path)
390
- FileUtils.mv self.tmp_path, self.path
391
+ Open.mv self.tmp_path, self.path
391
392
  end
392
393
  result
393
394
  end # END PERSIST
@@ -415,6 +416,8 @@ class Step
415
416
  stop_dependencies
416
417
  raise $!
417
418
  ensure
419
+ no_load = false unless IO === result
420
+ Open.rm pid_file if Open.exist?(pid_file) unless no_load
418
421
  set_info :pid, nil unless no_load
419
422
  end
420
423
  end
@@ -433,6 +436,7 @@ class Step
433
436
  else
434
437
  e = get_exception
435
438
  if e
439
+ Log.error "Raising exception in produced job #{job.path}: #{e.message}"
436
440
  raise e
437
441
  else
438
442
  raise "Error in job: #{self.path}"
@@ -464,7 +468,7 @@ class Step
464
468
  Misc.pre_fork
465
469
  begin
466
470
  RbbtSemaphore.wait_semaphore(semaphore) if semaphore
467
- FileUtils.mkdir_p File.dirname(path) unless File.exist? File.dirname(path)
471
+ Open.mkdir File.dirname(path) unless Open.exist?(File.dirname(path))
468
472
  begin
469
473
  @forked = true
470
474
  res = run no_load
@@ -626,7 +630,7 @@ class Step
626
630
  end
627
631
 
628
632
  def soft_grace
629
- until done? or File.exist?(info_file)
633
+ until done? or Open.exist?(info_file)
630
634
  sleep 1
631
635
  end
632
636
  self
@@ -672,8 +676,8 @@ class Step
672
676
  dependencies.each{|dep| dep.join }
673
677
  end
674
678
 
675
- until (path.exists? && status == :done) or error? or aborted? or waiting?
676
- sleep 1
679
+ until (Open.exists?(path) && status == :done) or error? or aborted? or waiting?
680
+ sleep 1
677
681
  join_stream if streaming?
678
682
  end
679
683
 
@@ -682,7 +686,7 @@ class Step
682
686
  begin
683
687
  set_info :joined, true
684
688
  rescue
685
- end if File.exists?(info_file) && writable?
689
+ end if Open.exists?(info_file) && writable?
686
690
  @result = nil
687
691
  end
688
692
  end
@@ -9,6 +9,7 @@ class Step
9
9
  attr_accessor :task_name, :overriden
10
10
  attr_accessor :pid
11
11
  attr_accessor :exec
12
+ attr_accessor :relocated
12
13
  attr_accessor :result, :mutex, :seen
13
14
 
14
15
  class << self
@@ -252,19 +253,29 @@ class Step
252
253
 
253
254
 
254
255
  def load
255
- res = if @result and not @path == @result
256
- res = @result
257
- else
258
- join if not done?
259
- @path.exists? ? Persist.load_file(@path, result_type) : exec
256
+ res = begin
257
+ if @result and not @path == @result
258
+ res = @result
259
+ else
260
+ join if not done?
261
+ res = @path.exists? ? Persist.load_file(@path, result_type) : exec
262
+ end
263
+
264
+ if result_description
265
+ entity_info = info.dup
266
+ entity_info.merge! info[:inputs] if info[:inputs]
267
+ res = prepare_result res, result_description, entity_info
268
+ end
269
+
270
+ res
271
+ rescue IOError
272
+ if @result
273
+ @result = nil
274
+ retry
275
+ end
276
+ raise $!
260
277
  end
261
278
 
262
- if result_description
263
- entity_info = info.dup
264
- entity_info.merge! info[:inputs] if info[:inputs]
265
- res = prepare_result res, result_description, entity_info
266
- end
267
-
268
279
  res
269
280
  end
270
281
 
data/lib/rbbt/workflow.rb CHANGED
@@ -471,21 +471,24 @@ module Workflow
471
471
  preal = real.split(/\/+/)
472
472
  pother = other.split(/\/+/)
473
473
  end_part = pother[-3..-1] * "/"
474
- new_path = preal[0..-4] * "/" << end_part
474
+ new_path = preal[0..-4] * "/" << "/" << end_part
475
475
  return new_path if File.exists? new_path
476
476
  Rbbt.var.jobs[end_part].find
477
477
  end
478
478
 
479
479
  def self.load_step(path)
480
480
  step = Step.new path
481
+ relocated = false
481
482
  step.dependencies = (step.info[:dependencies] || []).collect do |task,name,dep_path|
482
- if File.exists?(dep_path)
483
+ if Open.exists?(dep_path)
483
484
  Workflow.load_step dep_path
484
485
  else
485
486
  new_path = relocate(path, dep_path)
487
+ relocated = true if Open.exists?(new_path)
486
488
  Workflow.load_step new_path
487
489
  end
488
490
  end
491
+ step.relocated = relocated
489
492
 
490
493
  step
491
494
  end
@@ -103,6 +103,14 @@ TSV.traverse jobs, :_bar => "Checking job status" do |file,i|
103
103
  status = :sync if status != "done" and File.exist? file
104
104
 
105
105
  status = :dirty if info[:status].to_s == "done" and dirty and Workflow.load_step(file).dirty?
106
+ if info[:status] == :error
107
+ begin
108
+ exception = info[:exception][:class]
109
+ Kernel.const_get exception
110
+ status = :non_recoverable if exception.superclass === RbbtException
111
+ rescue
112
+ end
113
+ end
106
114
 
107
115
  status = status.to_s
108
116
  end
@@ -88,6 +88,8 @@ orig_name = name
88
88
 
89
89
  $saved_args = ARGV.dup
90
90
 
91
+ $saved_args.shift if $saved_args.include? '--'
92
+
91
93
  workflow = Workflow.require_workflow workflow
92
94
 
93
95
  tasks = task ? [task] : workflow.libdir.examples.glob('*').collect{|file| File.basename file }
@@ -70,7 +70,7 @@ def report_msg(status, name, path, info = nil)
70
70
  task, status, workflow = Log.color(:yellow, info[:task_name]), Log.color(:blue, "file"), Log.color(:magenta, "-")
71
71
  end
72
72
 
73
- str = if not Open.remote?(path) and (File.exists?(path) and $main_mtime and ($main_mtime - File.mtime(path)) < 0)
73
+ str = if not Open.remote?(path) and (Open.exists?(path) and $main_mtime and ($main_mtime - Open.mtime(path)) < 0)
74
74
  status_msg(status.to_s) << " " << [workflow, task, path].compact * " " << " (#{Log.color(:red, "Mtime out of sync") })"
75
75
  else
76
76
  status_msg(status.to_s) << " " << [workflow, task, path].compact * " "
@@ -108,7 +108,7 @@ def report(step, offset = 0, task = nil)
108
108
  status = info[:status] || :missing
109
109
  status = "remote" if Open.remote?(path)
110
110
  name = info[:name] || File.basename(path)
111
- status = :unsync if status == :done and not File.exist? path
111
+ status = :unsync if status == :done and not Open.exist? path
112
112
  str = " " * offset
113
113
  str << report_msg(status, name, path, info)
114
114
  step.dependencies.each do |dep|
@@ -124,7 +124,7 @@ def report(step, offset = 0, task = nil)
124
124
  end
125
125
 
126
126
  step = get_step file
127
- $main_mtime = File.exist?(step.path) ? File.mtime(step.path) : nil
127
+ $main_mtime = Open.exist?(step.path) ? Open.mtime(step.path) : nil
128
128
 
129
129
  def adjacency(step)
130
130
 
@@ -138,7 +138,7 @@ def adjacency(step)
138
138
  workflow, task, name = path.split("/")[-3..-1]
139
139
  end
140
140
  name = name.split(":").last
141
- status = :unsync if status == :done and not File.exist? path
141
+ status = :unsync if status == :done and not Open.exist? path
142
142
  shapes = Hash.new "circle"
143
143
  edge_info = {:status => status, :workflow => workflow, :task => task, :name => name, :label => task, :shape => shapes[workflow], :color => status == 'remote' ? 'blue' : 'green'}
144
144
  id = Misc.digest(path)
@@ -129,12 +129,64 @@ for this dependency
129
129
  "Hi #{name}"
130
130
  end
131
131
 
132
+ input :num, :integer
133
+ task :odd => :integer do |num|
134
+ raise ParameterException, "Not odd" if num % 2 == 0
135
+ num
136
+ end
137
+
138
+ dep :odd, :num => 10, :compute => :canfail
139
+ dep :odd, :num => 11, :compute => :canfail
140
+ dep :odd, :num => 12, :compute => :canfail
141
+ dep :odd, :num => 13, :compute => :canfail
142
+ task :sum_odds => :integer do
143
+ dependencies.inject(0) do |acc, dep|
144
+ acc += dep.load unless dep.error?
145
+ acc
146
+ end
147
+ end
148
+
149
+ dep :sum_odds
150
+ task :sum_odds_str => :string do
151
+ "Sum odds: " << step(:sum_odds).load.to_s
152
+ end
153
+
154
+
132
155
  end
133
156
 
134
157
  TestWF.workdir = Rbbt.tmp.test.workflow
135
158
 
136
159
  class TestWorkflow < Test::Unit::TestCase
137
160
 
161
+
162
+ def test_repo_marshal
163
+ TmpFile.with_file do |tmpdir|
164
+ tmpdir = Rbbt.tmp.repo_dir.find
165
+ repo = File.join(tmpdir, 'repo')
166
+
167
+ filename = 'file'
168
+ Open.repository_dirs.push(repo)
169
+
170
+ job = TestWF.job(:call_name, "Miguel")
171
+ job.run
172
+
173
+ obj = job.info
174
+ Open.write(File.join(repo, filename), Marshal.dump(obj))
175
+ new =Open.open(File.join(repo, filename)) do |f|
176
+ Marshal.load(f)
177
+ end
178
+
179
+ assert_equal new, obj
180
+ end
181
+
182
+ end
183
+
184
+ def test_in_repo
185
+ job = TestWF.job(:call_name, "Miguel")
186
+ assert_equal "Hi Miguel", job.run
187
+ assert_equal "Miguel", job.clean_name
188
+ end
189
+
138
190
  def test_as_jobname
139
191
  job = TestWF.job(:call_name, "Miguel")
140
192
  assert_equal "Hi Miguel", job.run
@@ -146,21 +198,22 @@ class TestWorkflow < Test::Unit::TestCase
146
198
  end
147
199
 
148
200
  def test_update_on_input_dependency_update
201
+ Open.repository_dirs << File.join(ENV["HOME"],".rbbt/tmp/test/workflow")
149
202
  Log.severity = 0
150
203
  send_input_dep_to_reverse_job = TestWF.job(:send_input_dep_to_reverse, nil, :name => "Miguel")
151
204
  send_input_dep_to_reverse_job.clean
152
205
  send_input_dep_to_reverse_job.run
153
206
 
154
207
  input_dep_job = send_input_dep_to_reverse_job.step(:input_dep)
155
- mtime_orig = File.mtime send_input_dep_to_reverse_job.step(:reverse_input_text).path
208
+ mtime_orig = Open.mtime send_input_dep_to_reverse_job.step(:reverse_input_text).path
156
209
 
157
- sleep 1
210
+ sleep 2
158
211
  input_dep_job.clean
159
212
  input_dep_job.run
160
213
  send_input_dep_to_reverse_job = TestWF.job(:send_input_dep_to_reverse, nil, :name => "Miguel")
161
214
 
162
215
  send_input_dep_to_reverse_job.run
163
- mtime_new = File.mtime send_input_dep_to_reverse_job.step(:reverse_input_text).path
216
+ mtime_new = Open.mtime send_input_dep_to_reverse_job.step(:reverse_input_text).path
164
217
  assert mtime_orig < mtime_new
165
218
  end
166
219
 
@@ -170,7 +223,7 @@ class TestWorkflow < Test::Unit::TestCase
170
223
 
171
224
  def test_job
172
225
  str = "TEST"
173
- job = TestWF.job(:repeat2, "Default", :number => 3).fork
226
+ job = TestWF.job(:repeat2, "Default", :number => 3).clean.fork
174
227
  while not job.done?
175
228
  sleep 1
176
229
  end
@@ -275,16 +328,6 @@ class TestWorkflow < Test::Unit::TestCase
275
328
  assert_equal "CB", TestWF.job(:t3).run
276
329
  end
277
330
 
278
- def test_relocate
279
- listed = '/home/user/.rbbt/var/jobs/TestWF/task1/Default'
280
- real = '/usr/local/var/rbbt/jobs/TestWF/task1/Default'
281
- other = '/home/user/.rbbt/var/jobs/TestWF/task2/Default'
282
- real_other = '/usr/local/var/rbbt/jobs/TestWF/task2/Default'
283
-
284
- assert_equal real_other, Workflow.relocate(real, other)
285
- assert_equal real_other, Workflow.relocate(real, other)
286
- end
287
-
288
331
  def test_transplant
289
332
  listed = '/home/user/.rbbt/var/jobs/TestWF/task1/Default'
290
333
  real = '/usr/local/var/rbbt/jobs/TestWF/task1/Default'
@@ -295,13 +338,29 @@ class TestWorkflow < Test::Unit::TestCase
295
338
  assert_equal real_other, Workflow.transplant(nil, real, other)
296
339
  end
297
340
 
298
- def test_relocate_alt
299
- listed = '/scratch/tmp/rbbt/.rbbt/var/jobs/Study/sample_gene_cnvs_focal/Bladder-TCC'
300
- real = '/home/bsc26/bsc26892/.rbbt/var/jobs/Study/sample_gene_cnvs_focal/Bladder-TCC'
301
- other = '/scratch/tmp/rbbt/scratch/bsc26892/rbbt/var/jobs/Sample/gene_cnv_status_focal/PCAWG'
302
- real_other = '/home/bsc26/bsc26892/.rbbt/var/jobs/Sample/gene_cnv_status_focal/PCAWG'
341
+ def test_relocate
342
+ TmpFile.with_file do |tmpdir|
343
+ listed = File.join(tmpdir, '/home/user/.rbbt/var/jobs/TestWF/task1/Default')
344
+ real = File.join(tmpdir, '/usr/local/var/rbbt/jobs/TestWF/task1/Default')
345
+ other = File.join(tmpdir, '/home/user/.rbbt/var/jobs/TestWF/task2/Default')
346
+ real_other = File.join(tmpdir, '/usr/local/var/rbbt/jobs/TestWF/task2/Default')
347
+
348
+ Open.write(real_other,'')
349
+ assert_equal real_other, Workflow.relocate(real, other)
350
+ assert_equal real_other, Workflow.relocate(real, other)
351
+ end
352
+ end
303
353
 
304
- assert_equal real_other, Workflow.relocate(real, other)
354
+ def test_relocate_alt
355
+ TmpFile.with_file do |tmpdir|
356
+ listed = File.join(tmpdir, '/scratch/tmp/rbbt/.rbbt/var/jobs/Study/sample_gene_cnvs_focal/Bladder-TCC')
357
+ real = File.join(tmpdir, '/home/bsc26/bsc26892/.rbbt/var/jobs/Study/sample_gene_cnvs_focal/Bladder-TCC')
358
+ other = File.join(tmpdir, '/scratch/tmp/rbbt/scratch/bsc26892/rbbt/var/jobs/Sample/gene_cnv_status_focal/PCAWG')
359
+ real_other = File.join(tmpdir, '/home/bsc26/bsc26892/.rbbt/var/jobs/Sample/gene_cnv_status_focal/PCAWG')
360
+ Open.write(real_other,'')
361
+
362
+ assert_equal real_other, Workflow.relocate(real, other)
363
+ end
305
364
  end
306
365
 
307
366
  def test_delete_dep
@@ -317,8 +376,17 @@ class TestWorkflow < Test::Unit::TestCase
317
376
  job = TestWF.job(:t3)
318
377
  job.step(:t1).clean
319
378
  Misc.with_env "RBBT_UPDATE_ALL_JOBS", "true" do
320
- assert job.checks.select{|d| d.task_name.to_s == "t1" }.any?
379
+ assert job.checks.select{|d| d.task_name.to_s == "t1" }.any?
321
380
  end
322
381
  end
323
382
 
383
+ def test_canfail
384
+ job = TestWF.job(:sum_odds)
385
+ assert_equal 24, job.run
386
+
387
+ job = TestWF.job(:sum_odds_str)
388
+ job.recursive_clean
389
+ assert_equal "Sum odds: 24", job.run
390
+ end
391
+
324
392
  end
@@ -109,7 +109,7 @@ class TestOpen < Test::Unit::TestCase
109
109
  file1 = "TEST"
110
110
  file2 = "TEST" * 1000
111
111
  TmpFile.with_file do |tmpdir|
112
- tmpdir = "/home/mvazquezg/tmp/repo_dir"
112
+ tmpdir = Rbbt.tmp.repo_dir.find
113
113
  normal = File.join(tmpdir, 'normal')
114
114
  repo = File.join(tmpdir, 'repo')
115
115
 
@@ -135,7 +135,7 @@ class TestOpen < Test::Unit::TestCase
135
135
 
136
136
  def test_repo_dir2
137
137
  TmpFile.with_file do |tmpdir|
138
- tmpdir = "/home/mvazquezg/tmp/repo_dir"
138
+ tmpdir = Rbbt.tmp.repo_dir.find
139
139
  repo = File.join(tmpdir, 'repo')
140
140
 
141
141
  Open.repository_dirs.push(repo)
@@ -149,5 +149,44 @@ class TestOpen < Test::Unit::TestCase
149
149
  end
150
150
  end
151
151
 
152
+ def test_repo_marshal
153
+ TmpFile.with_file do |tmpdir|
154
+ tmpdir = Rbbt.tmp.repo_dir.find
155
+ repo = File.join(tmpdir, 'repo')
156
+
157
+ filename = 'file'
158
+ Open.repository_dirs.push(repo)
159
+
160
+ obj = {:a => "string", :pid => nil, :num => 1000, :p => Rbbt.tmp.foo}
161
+ Open.write(File.join(repo, filename), Marshal.dump(obj))
162
+ new =Open.open(File.join(repo, filename)) do |f|
163
+ Marshal.load(f)
164
+ end
165
+
166
+ assert_equal new, obj
167
+ end
168
+
169
+ end
170
+
171
+ def test_write_stream_repo
172
+ Log.severity = 0
173
+ TmpFile.with_file do |tmpdir|
174
+ tmpdir = Rbbt.tmp.repo_dir.find
175
+ repo = File.join(tmpdir, 'repo')
176
+
177
+ file = File.join(repo, 'file')
178
+ Open.repository_dirs.push(repo)
179
+
180
+ text = (["text"] * 5) * "\n"
181
+
182
+ Misc.consume_stream(StringIO.new(text), false, file)
183
+
184
+ assert_equal text, Open.read(file)
185
+ assert !File.exists?(file)
186
+ assert Open.exists? file
187
+ end
188
+
189
+ end
190
+
152
191
  end
153
192
 
data/test/test_helper.rb CHANGED
@@ -25,6 +25,7 @@ class Test::Unit::TestCase
25
25
 
26
26
  def teardown
27
27
  FileUtils.rm_rf Rbbt.tmp.test.workflow.find
28
+ #Open.clear_dir_repos
28
29
  #if defined? Persist
29
30
  # FileUtils.rm_rf Path.setup("", 'rbbt').tmp.test.find :user
30
31
  # Persist::CONNECTIONS.values.each do |c| c.close end
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.23.21
4
+ version: 5.23.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-27 00:00:00.000000000 Z
11
+ date: 2018-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake