scout-gear 6.0.0 → 7.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.vimproject +436 -432
- data/VERSION +1 -1
- data/lib/scout/exceptions.rb +8 -0
- data/lib/scout/log/color.rb +29 -2
- data/lib/scout/log/progress/util.rb +2 -0
- data/lib/scout/log/progress.rb +2 -0
- data/lib/scout/log.rb +5 -1
- data/lib/scout/misc/digest.rb +1 -3
- data/lib/scout/open/stream.rb +20 -19
- data/lib/scout/tsv/parser.rb +144 -0
- data/lib/scout/tsv.rb +14 -0
- data/lib/scout/work_queue/worker.rb +16 -11
- data/lib/scout/work_queue.rb +48 -21
- data/lib/scout/workflow/step/info.rb +2 -2
- data/lib/scout/workflow/step.rb +2 -1
- data/lib/scout/workflow/task.rb +2 -2
- data/scout-gear.gemspec +7 -3
- data/test/scout/open/test_stream.rb +1 -1
- data/test/scout/test_semaphore.rb +1 -1
- data/test/scout/test_tsv.rb +34 -0
- data/test/scout/test_work_queue.rb +28 -0
- data/test/scout/tsv/test_parser.rb +87 -0
- data/test/scout/work_queue/test_worker.rb +48 -0
- metadata +6 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
7.1.0
|
data/lib/scout/exceptions.rb
CHANGED
@@ -84,6 +84,14 @@ class DoneProcessing < Exception
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
class WorkerException < ScoutException
|
88
|
+
attr_accessor :exception, :pid
|
89
|
+
def initialize(exception, pid)
|
90
|
+
@exception = exception
|
91
|
+
@pid = pid
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
87
95
|
|
88
96
|
#class OpenGzipError < StandardError; end
|
89
97
|
#
|
data/lib/scout/log/color.rb
CHANGED
@@ -143,13 +143,14 @@ module Log
|
|
143
143
|
CONCEPT_COLORS = IndiferentHash.setup({
|
144
144
|
:title => magenta,
|
145
145
|
:path => blue,
|
146
|
-
:input =>
|
146
|
+
:input => cyan,
|
147
147
|
:value => green,
|
148
148
|
:integer => green,
|
149
149
|
:negative => red,
|
150
150
|
:float => green,
|
151
151
|
:waiting => yellow,
|
152
|
-
:started =>
|
152
|
+
:started => cyan,
|
153
|
+
:start => cyan,
|
153
154
|
:done => green,
|
154
155
|
:error => red,
|
155
156
|
})
|
@@ -166,10 +167,36 @@ module Log
|
|
166
167
|
def self.color(color, str = nil, reset = false)
|
167
168
|
return str.dup || "" if nocolor
|
168
169
|
|
170
|
+
if (color == :integer || color == :float) && Numeric === str
|
171
|
+
color = if str < 0
|
172
|
+
:red
|
173
|
+
elsif str > 1
|
174
|
+
:cyan
|
175
|
+
else
|
176
|
+
:green
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
if color == :status
|
181
|
+
color = case str.to_sym
|
182
|
+
when :done
|
183
|
+
:green
|
184
|
+
when :error, :aborted
|
185
|
+
:red
|
186
|
+
when :waiting, :queued
|
187
|
+
:yellow
|
188
|
+
when :started, :start, :streamming
|
189
|
+
:cyan
|
190
|
+
else
|
191
|
+
:cyan
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
169
195
|
color = SEVERITY_COLOR[color] if Integer === color
|
170
196
|
color = CONCEPT_COLORS[color] if CONCEPT_COLORS.include?(color)
|
171
197
|
color = Term::ANSIColor.send(color) if Symbol === color and Term::ANSIColor.respond_to?(color)
|
172
198
|
|
199
|
+
str = str.to_s unless str.nil?
|
173
200
|
return str if Symbol === color
|
174
201
|
color_str = reset ? Term::ANSIColor.reset : ""
|
175
202
|
color_str << color
|
data/lib/scout/log/progress.rb
CHANGED
data/lib/scout/log.rb
CHANGED
@@ -206,7 +206,11 @@ module Log
|
|
206
206
|
line = line.sub('`',"'")
|
207
207
|
color = :green if line =~ /workflow/
|
208
208
|
color = :blue if line =~ /scout-/
|
209
|
-
|
209
|
+
if color
|
210
|
+
Log.color color, line
|
211
|
+
else
|
212
|
+
line
|
213
|
+
end
|
210
214
|
end unless stack.nil?
|
211
215
|
end
|
212
216
|
|
data/lib/scout/misc/digest.rb
CHANGED
data/lib/scout/open/stream.rb
CHANGED
@@ -31,13 +31,16 @@ module Open
|
|
31
31
|
Thread.current.report_on_exception = false
|
32
32
|
consume_stream(io, false, into, into_close)
|
33
33
|
end
|
34
|
+
|
34
35
|
io.threads.push(consumer_thread) if io.respond_to?(:threads)
|
36
|
+
Thread.pass until consumer_thread["name"]
|
37
|
+
|
35
38
|
consumer_thread
|
36
39
|
else
|
37
40
|
if into
|
38
|
-
Log.
|
41
|
+
Log.low "Consuming stream #{Log.fingerprint io} -> #{Log.fingerprint into}"
|
39
42
|
else
|
40
|
-
Log.
|
43
|
+
Log.low "Consuming stream #{Log.fingerprint io}"
|
41
44
|
end
|
42
45
|
|
43
46
|
begin
|
@@ -53,7 +56,6 @@ module Open
|
|
53
56
|
into_close = false unless into.respond_to? :close
|
54
57
|
io.sync = true
|
55
58
|
|
56
|
-
Log.high "started consuming stream #{Log.fingerprint io}"
|
57
59
|
begin
|
58
60
|
while c = io.readpartial(BLOCK_SIZE)
|
59
61
|
into << c if into
|
@@ -67,15 +69,14 @@ module Open
|
|
67
69
|
into.close if into and into_close and not into.closed?
|
68
70
|
block.call if block_given?
|
69
71
|
|
70
|
-
Log.high "Done consuming stream #{Log.fingerprint io} into #{into_path || into}"
|
71
72
|
c
|
72
73
|
rescue Aborted
|
73
|
-
Log.
|
74
|
+
Log.low "Consume stream Aborted #{Log.fingerprint io} into #{into_path || into}"
|
74
75
|
io.abort $! if io.respond_to? :abort
|
75
76
|
into.close if into.respond_to?(:closed?) && ! into.closed?
|
76
77
|
FileUtils.rm into_path if into_path and File.exist?(into_path)
|
77
78
|
rescue Exception
|
78
|
-
Log.
|
79
|
+
Log.low "Consume stream Exception reading #{Log.fingerprint io} into #{into_path || into} - #{$!.message}"
|
79
80
|
exception = io.stream_exception || $!
|
80
81
|
io.abort exception if io.respond_to? :abort
|
81
82
|
into.close if into.respond_to?(:closed?) && ! into.closed?
|
@@ -145,12 +146,12 @@ module Open
|
|
145
146
|
|
146
147
|
Open.notify_write(path)
|
147
148
|
rescue Aborted
|
148
|
-
Log.
|
149
|
+
Log.low "Aborted sensible_write -- #{ Log.reset << Log.color(:blue, path) }"
|
149
150
|
content.abort if content.respond_to? :abort
|
150
151
|
Open.rm path if File.exist? path
|
151
152
|
rescue Exception
|
152
153
|
exception = (AbortedStream === content and content.exception) ? content.exception : $!
|
153
|
-
Log.
|
154
|
+
Log.low "Exception in sensible_write: [#{Process.pid}] #{exception.message} -- #{ Log.color :blue, path }"
|
154
155
|
content.abort if content.respond_to? :abort
|
155
156
|
Open.rm path if File.exist? path
|
156
157
|
raise exception
|
@@ -219,16 +220,15 @@ module Open
|
|
219
220
|
|
220
221
|
#parent_pid = Process.pid
|
221
222
|
pid = Process.fork {
|
222
|
-
purge_pipes(sin)
|
223
|
-
sout.close
|
224
223
|
begin
|
224
|
+
purge_pipes(sin)
|
225
|
+
sout.close
|
225
226
|
|
226
227
|
yield sin
|
227
228
|
sin.close if close and not sin.closed?
|
228
229
|
|
229
230
|
rescue Exception
|
230
231
|
Log.exception $!
|
231
|
-
#Process.kill :INT, parent_pid
|
232
232
|
Kernel.exit!(-1)
|
233
233
|
end
|
234
234
|
Kernel.exit! 0
|
@@ -242,18 +242,18 @@ module Open
|
|
242
242
|
ConcurrentStream.setup sout, :pair => sin
|
243
243
|
|
244
244
|
thread = Thread.new do
|
245
|
-
Thread.current["name"] = "Pipe input #{Log.fingerprint sin} => #{Log.fingerprint sout}"
|
246
|
-
Thread.current.report_on_exception = false
|
247
245
|
begin
|
246
|
+
Thread.current.report_on_exception = false
|
247
|
+
Thread.current["name"] = "Pipe input #{Log.fingerprint sin} => #{Log.fingerprint sout}"
|
248
248
|
|
249
249
|
yield sin
|
250
250
|
|
251
251
|
sin.close if close and not sin.closed? and not sin.aborted?
|
252
252
|
rescue Aborted
|
253
|
-
Log.
|
253
|
+
Log.low "Aborted open_pipe: #{$!.message}"
|
254
254
|
raise $!
|
255
255
|
rescue Exception
|
256
|
-
Log.
|
256
|
+
Log.low "Exception in open_pipe: #{$!.message}"
|
257
257
|
begin
|
258
258
|
sout.threads.delete(Thread.current)
|
259
259
|
sout.pair = []
|
@@ -269,6 +269,7 @@ module Open
|
|
269
269
|
|
270
270
|
sin.threads = [thread]
|
271
271
|
sout.threads = [thread]
|
272
|
+
Thread.pass until thread["name"]
|
272
273
|
end
|
273
274
|
|
274
275
|
sout
|
@@ -287,8 +288,8 @@ module Open
|
|
287
288
|
|
288
289
|
splitter_thread = Thread.new(Thread.current) do |parent|
|
289
290
|
begin
|
290
|
-
Thread.current["name"] = "Splitter #{Log.fingerprint stream}"
|
291
291
|
Thread.current.report_on_exception = false
|
292
|
+
Thread.current["name"] = "Splitter #{Log.fingerprint stream}"
|
292
293
|
|
293
294
|
skip = [false] * num
|
294
295
|
begin
|
@@ -317,7 +318,7 @@ module Open
|
|
317
318
|
out_pipes.each do |sout|
|
318
319
|
sout.abort if sout.respond_to? :abort
|
319
320
|
end
|
320
|
-
Log.
|
321
|
+
Log.low "Tee aborting #{Log.fingerprint stream}"
|
321
322
|
raise $!
|
322
323
|
rescue Exception
|
323
324
|
begin
|
@@ -332,7 +333,7 @@ module Open
|
|
332
333
|
in_pipes.each do |sin|
|
333
334
|
sin.close unless sin.closed?
|
334
335
|
end
|
335
|
-
Log.
|
336
|
+
Log.low "Tee exception #{Log.fingerprint stream}"
|
336
337
|
rescue
|
337
338
|
Log.exception $!
|
338
339
|
ensure
|
@@ -348,7 +349,7 @@ module Open
|
|
348
349
|
out_pipes.each do |sout|
|
349
350
|
ConcurrentStream.setup sout, :threads => splitter_thread, :filename => filename, :pair => stream
|
350
351
|
end
|
351
|
-
|
352
|
+
Thread.pass until splitter_thread["name"]
|
352
353
|
|
353
354
|
main_pipe = out_pipes.first
|
354
355
|
main_pipe.autojoin = true
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module TSV
|
2
|
+
def self.cast_value(value, cast)
|
3
|
+
if Array === value
|
4
|
+
value.collect{|e| cast_value(e, cast) }
|
5
|
+
else
|
6
|
+
value.send(cast)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.parse_line(line, type: :list, key: 0, positions: nil, sep: "\t", sep2: "|", cast: nil)
|
11
|
+
items = line.split(sep, -1)
|
12
|
+
|
13
|
+
if positions.nil? && key == 0
|
14
|
+
key = items.shift
|
15
|
+
elsif positions.nil?
|
16
|
+
key = items.delete(key)
|
17
|
+
else
|
18
|
+
key, items = items[key], items.values_at(*positions)
|
19
|
+
end
|
20
|
+
|
21
|
+
items = case type
|
22
|
+
when :list
|
23
|
+
items
|
24
|
+
when :single
|
25
|
+
items.first
|
26
|
+
when :flat
|
27
|
+
[items]
|
28
|
+
when :double
|
29
|
+
items.collect{|i| i.split(sep2, -1) }
|
30
|
+
end
|
31
|
+
|
32
|
+
key = key.partition(sep2).first if type == :double
|
33
|
+
|
34
|
+
if cast
|
35
|
+
items = cast_value(items, cast)
|
36
|
+
end
|
37
|
+
|
38
|
+
[key, items]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.parse_stream(stream, data: nil, merge: true, type: :list, fix: true, bar: false, first_line: nil, **kargs, &block)
|
42
|
+
begin
|
43
|
+
bar = Log::ProgressBar.new_bar(bar) if bar
|
44
|
+
|
45
|
+
data = {} if data.nil?
|
46
|
+
merge = false if type != :double
|
47
|
+
line = first_line || stream.gets
|
48
|
+
while line
|
49
|
+
begin
|
50
|
+
line.strip!
|
51
|
+
line = Misc.fixutf8(line) if fix
|
52
|
+
bar.tick if bar
|
53
|
+
key, items = parse_line(line, type: type, **kargs)
|
54
|
+
|
55
|
+
if block_given?
|
56
|
+
res = block.call(key, items)
|
57
|
+
data[key] = res unless res.nil?
|
58
|
+
next
|
59
|
+
end
|
60
|
+
|
61
|
+
if ! merge || ! data.include?(key)
|
62
|
+
data[key] = items
|
63
|
+
else
|
64
|
+
current = data[key]
|
65
|
+
if merge == :concat
|
66
|
+
items.each_with_index do |new,i|
|
67
|
+
next if new.empty?
|
68
|
+
current[i].concat(new)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
merged = []
|
72
|
+
items.each_with_index do |new,i|
|
73
|
+
next if new.empty?
|
74
|
+
merged[i] = current[i] + new
|
75
|
+
end
|
76
|
+
data[key] = merged
|
77
|
+
end
|
78
|
+
end
|
79
|
+
ensure
|
80
|
+
line = stream.gets
|
81
|
+
end
|
82
|
+
end
|
83
|
+
data
|
84
|
+
ensure
|
85
|
+
Log::ProgressBar.remove_bar(bar) if bar
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.parse_header(stream, fix: true, header_hash: '#', sep: "\n")
|
90
|
+
raise "Closed stream" if IO === stream && stream.closed?
|
91
|
+
|
92
|
+
options = {}
|
93
|
+
preamble = []
|
94
|
+
|
95
|
+
# Get line
|
96
|
+
|
97
|
+
#Thread.pass while IO.select([stream], nil, nil, 1).nil? if IO === stream
|
98
|
+
line = stream.gets
|
99
|
+
return {} if line.nil?
|
100
|
+
line = Misc.fixutf8 line.chomp if fix
|
101
|
+
|
102
|
+
# Process options line
|
103
|
+
if line and (String === header_hash && m = line.match(/^#{header_hash}: (.*)/))
|
104
|
+
options = IndiferentHash.string2hash m.captures.first.chomp
|
105
|
+
line = stream.gets
|
106
|
+
line = Misc.fixutf8 line.chomp if line && fix
|
107
|
+
end
|
108
|
+
|
109
|
+
# Determine separator
|
110
|
+
sep = options[:sep] if options[:sep]
|
111
|
+
|
112
|
+
# Process fields line
|
113
|
+
preamble << line if line
|
114
|
+
while line && (TrueClass === header_hash || (String === header_hash && line.start_with?(header_hash)))
|
115
|
+
fields = line.split(sep, -1)
|
116
|
+
key_field = fields.shift
|
117
|
+
key_field = key_field.sub(header_hash, '') if String === header_hash && ! header_hash.empty?
|
118
|
+
|
119
|
+
line = (header_hash != "" ? stream.gets : nil)
|
120
|
+
line = Misc.fixutf8 line.chomp if line
|
121
|
+
preamble << line if line
|
122
|
+
break if TrueClass === header_hash || header_hash == ""
|
123
|
+
end
|
124
|
+
|
125
|
+
preamble = preamble[0..-3] * "\n"
|
126
|
+
|
127
|
+
line ||= stream.gets
|
128
|
+
|
129
|
+
first_line = line
|
130
|
+
|
131
|
+
[options, key_field, fields, first_line, preamble]
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.parse(stream, **kwargs)
|
135
|
+
options, key_field, fields, first_line, preamble = parse_header(stream)
|
136
|
+
|
137
|
+
options.each do |option,value|
|
138
|
+
option = option.to_sym
|
139
|
+
kwargs[option] = value unless kwargs.include?(option)
|
140
|
+
end
|
141
|
+
data = parse_stream(stream, first_line: first_line, **kwargs)
|
142
|
+
TSV.setup data, :key_field => key_field, :fields => fields
|
143
|
+
end
|
144
|
+
end
|
data/lib/scout/tsv.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'meta_extension'
|
2
|
+
require_relative 'tsv/parser'
|
3
|
+
|
4
|
+
module TSV
|
5
|
+
extend MetaExtension
|
6
|
+
extension_attr :key_field, :fields
|
7
|
+
|
8
|
+
def self.open(file, options = {})
|
9
|
+
Open.open(file) do |f|
|
10
|
+
TSV.parse(f,**options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -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
|
@@ -19,33 +21,36 @@ class WorkQueue
|
|
19
21
|
raise obj
|
20
22
|
end
|
21
23
|
res = block.call obj
|
22
|
-
output.write res unless ignore_ouput || res == :ignore
|
24
|
+
output.write res unless output.nil? || 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
|
|
35
|
+
def abort
|
36
|
+
begin
|
37
|
+
Log.log "Aborting worker #{@pid}"
|
38
|
+
Process.kill "INT", @pid
|
39
|
+
rescue Errno::ECHILD
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
33
43
|
def join
|
34
44
|
Log.log "Joining worker #{@pid}"
|
35
45
|
Process.waitpid @pid
|
36
46
|
end
|
37
47
|
|
38
|
-
def exit(status)
|
39
|
-
Log.log "Worker #{@pid} exited with status #{Log.color(:green, status)}"
|
40
|
-
end
|
41
|
-
|
42
48
|
def self.join(workers)
|
43
49
|
workers = [workers] unless Array === workers
|
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
|
data/lib/scout/work_queue.rb
CHANGED
@@ -35,52 +35,79 @@ class WorkQueue
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def remove_worker(pid)
|
38
|
-
|
39
|
-
|
40
|
-
@removed_workers
|
38
|
+
@worker_mutex.synchronize do
|
39
|
+
@workers.delete_if{|w| w.pid == pid }
|
40
|
+
@removed_workers << pid
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
def process(&callback)
|
45
|
-
@
|
46
|
-
w.process @input, @output, &@worker_proc
|
47
|
-
end
|
48
|
-
@reader = Thread.new do
|
45
|
+
@reader = Thread.new do |parent|
|
49
46
|
begin
|
47
|
+
Thread.current.report_on_exception = false
|
48
|
+
Thread.current["name"] = "Output reader #{Process.pid}"
|
49
|
+
@done_workers ||= []
|
50
50
|
while true
|
51
51
|
obj = @output.read
|
52
52
|
if DoneProcessing === obj
|
53
|
-
|
53
|
+
done = @worker_mutex.synchronize do
|
54
|
+
Log.low "Worker #{obj.pid} done"
|
55
|
+
@done_workers << obj.pid
|
56
|
+
@done_workers.length == @removed_workers.length + @workers.length
|
57
|
+
end
|
58
|
+
break if done
|
59
|
+
elsif Exception === obj
|
60
|
+
raise obj
|
54
61
|
else
|
55
62
|
callback.call obj if callback
|
56
63
|
end
|
57
64
|
end
|
65
|
+
rescue DoneProcessing
|
58
66
|
rescue Aborted
|
67
|
+
rescue WorkerException
|
68
|
+
Log.error "Exception in worker #{obj.pid} #{Log.fingerprint obj.exception}"
|
69
|
+
self.abort
|
70
|
+
raise obj.exception
|
59
71
|
end
|
60
|
-
end
|
72
|
+
end
|
73
|
+
|
74
|
+
@workers.each do |w|
|
75
|
+
w.process @input, @output, &@worker_proc
|
76
|
+
end
|
77
|
+
|
78
|
+
Thread.pass until @reader["name"]
|
79
|
+
|
80
|
+
@waiter = Thread.new do
|
81
|
+
begin
|
82
|
+
Thread.current.report_on_exception = false
|
83
|
+
Thread.current["name"] = "Worker waiter #{Process.pid}"
|
84
|
+
while true
|
85
|
+
pid = Process.wait
|
86
|
+
remove_worker(pid)
|
87
|
+
break if workers.empty?
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
Thread.pass until @waiter["name"]
|
61
93
|
end
|
62
94
|
|
63
95
|
def write(obj)
|
64
96
|
@input.write obj
|
65
97
|
end
|
66
98
|
|
99
|
+
def abort
|
100
|
+
workers.each{|w| w.abort }
|
101
|
+
end
|
102
|
+
|
67
103
|
def close
|
68
|
-
|
69
|
-
|
70
|
-
@input.write DoneProcessing.new
|
71
|
-
pid = Process.wait
|
72
|
-
status = $?
|
73
|
-
worker = @worker_mutex.synchronize{ @removed_workers.delete_if{|w| w.pid == pid }.first }
|
74
|
-
worker.exit $?.exitstatus if worker
|
75
|
-
rescue Errno::ECHILD
|
76
|
-
Thread.pass until @workers.length == 0
|
77
|
-
break
|
78
|
-
end
|
104
|
+
@worker_mutex.synchronize{ @workers.length }.times do
|
105
|
+
@input.write DoneProcessing.new()
|
79
106
|
end
|
80
|
-
@reader.raise Aborted if @reader
|
81
107
|
end
|
82
108
|
|
83
109
|
def join
|
110
|
+
@waiter.join if @waiter
|
84
111
|
@reader.join if @reader
|
85
112
|
end
|
86
113
|
end
|
@@ -55,9 +55,9 @@ class Step
|
|
55
55
|
|
56
56
|
def report_status(status, message = nil)
|
57
57
|
if message.nil?
|
58
|
-
Log.info Log.color(status, status
|
58
|
+
Log.info Log.color(:status, status, true) + " " + Log.color(:path, path)
|
59
59
|
else
|
60
|
-
Log.info Log.color(status, status
|
60
|
+
Log.info Log.color(:status, status, true) + " " + Log.color(:path, path) + " " + message
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
data/lib/scout/workflow/step.rb
CHANGED
data/lib/scout/workflow/task.rb
CHANGED
@@ -143,8 +143,8 @@ module Task
|
|
143
143
|
non_default_inputs.concat provided_inputs.keys.select{|k| String === k && k.include?("#") } if Hash === provided_inputs
|
144
144
|
|
145
145
|
if non_default_inputs.any?
|
146
|
-
hash = Misc.digest(:inputs => input_hash, :
|
147
|
-
Log.debug "Hash #{name} - #{hash}: #{Misc.digest_str(:inputs => inputs, :dependencies => dependencies)}"
|
146
|
+
hash = Misc.digest(:inputs => input_hash, :dependencies => dependencies)
|
147
|
+
Log.debug "Hash #{name} - #{hash}: #{Misc.digest_str(:inputs => inputs, :non_default_inputs => non_default_inputs, :dependencies => dependencies)}"
|
148
148
|
id = [id, hash] * "_"
|
149
149
|
end
|
150
150
|
|
data/scout-gear.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: scout-gear
|
5
|
+
# stub: scout-gear 7.1.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "scout-gear".freeze
|
9
|
-
s.version = "
|
9
|
+
s.version = "7.1.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Miguel Vazquez".freeze]
|
14
|
-
s.date = "2023-
|
14
|
+
s.date = "2023-05-01"
|
15
15
|
s.description = "Temporary files, logs, etc.".freeze
|
16
16
|
s.email = "mikisvaz@gmail.com".freeze
|
17
17
|
s.executables = ["scout".freeze]
|
@@ -77,6 +77,8 @@ Gem::Specification.new do |s|
|
|
77
77
|
"lib/scout/simple_opt/parse.rb",
|
78
78
|
"lib/scout/simple_opt/setup.rb",
|
79
79
|
"lib/scout/tmpfile.rb",
|
80
|
+
"lib/scout/tsv.rb",
|
81
|
+
"lib/scout/tsv/parser.rb",
|
80
82
|
"lib/scout/work_queue.rb",
|
81
83
|
"lib/scout/work_queue/socket.rb",
|
82
84
|
"lib/scout/work_queue/worker.rb",
|
@@ -137,8 +139,10 @@ Gem::Specification.new do |s|
|
|
137
139
|
"test/scout/test_resource.rb",
|
138
140
|
"test/scout/test_semaphore.rb",
|
139
141
|
"test/scout/test_tmpfile.rb",
|
142
|
+
"test/scout/test_tsv.rb",
|
140
143
|
"test/scout/test_work_queue.rb",
|
141
144
|
"test/scout/test_workflow.rb",
|
145
|
+
"test/scout/tsv/test_parser.rb",
|
142
146
|
"test/scout/work_queue/test_socket.rb",
|
143
147
|
"test/scout/work_queue/test_worker.rb",
|
144
148
|
"test/scout/workflow/step/test_info.rb",
|
@@ -4,7 +4,7 @@ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1
|
|
4
4
|
require 'scout/work_queue/worker'
|
5
5
|
class TestSemaphore < Test::Unit::TestCase
|
6
6
|
|
7
|
-
def
|
7
|
+
def test_simple
|
8
8
|
ScoutSemaphore.with_semaphore 1 do |sem|
|
9
9
|
10.times do
|
10
10
|
ScoutSemaphore.synchronize(sem) do
|