scout-gear 6.0.0 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
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