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.
- checksums.yaml +4 -4
- data/.vimproject +465 -432
- data/VERSION +1 -1
- data/bin/scout +5 -1
- data/lib/rbbt-scout.rb +5 -0
- data/lib/scout/concurrent_stream.rb +6 -2
- data/lib/scout/config.rb +168 -0
- data/lib/scout/exceptions.rb +9 -0
- data/lib/scout/indiferent_hash/options.rb +1 -0
- data/lib/scout/indiferent_hash.rb +4 -2
- data/lib/scout/log/color.rb +31 -2
- data/lib/scout/log/progress/report.rb +1 -0
- data/lib/scout/log/progress/util.rb +3 -1
- data/lib/scout/log/progress.rb +7 -3
- data/lib/scout/log.rb +8 -3
- data/lib/scout/misc/digest.rb +1 -3
- data/lib/scout/misc/monitor.rb +3 -0
- data/lib/scout/misc/system.rb +15 -0
- data/lib/scout/misc.rb +1 -0
- data/lib/scout/named_array.rb +68 -0
- data/lib/scout/open/stream.rb +58 -26
- data/lib/scout/path/find.rb +27 -3
- data/lib/scout/path/util.rb +7 -4
- data/lib/scout/persist/serialize.rb +7 -14
- data/lib/scout/persist.rb +21 -1
- data/lib/scout/resource/produce.rb +7 -94
- data/lib/scout/resource/software.rb +176 -0
- data/lib/scout/tsv/dumper.rb +107 -0
- data/lib/scout/tsv/index.rb +49 -0
- data/lib/scout/tsv/parser.rb +317 -0
- data/lib/scout/tsv/path.rb +13 -0
- data/lib/scout/tsv/persist/adapter.rb +348 -0
- data/lib/scout/tsv/persist/tokyocabinet.rb +113 -0
- data/lib/scout/tsv/persist.rb +15 -0
- data/lib/scout/tsv/traverse.rb +48 -0
- data/lib/scout/tsv/util.rb +24 -0
- data/lib/scout/tsv.rb +27 -0
- data/lib/scout/work_queue/worker.rb +16 -11
- data/lib/scout/work_queue.rb +63 -21
- data/lib/scout/workflow/definition.rb +93 -4
- data/lib/scout/workflow/step/config.rb +18 -0
- data/lib/scout/workflow/step/dependencies.rb +40 -0
- data/lib/scout/workflow/step/file.rb +15 -0
- data/lib/scout/workflow/step/info.rb +33 -6
- data/lib/scout/workflow/step/provenance.rb +148 -0
- data/lib/scout/workflow/step.rb +70 -20
- data/lib/scout/workflow/task.rb +5 -4
- data/lib/scout/workflow/usage.rb +1 -1
- data/lib/scout/workflow.rb +11 -3
- data/lib/scout-gear.rb +1 -0
- data/lib/scout.rb +1 -0
- data/scout-gear.gemspec +38 -3
- data/scout_commands/find +1 -1
- data/scout_commands/workflow/task +16 -10
- data/share/software/install_helpers +523 -0
- data/test/scout/log/test_progress.rb +0 -2
- data/test/scout/misc/test_system.rb +21 -0
- data/test/scout/open/test_stream.rb +160 -1
- data/test/scout/path/test_find.rb +14 -7
- data/test/scout/resource/test_software.rb +24 -0
- data/test/scout/test_config.rb +66 -0
- data/test/scout/test_meta_extension.rb +10 -0
- data/test/scout/test_named_array.rb +19 -0
- data/test/scout/test_persist.rb +35 -0
- data/test/scout/test_semaphore.rb +1 -1
- data/test/scout/test_tmpfile.rb +2 -2
- data/test/scout/test_tsv.rb +74 -0
- data/test/scout/test_work_queue.rb +63 -8
- data/test/scout/tsv/persist/test_adapter.rb +34 -0
- data/test/scout/tsv/persist/test_tokyocabinet.rb +92 -0
- data/test/scout/tsv/test_dumper.rb +44 -0
- data/test/scout/tsv/test_index.rb +64 -0
- data/test/scout/tsv/test_parser.rb +173 -0
- data/test/scout/tsv/test_persist.rb +36 -0
- data/test/scout/tsv/test_traverse.rb +9 -0
- data/test/scout/tsv/test_util.rb +0 -0
- data/test/scout/work_queue/test_worker.rb +49 -1
- data/test/scout/workflow/step/test_dependencies.rb +25 -0
- data/test/scout/workflow/step/test_info.rb +15 -17
- data/test/scout/workflow/step/test_load.rb +16 -18
- data/test/scout/workflow/step/test_provenance.rb +25 -0
- data/test/scout/workflow/test_step.rb +206 -10
- data/test/scout/workflow/test_task.rb +0 -3
- data/test/test_helper.rb +6 -0
- 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
|
-
|
27
|
+
rescue Interrupt
|
26
28
|
rescue Exception
|
27
|
-
|
29
|
+
output.write WorkerException.new($!, Process.pid)
|
28
30
|
exit -1
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
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
|
39
|
-
Log.
|
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
|
-
|
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
|