scout-gear 7.2.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +51 -6
  3. data/VERSION +1 -1
  4. data/bin/scout +6 -3
  5. data/lib/rbbt-scout.rb +1 -0
  6. data/lib/scout/cmd.rb +1 -1
  7. data/lib/scout/concurrent_stream.rb +33 -29
  8. data/lib/scout/config.rb +1 -1
  9. data/lib/scout/exceptions.rb +1 -0
  10. data/lib/scout/log/color.rb +4 -2
  11. data/lib/scout/log/progress/report.rb +1 -1
  12. data/lib/scout/log/progress/util.rb +71 -2
  13. data/lib/scout/log/progress.rb +1 -1
  14. data/lib/scout/log/trap.rb +107 -0
  15. data/lib/scout/log.rb +56 -21
  16. data/lib/scout/meta_extension.rb +13 -6
  17. data/lib/scout/misc/digest.rb +1 -1
  18. data/lib/scout/misc/format.rb +12 -0
  19. data/lib/scout/misc/helper.rb +31 -0
  20. data/lib/scout/misc/insist.rb +1 -1
  21. data/lib/scout/misc/monitor.rb +12 -1
  22. data/lib/scout/misc/system.rb +10 -0
  23. data/lib/scout/misc.rb +1 -0
  24. data/lib/scout/named_array.rb +65 -3
  25. data/lib/scout/open/lock/lockfile.rb +587 -0
  26. data/lib/scout/open/lock.rb +28 -2
  27. data/lib/scout/open/remote.rb +4 -0
  28. data/lib/scout/open/stream.rb +111 -42
  29. data/lib/scout/open/util.rb +13 -3
  30. data/lib/scout/path/find.rb +9 -1
  31. data/lib/scout/path/util.rb +35 -0
  32. data/lib/scout/persist/serialize.rb +18 -5
  33. data/lib/scout/persist.rb +60 -30
  34. data/lib/scout/resource/path.rb +53 -0
  35. data/lib/scout/resource/produce.rb +0 -8
  36. data/lib/scout/resource/util.rb +2 -1
  37. data/lib/scout/semaphore.rb +8 -1
  38. data/lib/scout/tmpfile.rb +7 -8
  39. data/lib/scout/tsv/attach.rb +177 -0
  40. data/lib/scout/tsv/change_id.rb +40 -0
  41. data/lib/scout/tsv/dumper.rb +85 -54
  42. data/lib/scout/tsv/index.rb +188 -20
  43. data/lib/scout/tsv/open.rb +182 -0
  44. data/lib/scout/tsv/parser.rb +200 -118
  45. data/lib/scout/tsv/path.rb +5 -6
  46. data/lib/scout/tsv/persist/adapter.rb +26 -37
  47. data/lib/scout/tsv/persist/fix_width_table.rb +327 -0
  48. data/lib/scout/tsv/persist/serialize.rb +117 -0
  49. data/lib/scout/tsv/persist/tokyocabinet.rb +6 -3
  50. data/lib/scout/tsv/persist.rb +4 -2
  51. data/lib/scout/tsv/transformer.rb +141 -0
  52. data/lib/scout/tsv/traverse.rb +136 -37
  53. data/lib/scout/tsv/util/filter.rb +312 -0
  54. data/lib/scout/tsv/util/process.rb +73 -0
  55. data/lib/scout/tsv/util/reorder.rb +81 -0
  56. data/lib/scout/tsv/util/select.rb +265 -0
  57. data/lib/scout/tsv/util/unzip.rb +86 -0
  58. data/lib/scout/tsv/util.rb +126 -19
  59. data/lib/scout/tsv.rb +28 -5
  60. data/lib/scout/work_queue/socket.rb +6 -1
  61. data/lib/scout/work_queue/worker.rb +5 -2
  62. data/lib/scout/work_queue.rb +15 -8
  63. data/lib/scout/workflow/definition.rb +29 -2
  64. data/lib/scout/workflow/step/dependencies.rb +24 -4
  65. data/lib/scout/workflow/step/info.rb +40 -5
  66. data/lib/scout/workflow/step/progress.rb +14 -0
  67. data/lib/scout/workflow/step/provenance.rb +8 -7
  68. data/lib/scout/workflow/step/status.rb +45 -0
  69. data/lib/scout/workflow/step.rb +104 -33
  70. data/lib/scout/workflow/task/inputs.rb +14 -20
  71. data/lib/scout/workflow/task.rb +86 -47
  72. data/lib/scout/workflow/usage.rb +10 -6
  73. data/scout-gear.gemspec +30 -3
  74. data/scout_commands/workflow/task +37 -9
  75. data/scout_commands/workflow/task_old +2 -2
  76. data/test/scout/open/test_stream.rb +61 -59
  77. data/test/scout/path/test_find.rb +10 -1
  78. data/test/scout/resource/test_produce.rb +15 -0
  79. data/test/scout/test_meta_extension.rb +25 -0
  80. data/test/scout/test_named_array.rb +18 -0
  81. data/test/scout/test_persist.rb +67 -0
  82. data/test/scout/test_tmpfile.rb +1 -1
  83. data/test/scout/test_tsv.rb +222 -3
  84. data/test/scout/test_work_queue.rb +21 -18
  85. data/test/scout/tsv/persist/test_adapter.rb +11 -1
  86. data/test/scout/tsv/persist/test_fix_width_table.rb +134 -0
  87. data/test/scout/tsv/persist/test_tokyocabinet.rb +29 -1
  88. data/test/scout/tsv/test_attach.rb +227 -0
  89. data/test/scout/tsv/test_change_id.rb +98 -0
  90. data/test/scout/tsv/test_dumper.rb +1 -1
  91. data/test/scout/tsv/test_index.rb +127 -3
  92. data/test/scout/tsv/test_open.rb +167 -0
  93. data/test/scout/tsv/test_parser.rb +45 -3
  94. data/test/scout/tsv/test_persist.rb +9 -0
  95. data/test/scout/tsv/test_transformer.rb +108 -0
  96. data/test/scout/tsv/test_traverse.rb +195 -3
  97. data/test/scout/tsv/test_util.rb +24 -0
  98. data/test/scout/tsv/util/test_filter.rb +188 -0
  99. data/test/scout/tsv/util/test_process.rb +47 -0
  100. data/test/scout/tsv/util/test_reorder.rb +94 -0
  101. data/test/scout/tsv/util/test_select.rb +58 -0
  102. data/test/scout/tsv/util/test_unzip.rb +112 -0
  103. data/test/scout/work_queue/test_socket.rb +0 -1
  104. data/test/scout/work_queue/test_worker.rb +63 -6
  105. data/test/scout/workflow/step/test_load.rb +3 -3
  106. data/test/scout/workflow/step/test_status.rb +31 -0
  107. data/test/scout/workflow/task/test_inputs.rb +14 -14
  108. data/test/scout/workflow/test_step.rb +13 -13
  109. data/test/scout/workflow/test_task.rb +168 -32
  110. data/test/scout/workflow/test_usage.rb +33 -6
  111. data/test/test_helper.rb +3 -1
  112. metadata +29 -2
@@ -0,0 +1,81 @@
1
+ require 'matrix'
2
+
3
+ module TSV
4
+ def reorder(key_field = nil, fields = nil, merge: true, one2one: true, **kwargs)
5
+ res = self.annotate({})
6
+ res.type = kwargs[:type] if kwargs.include?(:type)
7
+ kwargs[:one2one] = one2one
8
+ key_field_name, field_names = traverse key_field, fields, **kwargs do |k,v|
9
+ if @type == :double && merge && res.include?(k)
10
+ current = res[k]
11
+ if merge == :concat
12
+ v.each_with_index do |new,i|
13
+ next if new.empty?
14
+ current[i].concat(new)
15
+ end
16
+ else
17
+ merged = []
18
+ v.each_with_index do |new,i|
19
+ next if new.empty?
20
+ merged[i] = current[i] + new
21
+ end
22
+ res[k] = merged
23
+ end
24
+ else
25
+ res[k] = v
26
+ end
27
+ end
28
+ res.key_field = key_field_name
29
+ res.fields = field_names
30
+ res
31
+ end
32
+
33
+ def slice(fields, **kwargs)
34
+ reorder :key, fields, **kwargs
35
+ end
36
+
37
+ def column(field, **kwargs)
38
+ new_type = case type
39
+ when :double, :flat
40
+ :flat
41
+ else
42
+ :single
43
+ end
44
+
45
+ kwargs[:type] = new_type
46
+ slice(field, **kwargs)
47
+ end
48
+
49
+ def transpose_list(key_field="Unkown ID")
50
+ new_fields = keys.dup
51
+ new = self.annotate({})
52
+ TSV.setup(new, :key_field => key_field, :fields => new_fields, :type => type, :filename => filename, :identifiers => identifiers)
53
+
54
+ m = Matrix.rows values
55
+ new_rows = m.transpose.to_a
56
+
57
+ fields.zip(new_rows) do |key,row|
58
+ new[key] = row
59
+ end
60
+
61
+ new
62
+ end
63
+
64
+ def transpose_double(key_field = "Unkown ID")
65
+ sep = "-!SEP--#{rand 10000}!-"
66
+ tmp = self.to_list{|v| v * sep}
67
+ new = tmp.transpose_list(key_field)
68
+ new.to_double{|v| v.split(sep)}
69
+ end
70
+
71
+ def transpose(key_field = "Unkown ID")
72
+ case type
73
+ when :single, :flat
74
+ self.to_list.transpose_list key_field
75
+ when :list
76
+ transpose_list key_field
77
+ when :double
78
+ transpose_double key_field
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,265 @@
1
+ module TSV
2
+ def self.select(key, values, method, fields: nil, field: nil, invert: false, type: nil, sep: nil, &block)
3
+ return ! select(key, values, method, field: field, invert: false, type: type, sep: sep, &block) if invert
4
+
5
+ return yield(key, values) if method.nil? && block_given
6
+
7
+ if Hash === method
8
+ if method.include?(:invert)
9
+ method = method.dup
10
+ invert = method.delete(:invert)
11
+ return select(key, values, method, fields: fields, field: field, invert: invert, type: type, sep: sep, &block)
12
+ end
13
+ field = method.keys.first
14
+ value = method[field]
15
+ return select(key, values, value, fields: fields, field: field, invert: invert, type: type, sep: sep, &block)
16
+ end
17
+
18
+ if field
19
+ field = fields.index(field) if fields && String === field
20
+ set = field == :key ? [key] : (type == :double ? values[field].split(sep) : values[field])
21
+ else
22
+ set = [key, (type == :double ? values.collect{|v| v.split(sep) } : values)]
23
+ end
24
+
25
+ if Array === set
26
+ set.flatten!
27
+ else
28
+ set = [set]
29
+ end
30
+
31
+ case method
32
+ when Array
33
+ (method & set).any?
34
+ when Regexp
35
+ set.select{|v| v =~ method }.any?
36
+ when Symbol
37
+ set.first.send(method)
38
+ when Numeric
39
+ set.size > method
40
+ when String
41
+ if block_given?
42
+ field = method
43
+ field = fields.index?(field) if fields && String === field
44
+ case
45
+ when block.arity == 1
46
+ if (method == key_field or method == :key)
47
+ yield(key)
48
+ else
49
+ yield(values[method])
50
+ end
51
+ when block.arity == 2
52
+ if (method == key_field or method == :key)
53
+ yield(key, key)
54
+ else
55
+ yield(key, values[method])
56
+ end
57
+ end
58
+ elsif m = method.match(/^([<>]=?)(.*)/)
59
+ set.select{|v| v.to_f.send($1, $2.to_f) }.any?
60
+ else
61
+ set.select{|v| v == method }.any?
62
+ end
63
+ when Proc
64
+ set.select{|v| method.call(v) }.any?
65
+ end
66
+ end
67
+
68
+ def select(method = nil, invert = false, &block)
69
+ new = TSV.setup({}, :key_field => key_field, :fields => fields, :type => type, :filename => filename, :identifiers => identifiers)
70
+
71
+ self.annotate(new)
72
+
73
+ case
74
+ when (method.nil? and block_given?)
75
+ through do |key, values|
76
+ new[key] = values if invert ^ (yield key, values)
77
+ end
78
+ when Array === method
79
+ method = Set.new method
80
+ with_unnamed do
81
+ case type
82
+ when :single
83
+ through do |key, value|
84
+ new[key] = value if invert ^ (method.include? key or method.include? value)
85
+ end
86
+ when :list, :flat
87
+ through do |key, values|
88
+ new[key] = values if invert ^ (method.include? key or (method & values).length > 0)
89
+ end
90
+ else
91
+ through do |key, values|
92
+ new[key] = values if invert ^ (method.include? key or (method & values.flatten).length > 0)
93
+ end
94
+ end
95
+ end
96
+ when Regexp === method
97
+ with_unnamed do
98
+ through do |key, values|
99
+ new[key] = values if invert ^ ([key,values].flatten.select{|v| v =~ method}.any?)
100
+ end
101
+ end
102
+ when ((String === method) || (Symbol === method))
103
+ if block_given?
104
+ case
105
+ when block.arity == 1
106
+ with_unnamed do
107
+ case
108
+ when (method == key_field or method == :key)
109
+ through do |key, values|
110
+ new[key] = values if invert ^ (yield(key))
111
+ end
112
+ when (type == :single or type == :flat)
113
+ through do |key, value|
114
+ new[key] = value if invert ^ (yield(value))
115
+ end
116
+ else
117
+ pos = identify_field method
118
+ raise "Field #{ method } not identified. Available: #{ fields * ", " }" if pos.nil?
119
+
120
+ through do |key, values|
121
+ new[key] = values if invert ^ (yield(values[pos]))
122
+ end
123
+ end
124
+ end
125
+ when block.arity == 2
126
+ with_unnamed do
127
+ case
128
+ when (method == key_field or method == :key)
129
+ through do |key, values|
130
+ new[key] = values if invert ^ (yield(key, key))
131
+ end
132
+ when (type == :single or type == :flat)
133
+ through do |key, value|
134
+ new[key] = value if invert ^ (yield(key, value))
135
+ end
136
+ else
137
+ pos = identify_field method
138
+ through do |key, values|
139
+ new[key] = values if invert ^ (yield(key, values[pos]))
140
+ end
141
+ end
142
+
143
+ end
144
+ end
145
+
146
+ else
147
+ with_unnamed do
148
+ through do |key, values|
149
+ new[key] = values if invert ^ ([key,values].flatten.select{|v| v == method}.any?)
150
+ end
151
+ end
152
+ end
153
+ when Hash === method
154
+ key = method.keys.first
155
+ method = method.values.first
156
+ case
157
+ when ((Array === method) and (key == :key or key_field == key))
158
+ with_unnamed do
159
+ keys.each do |key|
160
+ new[key] = self[key] if invert ^ (method.include? key)
161
+ end
162
+ end
163
+ when Array === method
164
+ with_unnamed do
165
+ method = Set.new method unless Set === method
166
+ case type
167
+ when :single
168
+ through :key, key do |key, value|
169
+ new[key] = self[key] if invert ^ (method.include? value)
170
+ end
171
+ when :list
172
+ through :key, key do |key, values|
173
+ new[key] = self[key] if invert ^ (method.include? values.first)
174
+ end
175
+ when :flat #untested
176
+ through :key, key do |key, values|
177
+ new[key] = self[key] if invert ^ ((method & values.flatten).any?)
178
+ end
179
+ else
180
+ through :key, key do |key, values|
181
+ new[key] = self[key] if invert ^ ((method & values.flatten).any?)
182
+ end
183
+ end
184
+ end
185
+
186
+ when Regexp === method
187
+ with_unnamed do
188
+ through :key, key do |key, values|
189
+ values = [values] if type == :single
190
+ new[key] = self[key] if invert ^ (values.flatten.select{|v| v =~ method}.any?)
191
+ end
192
+ end
193
+
194
+ when ((String === method) and (method =~ /name:(.*)/))
195
+ name = $1
196
+ old_unnamed = self.unnamed
197
+ self.unnamed = false
198
+ if name.strip =~ /^\/(.*)\/$/
199
+ regexp = Regexp.new $1
200
+ through :key, key do |key, values|
201
+ case type
202
+ when :single
203
+ values = values.annotate([values])
204
+ when :double
205
+ values = values[0]
206
+ end
207
+ new[key] = self[key] if invert ^ (values.select{|v| v.name =~ regexp}.any?)
208
+ end
209
+ else
210
+ through :key, key do |key, values|
211
+ case type
212
+ when :single
213
+ values = values.annotate([values])
214
+ when :double
215
+ values = values[0]
216
+ end
217
+ new[key] = self[key] if invert ^ (values.select{|v| v.name == name}.any?)
218
+ end
219
+ end
220
+ self.unnamed = old_unnamed
221
+
222
+ when String === method
223
+ if method =~ /^([<>]=?)(.*)/
224
+ with_unnamed do
225
+ through :key, key do |key, values|
226
+ value = Array === values ? values.flatten.first : values
227
+ new[key] = self[key] if value.to_f.send($1, $2.to_f)
228
+ end
229
+ end
230
+ else
231
+ with_unnamed do
232
+ through :key, key do |key, values|
233
+ values = [values] if type == :single
234
+ new[key] = self[key] if invert ^ (values.flatten.select{|v| v == method}.length > 0)
235
+ end
236
+ end
237
+ end
238
+ when Numeric === method
239
+ with_unnamed do
240
+ through :key, key do |key, values|
241
+ new[key] = self[key] if invert ^ (values.flatten.length >= method)
242
+ end
243
+ end
244
+ when Proc === method
245
+ with_unnamed do
246
+ through :key, key do |key, values|
247
+ values = [values] if type == :single
248
+ new[key] = self[key] if invert ^ (values.flatten.select{|v| method.call(v)}.length > 0)
249
+ end
250
+ end
251
+ end
252
+ end
253
+ new
254
+ end
255
+
256
+ def subset(keys)
257
+ new = self.annotate({})
258
+ self.with_unnamed do
259
+ keys.each do |k|
260
+ new[k] = self[k] if self.include?(k)
261
+ end
262
+ end
263
+ new
264
+ end
265
+ end
@@ -0,0 +1,86 @@
1
+ module TSV
2
+
3
+ def self.unzip(source, field, target: nil, sep: ":", delete: true, type: :list, merge: false, one2one: true, bar: nil)
4
+ source = TSV::Parser.new source if String === source
5
+
6
+ field_pos = source.identify_field(field)
7
+ new_fields = source.fields.dup
8
+ field_name = new_fields[field_pos]
9
+ new_fields.delete_at(field_pos) if delete
10
+ new_key_field = [source.key_field, field_name] * sep
11
+ type = :double if merge
12
+
13
+ stream = target == :stream
14
+
15
+ target = case target
16
+ when :stream
17
+ TSV::Dumper.new(source.options.merge(sep: "\t"))
18
+ when nil
19
+ TSV.setup({})
20
+ else
21
+ target
22
+ end
23
+
24
+ target.fields = new_fields
25
+ target.key_field = new_key_field
26
+ target.type = type
27
+
28
+ transformer = TSV::Transformer.new source, target, unnamed: true
29
+
30
+ bar = "Unzip #{new_key_field}" if TrueClass === bar
31
+
32
+ transformer.traverse unnamed: true, one2one: one2one, bar: bar do |k,v|
33
+ if source.type == :double
34
+ if one2one
35
+ res = NamedArray.zip_fields(v).collect do |_v|
36
+ field_value = _v[field_pos]
37
+
38
+ if delete
39
+ new_values = _v.dup
40
+ new_values.delete_at field_pos
41
+ else
42
+ new_values = _v
43
+ end
44
+
45
+ new_key = [k,field_value] * sep
46
+ new_values = new_values.collect{|e| [e] } if transformer.type == :double
47
+ [new_key, new_values]
48
+ end
49
+ else
50
+ all_values = v.collect{|e| e.dup }
51
+ all_values.delete_at field_pos if delete
52
+ res = NamedArray.zip_fields(v).collect do |_v|
53
+ field_value = _v[field_pos]
54
+
55
+ new_key = [k,field_value] * sep
56
+ new_values = all_values if transformer.type == :double
57
+ [new_key, new_values]
58
+ end
59
+ end
60
+
61
+ MultipleResult.setup(res)
62
+ else
63
+ field_value = v[field_pos]
64
+
65
+ if delete
66
+ new_values = v.dup
67
+ new_values.delete_at field_pos
68
+ else
69
+ new_values = v
70
+ end
71
+
72
+ new_key = [k,field_value] * sep
73
+
74
+ new_values = new_values.collect{|e| [e] } if transformer.type == :double
75
+
76
+ [new_key, new_values]
77
+ end
78
+ end
79
+
80
+ stream ? transformer : transformer.tsv(merge: merge)
81
+ end
82
+
83
+ def unzip(*args, **kwargs)
84
+ TSV.unzip(self, *args, **kwargs)
85
+ end
86
+ end
@@ -1,24 +1,131 @@
1
1
  #require_relative '../../../modules/rbbt-util/lib/rbbt/tsv/manipulate'
2
2
  #Log.warn "USING OLD RBBT CODE: #{__FILE__}"
3
+ require_relative 'traverse'
4
+ require_relative 'util/filter'
5
+ require_relative 'util/process'
6
+ require_relative 'util/select'
7
+ require_relative 'util/reorder'
8
+ require_relative 'util/unzip'
3
9
  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
10
+ def self.identify_field(key_field, fields, name, strict: nil)
11
+ return :key if name == :key || (! strict && NamedArray.field_match(key_field, name))
12
+ name.collect!{|n| key_field == n ? :key : n } if Array === name
13
+ NamedArray.identify_name(fields, name, strict: strict)
14
+ end
23
15
 
16
+ def identify_field(name, strict: nil)
17
+ TSV.identify_field(@key_field, @fields, name, strict: strict)
18
+ end
19
+
20
+ def [](key, *rest)
21
+ v = super(key, *rest)
22
+ NamedArray.setup(v, @fields, key) unless @unnamed || ! (Array === v)
23
+ v
24
+ end
25
+
26
+ def options
27
+ extension_attr_hash
28
+ end
29
+
30
+ def zip_new(key, values, insitu: :lax)
31
+ values = values.collect{|v| Array === v ? v : [v] } unless Array === values.first
32
+ if current_values = self[key]
33
+ if insitu == :lax
34
+ self[key] = NamedArray.add_zipped(current_values, values)
35
+ elsif insitu
36
+ NamedArray.add_zipped(current_values, values)
37
+ else
38
+ self[key] = NamedArray.add_zipped(current_values.dup, values)
39
+ end
40
+ else
41
+ if insitu && insitu != :lax
42
+ self[key] = values.dup
43
+ else
44
+ self[key] = values
45
+ end
46
+ end
47
+ end
48
+
49
+ def each(*args, &block)
50
+ if block_given?
51
+ super(*args) do |k,v|
52
+ NamedArray.setup(v, @fields) unless @unnamed || ! (Array === v)
53
+ block.call(k, v)
54
+ end
55
+ else
56
+ super(*args)
57
+ end
58
+ end
59
+
60
+ def collect(*args, &block)
61
+ if block_given?
62
+ res = []
63
+ each do |k,v|
64
+ res << yield(k, v)
65
+ end
66
+ res
67
+ else
68
+ super(*args)
69
+ end
70
+ end
71
+
72
+ def with_unnamed(unnamed = true)
73
+ begin
74
+ old_unnamed = @unnamed
75
+ @unnamed = unnamed
76
+ yield
77
+ ensure
78
+ @unnamed = old_unnamed
79
+ end
80
+ end
81
+
82
+ def summary
83
+ key = nil
84
+ values = nil
85
+ self.each do |k, v|
86
+ key = k
87
+ values = v
88
+ break
89
+ end
90
+
91
+ filename = @filename
92
+ filename = "No filename" if filename.nil? || String === filename && filename.empty?
93
+ filename.find if Path === filename
94
+ filename = File.basename(filename) + " [" + File.basename(persistence_path) + "]" if respond_to?(:persistence_path) and persistence_path
95
+
96
+ with_unnamed do
97
+ <<-EOF
98
+ Filename = #{filename}
99
+ Key field = #{key_field || "*No key field*"}
100
+ Fields = #{fields ? Log.fingerprint(fields) : "*No field info*"}
101
+ Type = #{type}
102
+ Size = #{size}
103
+ namespace = #{Log.fingerprint namespace}
104
+ identifiers = #{Log.fingerprint identifiers}
105
+ Example:
106
+ - #{key} -- #{Log.fingerprint values }
107
+ EOF
108
+ end
109
+ end
110
+
111
+ def all_fields
112
+ return [] if @fields.nil?
113
+ [@key_field] + @fields
114
+ end
115
+
116
+ def options
117
+ self.extension_attr_hash
118
+ end
119
+
120
+ def fingerprint
121
+ "TSV:{"<< Log.fingerprint(self.all_fields|| []) << ";" << Log.fingerprint(self.keys) << "}"
122
+ end
123
+
124
+ def digest_str
125
+ fingerprint
126
+ end
127
+
128
+ def inspect
129
+ fingerprint
130
+ end
24
131
  end
data/lib/scout/tsv.rb CHANGED
@@ -2,26 +2,49 @@ require_relative 'meta_extension'
2
2
  require_relative 'tsv/util'
3
3
  require_relative 'tsv/parser'
4
4
  require_relative 'tsv/dumper'
5
+ require_relative 'tsv/transformer'
5
6
  require_relative 'tsv/persist'
6
7
  require_relative 'tsv/index'
7
8
  require_relative 'tsv/path'
8
9
  require_relative 'tsv/traverse'
10
+ require_relative 'tsv/open'
11
+ require_relative 'tsv/attach'
12
+ require_relative 'tsv/change_id'
9
13
 
10
14
  module TSV
11
15
  extend MetaExtension
12
- extension_attr :key_field, :fields, :type, :filename, :namespace, :unnamed
16
+ extension_attr :key_field, :fields, :type, :filename, :namespace, :unnamed, :identifiers
17
+
18
+ def self.str2options(str)
19
+ field_options,_sep, rest = str.partition("#")
20
+ key, fields_str = field_options.split("~")
21
+
22
+ fields = fields_str.nil? ? [] : fields_str.split(/,\s*/)
23
+
24
+ rest = ":type=" << rest if rest =~ /^:?\w+$/
25
+ rest_options = rest.nil? ? {} : IndiferentHash.string2hash(rest)
26
+
27
+ {:key_field => key, :fields => fields}.merge(rest_options)
28
+ end
29
+
30
+ def self.str_setup(option_str, obj)
31
+ options = TSV.str2options(option_str)
32
+ setup(obj, options)
33
+ end
13
34
 
14
35
  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|
36
+ persist, type, grep, invert_grep = IndiferentHash.process_options options, :persist, :persist_type, :grep, :invert_grep, :persist => false, :persist_type => "HDB"
37
+ type = type.to_sym if type
38
+ file = StringIO.new file if String === file && ! (Path === file) && file.index("\n")
39
+ Persist.persist(file, type, options.merge(:persist => persist, :prefix => "Tsv", :other_options => options)) do |filename|
17
40
  data = filename ? ScoutCabinet.open(filename, true, type) : nil
18
41
  options[:data] = data if data
19
42
  options[:filename] = file
20
- Open.open(file) do |f|
43
+ Log.debug "TSV open #{Log.fingerprint file}"
44
+ Open.open(file, grep: grep, invert_grep: invert_grep) do |f|
21
45
  TSV.parse(f, **options)
22
46
  end
23
47
  end
24
48
  end
25
-
26
49
  end
27
50
 
@@ -3,7 +3,7 @@ require 'scout/semaphore'
3
3
  require 'scout/exceptions'
4
4
  class WorkQueue
5
5
  class Socket
6
- attr_accessor :sread, :swrite, :write_sem, :read_sem, :cleaned
6
+ attr_accessor :sread, :swrite, :write_sem, :read_sem, :cleaned, :exception
7
7
  def initialize(serializer = nil)
8
8
  @sread, @swrite = Open.pipe
9
9
 
@@ -112,6 +112,11 @@ class WorkQueue
112
112
  end
113
113
  end
114
114
 
115
+ def abort(exception)
116
+ @exception = exception
117
+ @swrite.close unless closed_write?
118
+ end
119
+
115
120
  alias write push
116
121
 
117
122
  alias read pop
@@ -27,8 +27,10 @@ class WorkQueue
27
27
  rescue Interrupt
28
28
  rescue Exception
29
29
  output.write WorkerException.new($!, Process.pid)
30
- exit -1
30
+ Process.exit! -1
31
+ ensure
31
32
  end
33
+ Process.exit! 0
32
34
  end
33
35
  end
34
36
 
@@ -36,7 +38,8 @@ class WorkQueue
36
38
  begin
37
39
  Log.debug "Aborting worker #{@pid}"
38
40
  Process.kill "INT", @pid
39
- rescue Errno::ECHILD
41
+ rescue Errno::ECHILD
42
+ rescue Errno::ESRCH
40
43
  end
41
44
  end
42
45