scout-gear 6.0.0 → 7.1.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.
- 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
         
     |