scout-gear 6.0.0 → 7.2.0

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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +465 -432
  3. data/VERSION +1 -1
  4. data/bin/scout +5 -1
  5. data/lib/rbbt-scout.rb +5 -0
  6. data/lib/scout/concurrent_stream.rb +6 -2
  7. data/lib/scout/config.rb +168 -0
  8. data/lib/scout/exceptions.rb +9 -0
  9. data/lib/scout/indiferent_hash/options.rb +1 -0
  10. data/lib/scout/indiferent_hash.rb +4 -2
  11. data/lib/scout/log/color.rb +31 -2
  12. data/lib/scout/log/progress/report.rb +1 -0
  13. data/lib/scout/log/progress/util.rb +3 -1
  14. data/lib/scout/log/progress.rb +7 -3
  15. data/lib/scout/log.rb +8 -3
  16. data/lib/scout/misc/digest.rb +1 -3
  17. data/lib/scout/misc/monitor.rb +3 -0
  18. data/lib/scout/misc/system.rb +15 -0
  19. data/lib/scout/misc.rb +1 -0
  20. data/lib/scout/named_array.rb +68 -0
  21. data/lib/scout/open/stream.rb +58 -26
  22. data/lib/scout/path/find.rb +27 -3
  23. data/lib/scout/path/util.rb +7 -4
  24. data/lib/scout/persist/serialize.rb +7 -14
  25. data/lib/scout/persist.rb +21 -1
  26. data/lib/scout/resource/produce.rb +7 -94
  27. data/lib/scout/resource/software.rb +176 -0
  28. data/lib/scout/tsv/dumper.rb +107 -0
  29. data/lib/scout/tsv/index.rb +49 -0
  30. data/lib/scout/tsv/parser.rb +317 -0
  31. data/lib/scout/tsv/path.rb +13 -0
  32. data/lib/scout/tsv/persist/adapter.rb +348 -0
  33. data/lib/scout/tsv/persist/tokyocabinet.rb +113 -0
  34. data/lib/scout/tsv/persist.rb +15 -0
  35. data/lib/scout/tsv/traverse.rb +48 -0
  36. data/lib/scout/tsv/util.rb +24 -0
  37. data/lib/scout/tsv.rb +27 -0
  38. data/lib/scout/work_queue/worker.rb +16 -11
  39. data/lib/scout/work_queue.rb +63 -21
  40. data/lib/scout/workflow/definition.rb +93 -4
  41. data/lib/scout/workflow/step/config.rb +18 -0
  42. data/lib/scout/workflow/step/dependencies.rb +40 -0
  43. data/lib/scout/workflow/step/file.rb +15 -0
  44. data/lib/scout/workflow/step/info.rb +33 -6
  45. data/lib/scout/workflow/step/provenance.rb +148 -0
  46. data/lib/scout/workflow/step.rb +70 -20
  47. data/lib/scout/workflow/task.rb +5 -4
  48. data/lib/scout/workflow/usage.rb +1 -1
  49. data/lib/scout/workflow.rb +11 -3
  50. data/lib/scout-gear.rb +1 -0
  51. data/lib/scout.rb +1 -0
  52. data/scout-gear.gemspec +38 -3
  53. data/scout_commands/find +1 -1
  54. data/scout_commands/workflow/task +16 -10
  55. data/share/software/install_helpers +523 -0
  56. data/test/scout/log/test_progress.rb +0 -2
  57. data/test/scout/misc/test_system.rb +21 -0
  58. data/test/scout/open/test_stream.rb +160 -1
  59. data/test/scout/path/test_find.rb +14 -7
  60. data/test/scout/resource/test_software.rb +24 -0
  61. data/test/scout/test_config.rb +66 -0
  62. data/test/scout/test_meta_extension.rb +10 -0
  63. data/test/scout/test_named_array.rb +19 -0
  64. data/test/scout/test_persist.rb +35 -0
  65. data/test/scout/test_semaphore.rb +1 -1
  66. data/test/scout/test_tmpfile.rb +2 -2
  67. data/test/scout/test_tsv.rb +74 -0
  68. data/test/scout/test_work_queue.rb +63 -8
  69. data/test/scout/tsv/persist/test_adapter.rb +34 -0
  70. data/test/scout/tsv/persist/test_tokyocabinet.rb +92 -0
  71. data/test/scout/tsv/test_dumper.rb +44 -0
  72. data/test/scout/tsv/test_index.rb +64 -0
  73. data/test/scout/tsv/test_parser.rb +173 -0
  74. data/test/scout/tsv/test_persist.rb +36 -0
  75. data/test/scout/tsv/test_traverse.rb +9 -0
  76. data/test/scout/tsv/test_util.rb +0 -0
  77. data/test/scout/work_queue/test_worker.rb +49 -1
  78. data/test/scout/workflow/step/test_dependencies.rb +25 -0
  79. data/test/scout/workflow/step/test_info.rb +15 -17
  80. data/test/scout/workflow/step/test_load.rb +16 -18
  81. data/test/scout/workflow/step/test_provenance.rb +25 -0
  82. data/test/scout/workflow/test_step.rb +206 -10
  83. data/test/scout/workflow/test_task.rb +0 -3
  84. data/test/test_helper.rb +6 -0
  85. metadata +37 -2
@@ -0,0 +1,348 @@
1
+ require_relative '../../open/lock'
2
+
3
+ module TSVAdapter
4
+ attr_accessor :persistence_path, :persistence_class, :closed, :writable
5
+
6
+ class << self
7
+ attr_accessor :lock_dir
8
+ def lock_dir
9
+ @lock_dir ||= Path.setup('tmp/tsv_locks')
10
+ end
11
+ end
12
+
13
+ EXTENSION_ATTR_HASH_KEY = "__extension_attr_hash__"
14
+ EXTENSION_ATTR_HASH_SERIALIZER = Marshal
15
+
16
+ def load_extension_attr_hash
17
+ EXTENSION_ATTR_HASH_SERIALIZER.load(self[EXTENSION_ATTR_HASH_KEY])
18
+ end
19
+
20
+ def save_extension_attr_hash
21
+ self[EXTENSION_ATTR_HASH_KEY]= EXTENSION_ATTR_HASH_SERIALIZER.dump(self.extension_attr_hash)
22
+ end
23
+
24
+ def self.extended(base)
25
+ if base.include?(EXTENSION_ATTR_HASH_KEY)
26
+ TSV.setup(base, base.load_extension_attr_hash)
27
+ elsif TSV === base
28
+ base[EXTENSION_ATTR_HASH_KEY] = EXTENSION_ATTR_HASH_SERIALIZER.dump(base.extension_attr_hash)
29
+ end
30
+
31
+ class << base
32
+ alias orig_set []=
33
+ alias orig_get []
34
+
35
+ def [](key)
36
+ self.read_lock do
37
+ load_value(super(key))
38
+ end
39
+ end
40
+
41
+ def []=(key, value)
42
+ self.write_lock do
43
+ super(key, save_value(value))
44
+ end
45
+ end
46
+ end
47
+
48
+ case base.type
49
+ when :single
50
+ class << base
51
+ def load_value(value)
52
+ value
53
+ end
54
+ def save_value(value)
55
+ value
56
+ end
57
+ end
58
+ when :list, :flat
59
+ class << base
60
+ def load_value(value)
61
+ value.nil? ? nil : value.split("\t")
62
+ end
63
+ def save_value(value)
64
+ value * "\t"
65
+ end
66
+ end
67
+ when :double
68
+ class << base
69
+ def load_value(value)
70
+ value.nil? ? nil : value.split("\t").collect{|v| v.split("|") }
71
+ end
72
+ def save_value(value)
73
+ value.collect{|v| v * "|" } * "\t"
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ def keys(*args)
80
+ k = self.read_lock do
81
+ super(*args)
82
+ end
83
+
84
+ if k[0] == EXTENSION_ATTR_HASH_KEY
85
+ k.slice(1,k.length-1)
86
+ elsif k[-1] == EXTENSION_ATTR_HASH_KEY
87
+ k.slice(0,k.length-2)
88
+ else
89
+ k - [EXTENSION_ATTR_HASH_KEY]
90
+ end
91
+ end
92
+
93
+ def each(&block)
94
+ self.read_lock do
95
+ super do |k,v|
96
+ next if k == EXTENSION_ATTR_HASH_KEY
97
+ yield(k, load_value(v))
98
+ end
99
+ end
100
+ end
101
+
102
+ def collect(&block)
103
+ res = []
104
+ if block_given?
105
+ each do |k,v|
106
+ res << yield(k, v)
107
+ end
108
+ else
109
+ each do |k,v|
110
+ res << [k, v]
111
+ end
112
+ end
113
+ res
114
+ end
115
+
116
+ def values
117
+ collect{|k,v| v }
118
+ end
119
+
120
+ alias map collect
121
+
122
+ def closed?
123
+ @closed
124
+ end
125
+
126
+ def write?
127
+ @writable
128
+ end
129
+
130
+ def read?
131
+ ! (write? || closed?)
132
+ end
133
+
134
+ def write(*args)
135
+ begin
136
+ super(*args)
137
+ @writable = true
138
+ rescue NoMethodError
139
+ end
140
+ end
141
+
142
+ def close(*args)
143
+ begin
144
+ super(*args)
145
+ @closed = true
146
+ rescue NoMethodError
147
+ end
148
+ self
149
+ end
150
+
151
+ def read(*args)
152
+ begin
153
+ super(*args)
154
+ rescue NoMethodError
155
+ end
156
+ end
157
+
158
+ def delete(key)
159
+ self.write_lock do
160
+ out(key)
161
+ end
162
+ end
163
+
164
+ def lock
165
+ return yield if @locked
166
+ lock_filename = Persist.persistence_path(persistence_path, {:dir => TSVAdapter.lock_dir})
167
+ Open.lock(lock_filename) do
168
+ begin
169
+ @locked = true
170
+ yield
171
+ ensure
172
+ @locked = false
173
+ end
174
+ end
175
+ end
176
+
177
+ def lock_and_close
178
+ lock do
179
+ begin
180
+ yield
181
+ ensure
182
+ close
183
+ end
184
+ end
185
+ end
186
+
187
+ def write_and_read
188
+ if write?
189
+ begin
190
+ return yield
191
+ ensure
192
+ read
193
+ end
194
+ end
195
+
196
+ lock do
197
+ write(true) if closed? || !write?
198
+ begin
199
+ yield
200
+ ensure
201
+ read
202
+ end
203
+ end
204
+ end
205
+
206
+ def write_and_close
207
+ if write?
208
+ begin
209
+ return yield
210
+ ensure
211
+ close unless @locked
212
+ end
213
+ end
214
+
215
+ lock do
216
+ write(true) if closed? || ! write?
217
+ res = begin
218
+ yield
219
+ ensure
220
+ close
221
+ end
222
+ res
223
+ end
224
+ end
225
+
226
+ def with_read(&block)
227
+ if read? || write?
228
+ return yield
229
+ else
230
+ read_and_close &block
231
+ end
232
+ end
233
+
234
+ def with_write(&block)
235
+ if write?
236
+ return yield
237
+ else
238
+ if self.read?
239
+ self.write_and_read do
240
+ return yield
241
+ end
242
+ else
243
+ self.write_and_close do
244
+ return yield
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+
251
+ def read_and_close
252
+ if read? || write?
253
+ begin
254
+ return yield
255
+ ensure
256
+ close unless @locked
257
+ end
258
+ end
259
+
260
+ lock do
261
+ read true if closed? || ! read?
262
+ begin
263
+ yield
264
+ ensure
265
+ close
266
+ end
267
+ end
268
+ end
269
+
270
+ def read_lock
271
+ read if closed?
272
+ if read? || write?
273
+ return yield
274
+ end
275
+
276
+ lock do
277
+ close
278
+ read true
279
+ begin
280
+ yield
281
+ end
282
+ end
283
+ end
284
+
285
+ def write_lock
286
+ write if closed?
287
+ if write?
288
+ return yield
289
+ end
290
+
291
+ lock do
292
+ close
293
+ write true
294
+ begin
295
+ yield
296
+ end
297
+ end
298
+ end
299
+
300
+ def merge!(hash)
301
+ hash.each do |key,values|
302
+ self[key] = values
303
+ end
304
+ end
305
+
306
+ def range(*args)
307
+ begin
308
+ self.read_lock do
309
+ super(*args)
310
+ end
311
+ rescue
312
+ []
313
+ end
314
+ end
315
+
316
+ def include?(*args)
317
+ self.read_lock do
318
+ super(*args) #- TSV::ENTRY_KEYS.to_a
319
+ end
320
+ end
321
+
322
+ MAX_CHAR = 255.chr
323
+
324
+ def prefix(key)
325
+ self.read_lock do
326
+ range(key, 1, key + MAX_CHAR, 1)
327
+ end
328
+ end
329
+
330
+ def get_prefix(key)
331
+ keys = prefix(key)
332
+ select(:key => keys)
333
+ end
334
+
335
+ def size(*args)
336
+ self.read_lock do
337
+ super(*args)
338
+ end
339
+ end
340
+
341
+ def values_at(*keys)
342
+ self.read_lock do
343
+ keys.collect do |k|
344
+ self[k]
345
+ end
346
+ end
347
+ end
348
+ end
@@ -0,0 +1,113 @@
1
+ require 'tokyocabinet'
2
+ require_relative 'adapter'
3
+
4
+ module ScoutCabinet
5
+ attr_accessor :persistence_path, :persistence_class
6
+
7
+ CONNECTIONS = {}
8
+ def self.open(path, write, tokyocabinet_class = TokyoCabinet::HDB)
9
+ if String === tokyocabinet_class && tokyocabinet_class.include?(":big")
10
+ big = true
11
+ tokyocabinet_class = tokyocabinet_class.split(":").first
12
+ else
13
+ big = false
14
+ end
15
+
16
+ dir = File.dirname(File.expand_path(path))
17
+ Open.mkdir(dir) unless File.exist?(dir)
18
+
19
+ tokyocabinet_class = TokyoCabinet::HDB if tokyocabinet_class == "HDB" or tokyocabinet_class.nil?
20
+ tokyocabinet_class = TokyoCabinet::BDB if tokyocabinet_class == "BDB"
21
+
22
+ database = CONNECTIONS[path] ||= tokyocabinet_class.new
23
+
24
+ if big and not Open.exists?(path)
25
+ database.tune(nil,nil,nil,tokyocabinet_class::TLARGE | tokyocabinet_class::TDEFLATE)
26
+ end
27
+
28
+ flags = (write ? tokyocabinet_class::OWRITER | tokyocabinet_class::OCREAT : tokyocabinet_class::OREADER)
29
+ database.close
30
+
31
+ if !database.open(path, flags)
32
+ ecode = database.ecode
33
+ raise "Open error: #{database.errmsg(ecode)}. Trying to open file #{path}"
34
+ end
35
+
36
+ database.extend ScoutCabinet
37
+ database.persistence_path ||= path
38
+ database.persistence_class = tokyocabinet_class
39
+
40
+ database.open(path, tokyocabinet_class::OREADER)
41
+
42
+ CONNECTIONS[path] = database
43
+
44
+ database
45
+ end
46
+
47
+ def close
48
+ @closed = true
49
+ @writable = false
50
+ super
51
+ end
52
+
53
+ def read(force = false)
54
+ return if ! write? && ! closed && ! force
55
+ self.close
56
+ if !self.open(@persistence_path, persistence_class::OREADER)
57
+ ecode = self.ecode
58
+ raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
59
+ end
60
+
61
+ @writable = false
62
+ @closed = false
63
+
64
+ self
65
+ end
66
+
67
+ def write(force = true)
68
+ return if write? && ! closed && ! force
69
+ self.close
70
+
71
+ if !self.open(@persistence_path, persistence_class::OWRITER)
72
+ ecode = self.ecode
73
+ raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
74
+ end
75
+
76
+ @writable = true
77
+ @closed = false
78
+
79
+ self
80
+ end
81
+
82
+ #def self.open_tokyocabinet(path, write, serializer = nil, tokyocabinet_class = TokyoCabinet::HDB)
83
+ # raise
84
+ # write = true unless File.exist? path
85
+
86
+ # FileUtils.mkdir_p File.dirname(path) unless File.exist?(File.dirname(path))
87
+
88
+ # database = Persist::TCAdapter.open(path, write, tokyocabinet_class)
89
+
90
+ # unless serializer == :clean
91
+ # TSV.setup database
92
+ # database.write_and_read do
93
+ # database.serializer = serializer
94
+ # end if serializer && database.serializer != serializer
95
+ # end
96
+
97
+ # database
98
+ #end
99
+ end
100
+
101
+ Persist.save_drivers[:HDB] = proc do |file, content|
102
+ data = ScoutCabinet.open(file, true, "HDB")
103
+ content.annotate(data)
104
+ data.extend TSVAdapter
105
+ data.merge!(content)
106
+ data
107
+ end
108
+
109
+ Persist.load_drivers[:HDB] = proc do |file|
110
+ data = ScoutCabinet.open(file, false, "HDB")
111
+ data.extend TSVAdapter unless TSVAdapter === data
112
+ data
113
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'persist/adapter'
2
+ require_relative 'persist/tokyocabinet'
3
+
4
+ Persist.save_drivers[:tsv] = proc do |file,content|
5
+ stream = if IO === content
6
+ content
7
+ elsif content.respond_to?(:get_stream)
8
+ content.get_stream
9
+ elsif content.respond_to?(:stream)
10
+ content.stream
11
+ end
12
+ Open.sensible_write(file, stream)
13
+ end
14
+
15
+ Persist.load_drivers[:tsv] = proc do |file| TSV.open file end
@@ -0,0 +1,48 @@
1
+ require_relative 'parser'
2
+ module TSV
3
+ def self.traverse_add(into, res)
4
+ case into
5
+ when TSV::Dumper
6
+ into.add *res
7
+ when TSV, Hash
8
+ key, value = res
9
+ into[key] = value
10
+ end
11
+ end
12
+
13
+ def self.traverse(obj, into: nil, cpus: nil, bar: nil, **options, &block)
14
+ case obj
15
+ when TSV
16
+ self.traverse(obj.stream, into: into, cpus: cpus, bar: bar, **options, &block)
17
+ when String
18
+ f = Open.open(obj)
19
+ self.traverse(f, into: into, cpus: cpus, bar: bar, **options, &block)
20
+ when Step
21
+ self.traverse(obj.get_stream, into: into, cpus: cpus, bar: bar, **options, &block)
22
+ when IO
23
+ if into
24
+ into_thread = Thread.new do
25
+ Thread.current.report_on_exception = false
26
+ Thread.current["name"] = "Traverse into"
27
+ TSV.parse obj, **options do |k,v|
28
+ begin
29
+ res = block.call k, v
30
+ traverse_add into, res
31
+ rescue
32
+ into.abort $!
33
+ end
34
+ nil
35
+ end
36
+ into.close if into.respond_to?(:close)
37
+ end
38
+ Thread.pass until into_thread
39
+ into
40
+ else
41
+ TSV.parse obj, **options do |k,v|
42
+ block.call k, v
43
+ nil
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,24 @@
1
+ #require_relative '../../../modules/rbbt-util/lib/rbbt/tsv/manipulate'
2
+ #Log.warn "USING OLD RBBT CODE: #{__FILE__}"
3
+ module TSV
4
+ #[:each, :collect, :map].each do |method|
5
+ # define_method(method) do |*args,&block|
6
+ # super(*args) do |k,v|
7
+ # NamedArray.setup(v, @fields) unless @unnamed
8
+ # block.call k, v
9
+ # end
10
+ # end
11
+ #end
12
+
13
+ #[:select, :reject].each do |method|
14
+ # define_method(method) do |*args,&block|
15
+ # res = super(*args) do |k,v|
16
+ # NamedArray.setup(v, @fields) unless @unnamed
17
+ # block.call k, v
18
+ # end
19
+ # self.annotate(res)
20
+ # res
21
+ # end
22
+ #end
23
+
24
+ end
data/lib/scout/tsv.rb ADDED
@@ -0,0 +1,27 @@
1
+ require_relative 'meta_extension'
2
+ require_relative 'tsv/util'
3
+ require_relative 'tsv/parser'
4
+ require_relative 'tsv/dumper'
5
+ require_relative 'tsv/persist'
6
+ require_relative 'tsv/index'
7
+ require_relative 'tsv/path'
8
+ require_relative 'tsv/traverse'
9
+
10
+ module TSV
11
+ extend MetaExtension
12
+ extension_attr :key_field, :fields, :type, :filename, :namespace, :unnamed
13
+
14
+ def self.open(file, options = {})
15
+ persist, type = IndiferentHash.process_options options, :persist, :persist_type, :persist => false, :persist_type => "HDB"
16
+ Persist.persist(file, type, options.merge(:persist => persist)) do |filename|
17
+ data = filename ? ScoutCabinet.open(filename, true, type) : nil
18
+ options[:data] = data if data
19
+ options[:filename] = file
20
+ Open.open(file) do |f|
21
+ TSV.parse(f, **options)
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+
@@ -1,16 +1,18 @@
1
1
  class WorkQueue
2
2
  class Worker
3
3
  attr_accessor :pid, :ignore_ouput
4
- def initialize
4
+ def initialize(ignore_ouput = false)
5
+ @ignore_output = ignore_ouput
5
6
  end
6
7
 
7
8
  def run
8
9
  @pid = Process.fork do
10
+ Log.debug "Worker start with #{Process.pid}"
9
11
  yield
10
12
  end
11
13
  end
12
14
 
13
- def process(input, output, &block)
15
+ def process(input, output = nil, &block)
14
16
  run do
15
17
  begin
16
18
  while obj = input.read
@@ -22,21 +24,25 @@ class WorkQueue
22
24
  output.write res unless ignore_ouput || res == :ignore
23
25
  end
24
26
  rescue DoneProcessing
25
- Log.log "Worker #{Process.pid} done"
27
+ rescue Interrupt
26
28
  rescue Exception
27
- Log.exception $!
29
+ output.write WorkerException.new($!, Process.pid)
28
30
  exit -1
29
31
  end
30
32
  end
31
33
  end
32
34
 
33
- def join
34
- Log.log "Joining worker #{@pid}"
35
- Process.waitpid @pid
35
+ def abort
36
+ begin
37
+ Log.debug "Aborting worker #{@pid}"
38
+ Process.kill "INT", @pid
39
+ rescue Errno::ECHILD
40
+ end
36
41
  end
37
42
 
38
- def exit(status)
39
- Log.log "Worker #{@pid} exited with status #{Log.color(:green, status)}"
43
+ def join
44
+ Log.debug "Joining worker #{@pid}"
45
+ Process.waitpid @pid
40
46
  end
41
47
 
42
48
  def self.join(workers)
@@ -44,8 +50,7 @@ class WorkQueue
44
50
  begin
45
51
  while pid = Process.wait
46
52
  status = $?
47
- worker = workers.select{|w| w.pid == pid }.first
48
- worker.exit status.exitstatus if worker
53
+ worker = workers.select{|w| w.pid == pid }.first
49
54
  end
50
55
  rescue Errno::ECHILD
51
56
  end