rbbt-util 5.19.37 → 5.20.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/lib/rbbt/rest/client/step.rb +73 -24
 - data/lib/rbbt/tsv/stream.rb +3 -2
 - data/lib/rbbt/util/misc/exceptions.rb +13 -1
 - data/lib/rbbt/util/misc/inspect.rb +2 -2
 - data/lib/rbbt/util/misc/multipart_payload.rb +27 -23
 - data/lib/rbbt/util/misc/pipes.rb +6 -5
 - data/lib/rbbt/workflow/accessor.rb +4 -4
 - data/lib/rbbt/workflow/step.rb +13 -5
 - data/lib/rbbt/workflow/step/run.rb +139 -90
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 333a3110a30ab60b25c3e7a5acb5364c2b75cf87
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 73610983c2f10ee9ec6cfcc3693e6569174a433d
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 433fe181900362ba716a2fdaf9924a08458f2d75d15e41d0b86a9fcab8315c7dfbfa23998f114bfe08cdce03f057fd9af94a3721afdd9f732fd640f2f1789311
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: f3ff2dc3ff968917dce9851548c8cafd5c2a7e26666f25fc7be70da1de45a92c5e65c8ea95ac353eb841663f88c76fdf2b6500b5d7e9abab68975876c7bf0226
         
     | 
| 
         @@ -6,9 +6,8 @@ class WorkflowRESTClient 
     | 
|
| 
       6 
6 
     | 
    
         
             
                def self.get_streams(inputs)
         
     | 
| 
       7 
7 
     | 
    
         
             
                  new_inputs = {}
         
     | 
| 
       8 
8 
     | 
    
         
             
                  inputs.each do |k,v|
         
     | 
| 
       9 
     | 
    
         
            -
                    if Step === v  
     | 
| 
       10 
     | 
    
         
            -
                      v 
     | 
| 
       11 
     | 
    
         
            -
                      new_inputs[k] = v.load
         
     | 
| 
      
 9 
     | 
    
         
            +
                    if Step === v 
         
     | 
| 
      
 10 
     | 
    
         
            +
                      new_inputs[k] = TSV.get_stream v
         
     | 
| 
       12 
11 
     | 
    
         
             
                    else
         
     | 
| 
       13 
12 
     | 
    
         
             
                      new_inputs[k] = v
         
     | 
| 
       14 
13 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -16,12 +15,27 @@ class WorkflowRESTClient 
     | 
|
| 
       16 
15 
     | 
    
         
             
                  new_inputs
         
     | 
| 
       17 
16 
     | 
    
         
             
                end
         
     | 
| 
       18 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
                def get_streams
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @inputs = WorkflowRESTClient::RemoteStep.get_streams @inputs
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
       19 
22 
     | 
    
         | 
| 
       20 
23 
     | 
    
         
             
                def initialize(base_url, task = nil, base_name = nil, inputs = nil, result_type = nil, result_description = nil, is_exec = false, stream_input = nil)
         
     | 
| 
       21 
24 
     | 
    
         
             
                  @base_url, @task, @base_name, @inputs, @result_type, @result_description, @is_exec = base_url, task, base_name, inputs, result_type, result_description, is_exec
         
     | 
| 
       22 
25 
     | 
    
         
             
                  @mutex = Mutex.new
         
     | 
| 
       23 
26 
     | 
    
         
             
                  @stream_input = stream_input
         
     | 
| 
       24 
     | 
    
         
            -
                   
     | 
| 
      
 27 
     | 
    
         
            +
                  #@inputs = RemoteStep.get_streams @inputs
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def dup_inputs
         
     | 
| 
      
 31 
     | 
    
         
            +
                  return if @dupped or ENV["RBBT_NO_STREAM"] == 'true'
         
     | 
| 
      
 32 
     | 
    
         
            +
                  Log.low "Dupping inputs for remote #{path}"
         
     | 
| 
      
 33 
     | 
    
         
            +
                  new_inputs = {}
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @inputs.each do |name,input|
         
     | 
| 
      
 35 
     | 
    
         
            +
                    new_inputs[name] = Step.dup_stream input
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @inputs = RemoteStep.get_streams new_inputs
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @dupped = true
         
     | 
| 
       25 
39 
     | 
    
         
             
                end
         
     | 
| 
       26 
40 
     | 
    
         | 
| 
       27 
41 
     | 
    
         
             
                def name
         
     | 
| 
         @@ -31,7 +45,7 @@ class WorkflowRESTClient 
     | 
|
| 
       31 
45 
     | 
    
         
             
                end
         
     | 
| 
       32 
46 
     | 
    
         | 
| 
       33 
47 
     | 
    
         
             
                def task_name
         
     | 
| 
       34 
     | 
    
         
            -
                  return task  
     | 
| 
      
 48 
     | 
    
         
            +
                  return task if task
         
     | 
| 
       35 
49 
     | 
    
         
             
                  init_job
         
     | 
| 
       36 
50 
     | 
    
         
             
                  (Array === @url ? @url.first : @url).split("/")[-2]
         
     | 
| 
       37 
51 
     | 
    
         
             
                end
         
     | 
| 
         @@ -39,16 +53,16 @@ class WorkflowRESTClient 
     | 
|
| 
       39 
53 
     | 
    
         
             
                def info(check_lock=false)
         
     | 
| 
       40 
54 
     | 
    
         
             
                  @done = @info and @info[:status] and @info[:status].to_sym == :done
         
     | 
| 
       41 
55 
     | 
    
         
             
                  @info = Persist.memory("RemoteSteps Info", :url => @url, :persist => !!@done) do
         
     | 
| 
       42 
     | 
    
         
            -
                    init_job unless url
         
     | 
| 
       43 
     | 
    
         
            -
                    info = WorkflowRESTClient.get_json(File.join(url, 'info'))
         
     | 
| 
      
 56 
     | 
    
         
            +
                    init_job unless @url
         
     | 
| 
      
 57 
     | 
    
         
            +
                    info = WorkflowRESTClient.get_json(File.join(@url, 'info'))
         
     | 
| 
       44 
58 
     | 
    
         
             
                    info = WorkflowRESTClient.fix_hash(info)
         
     | 
| 
       45 
59 
     | 
    
         
             
                    info[:status] = info[:status].to_sym if String === info[:status]
         
     | 
| 
       46 
60 
     | 
    
         
             
                    info
         
     | 
| 
       47 
61 
     | 
    
         
             
                  end
         
     | 
| 
       48 
62 
     | 
    
         
             
                end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
       50 
64 
     | 
    
         
             
                def status
         
     | 
| 
       51 
     | 
    
         
            -
                  return nil  
     | 
| 
      
 65 
     | 
    
         
            +
                  return nil unless url or started?
         
     | 
| 
       52 
66 
     | 
    
         
             
                  begin
         
     | 
| 
       53 
67 
     | 
    
         
             
                    info[:status]
         
     | 
| 
       54 
68 
     | 
    
         
             
                  ensure
         
     | 
| 
         @@ -56,6 +70,10 @@ class WorkflowRESTClient 
     | 
|
| 
       56 
70 
     | 
    
         
             
                  end
         
     | 
| 
       57 
71 
     | 
    
         
             
                end
         
     | 
| 
       58 
72 
     | 
    
         | 
| 
      
 73 
     | 
    
         
            +
                def started?
         
     | 
| 
      
 74 
     | 
    
         
            +
                  @result != nil or @started
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
       59 
77 
     | 
    
         
             
                def done?
         
     | 
| 
       60 
78 
     | 
    
         
             
                  @done || status.to_s == 'done'
         
     | 
| 
       61 
79 
     | 
    
         
             
                end
         
     | 
| 
         @@ -68,9 +86,24 @@ class WorkflowRESTClient 
     | 
|
| 
       68 
86 
     | 
    
         
             
                  WorkflowRESTClient.get_raw(File.join(url, 'file', file))
         
     | 
| 
       69 
87 
     | 
    
         
             
                end
         
     | 
| 
       70 
88 
     | 
    
         | 
| 
      
 89 
     | 
    
         
            +
                def get_stream
         
     | 
| 
      
 90 
     | 
    
         
            +
                  case @result
         
     | 
| 
      
 91 
     | 
    
         
            +
                  when IO 
         
     | 
| 
      
 92 
     | 
    
         
            +
                    @result
         
     | 
| 
      
 93 
     | 
    
         
            +
                  when String
         
     | 
| 
      
 94 
     | 
    
         
            +
                    StringIO.new @result
         
     | 
| 
      
 95 
     | 
    
         
            +
                  else
         
     | 
| 
      
 96 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                def grace
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       71 
103 
     | 
    
         
             
                #{{{ MANAGEMENT
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
       73 
105 
     | 
    
         
             
                def init_job(cache_type = nil, other_params = {})
         
     | 
| 
      
 106 
     | 
    
         
            +
                  Log.stack caller
         
     | 
| 
       74 
107 
     | 
    
         
             
                  cache_type = :asynchronous if cache_type.nil? and not @is_exec
         
     | 
| 
       75 
108 
     | 
    
         
             
                  cache_type = :exec if cache_type.nil?
         
     | 
| 
       76 
109 
     | 
    
         
             
                  @name ||= Persist.memory("RemoteSteps", :workflow => self, :task => task, :jobname => @name, :inputs => inputs, :cache_type => cache_type) do
         
     | 
| 
         @@ -108,6 +141,8 @@ class WorkflowRESTClient 
     | 
|
| 
       108 
141 
     | 
    
         
             
                                    init_job 
         
     | 
| 
       109 
142 
     | 
    
         
             
                                    self.load
         
     | 
| 
       110 
143 
     | 
    
         
             
                                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
                                ensure
         
     | 
| 
      
 145 
     | 
    
         
            +
                                  @started = true
         
     | 
| 
       111 
146 
     | 
    
         
             
                                end
         
     | 
| 
       112 
147 
     | 
    
         
             
                  end
         
     | 
| 
       113 
148 
     | 
    
         | 
| 
         @@ -116,11 +151,15 @@ class WorkflowRESTClient 
     | 
|
| 
       116 
151 
     | 
    
         
             
                end
         
     | 
| 
       117 
152 
     | 
    
         | 
| 
       118 
153 
     | 
    
         
             
                def exec(noload = false)
         
     | 
| 
       119 
     | 
    
         
            -
                   
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
      
 154 
     | 
    
         
            +
                  @result ||= begin
         
     | 
| 
      
 155 
     | 
    
         
            +
                                 if noload == :stream
         
     | 
| 
      
 156 
     | 
    
         
            +
                                   _run_job(:exec)
         
     | 
| 
      
 157 
     | 
    
         
            +
                                 else
         
     | 
| 
      
 158 
     | 
    
         
            +
                                   exec_job 
         
     | 
| 
      
 159 
     | 
    
         
            +
                                 end
         
     | 
| 
      
 160 
     | 
    
         
            +
                                ensure
         
     | 
| 
      
 161 
     | 
    
         
            +
                                  @started = true
         
     | 
| 
      
 162 
     | 
    
         
            +
                               end
         
     | 
| 
       124 
163 
     | 
    
         
             
                end
         
     | 
| 
       125 
164 
     | 
    
         | 
| 
       126 
165 
     | 
    
         
             
                def join
         
     | 
| 
         @@ -180,20 +219,29 @@ class WorkflowRESTClient 
     | 
|
| 
       180 
219 
     | 
    
         
             
                def _stream_job(stream_input, cache_type = :exec)
         
     | 
| 
       181 
220 
     | 
    
         
             
                  require 'rbbt/util/misc/multipart_payload'
         
     | 
| 
       182 
221 
     | 
    
         
             
                  WorkflowRESTClient.capture_exception do
         
     | 
| 
       183 
     | 
    
         
            -
                     
     | 
| 
       184 
     | 
    
         
            -
                    Log.debug{ "RestClient stream: #{  
     | 
| 
      
 222 
     | 
    
         
            +
                    task_url = URI.encode(File.join(base_url, task.to_s))
         
     | 
| 
      
 223 
     | 
    
         
            +
                    Log.debug{ "RestClient stream: #{ task_url } #{stream_input} #{cache_type} - #{Misc.fingerprint inputs}" }
         
     | 
| 
       185 
224 
     | 
    
         
             
                    task_params = inputs.merge(:_cache_type => cache_type, :jobname => base_name, :_format => [:string, :boolean, :tsv, :annotations].include?(result_type) ? :raw : :json)
         
     | 
| 
       186 
     | 
    
         
            -
                    res = RbbtMutiplartPayload.issue  
     | 
| 
      
 225 
     | 
    
         
            +
                    res = RbbtMutiplartPayload.issue task_url, task_params, stream_input, nil, nil, true
         
     | 
| 
       187 
226 
     | 
    
         
             
                    type = res.gets
         
     | 
| 
       188 
227 
     | 
    
         
             
                    case type.strip
         
     | 
| 
       189 
228 
     | 
    
         
             
                    when "LOCATION"
         
     | 
| 
       190 
     | 
    
         
            -
                      url = res.gets
         
     | 
| 
       191 
     | 
    
         
            -
                      url.sub!(/\?.*/,'')
         
     | 
| 
       192 
     | 
    
         
            -
                      WorkflowRESTClient.get_raw(url)
         
     | 
| 
       193 
     | 
    
         
            -
                    when  
     | 
| 
      
 229 
     | 
    
         
            +
                      @url = res.gets
         
     | 
| 
      
 230 
     | 
    
         
            +
                      @url.sub!(/\?.*/,'')
         
     | 
| 
      
 231 
     | 
    
         
            +
                      WorkflowRESTClient.get_raw(@url)
         
     | 
| 
      
 232 
     | 
    
         
            +
                    when /STREAM: (.*)/
         
     | 
| 
      
 233 
     | 
    
         
            +
                      @url = $1.strip
         
     | 
| 
      
 234 
     | 
    
         
            +
                      ConcurrentStream.setup(res)
         
     | 
| 
      
 235 
     | 
    
         
            +
                      res.callback = Proc.new do
         
     | 
| 
      
 236 
     | 
    
         
            +
                        @done = true
         
     | 
| 
      
 237 
     | 
    
         
            +
                      end
         
     | 
| 
       194 
238 
     | 
    
         
             
                      res
         
     | 
| 
       195 
239 
     | 
    
         
             
                    when "BULK"
         
     | 
| 
       196 
     | 
    
         
            -
                       
     | 
| 
      
 240 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 241 
     | 
    
         
            +
                        res.read
         
     | 
| 
      
 242 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 243 
     | 
    
         
            +
                        @done = true
         
     | 
| 
      
 244 
     | 
    
         
            +
                      end
         
     | 
| 
       197 
245 
     | 
    
         
             
                    else
         
     | 
| 
       198 
246 
     | 
    
         
             
                      raise "What? " + type
         
     | 
| 
       199 
247 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -206,7 +254,7 @@ class WorkflowRESTClient 
     | 
|
| 
       206 
254 
     | 
    
         
             
                    return _stream_job(stream_input, cache_type) 
         
     | 
| 
       207 
255 
     | 
    
         
             
                  end
         
     | 
| 
       208 
256 
     | 
    
         
             
                  WorkflowRESTClient.capture_exception do
         
     | 
| 
       209 
     | 
    
         
            -
                    url = URI.encode(File.join(base_url, task.to_s))
         
     | 
| 
      
 257 
     | 
    
         
            +
                    @url = URI.encode(File.join(base_url, task.to_s))
         
     | 
| 
       210 
258 
     | 
    
         
             
                    task_params = inputs.merge(:_cache_type => cache_type, :jobname => base_name, :_format => [:string, :boolean, :tsv, :annotations].include?(result_type) ? :raw : :json)
         
     | 
| 
       211 
259 
     | 
    
         | 
| 
       212 
260 
     | 
    
         
             
                    sout, sin = Misc.pipe
         
     | 
| 
         @@ -244,6 +292,7 @@ class WorkflowRESTClient 
     | 
|
| 
       244 
292 
     | 
    
         
             
                def _restart
         
     | 
| 
       245 
293 
     | 
    
         
             
                  @done = nil
         
     | 
| 
       246 
294 
     | 
    
         
             
                  @name = nil
         
     | 
| 
      
 295 
     | 
    
         
            +
                  @started = nil
         
     | 
| 
       247 
296 
     | 
    
         
             
                  new_inputs = {}
         
     | 
| 
       248 
297 
     | 
    
         
             
                  inputs.each do |k,i| 
         
     | 
| 
       249 
298 
     | 
    
         
             
                    if File === i 
         
     | 
    
        data/lib/rbbt/tsv/stream.rb
    CHANGED
    
    | 
         @@ -69,7 +69,7 @@ module TSV 
     | 
|
| 
       69 
69 
     | 
    
         
             
                    if fix_flat and parser.type == :flat and parser.first_line
         
     | 
| 
       70 
70 
     | 
    
         
             
                      parts = lines[-1].split("\t")
         
     | 
| 
       71 
71 
     | 
    
         
             
                      lines[-1] = [parts[0], (parts[1..-1] || [])*"|"] * "\t"
         
     | 
| 
       72 
     | 
    
         
            -
                      TSV.stream_flat2double(parser.stream).stream
         
     | 
| 
      
 72 
     | 
    
         
            +
                      TSV.stream_flat2double(parser.stream, :noheader => true).stream
         
     | 
| 
       73 
73 
     | 
    
         
             
                    else
         
     | 
| 
       74 
74 
     | 
    
         
             
                      parser.stream
         
     | 
| 
       75 
75 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -220,10 +220,11 @@ module TSV 
     | 
|
| 
       220 
220 
     | 
    
         
             
              end
         
     | 
| 
       221 
221 
     | 
    
         | 
| 
       222 
222 
     | 
    
         
             
              def self.stream_flat2double(stream, options = {})
         
     | 
| 
      
 223 
     | 
    
         
            +
                noheader = Misc.process_options options, :noheader
         
     | 
| 
       223 
224 
     | 
    
         
             
                parser = TSV::Parser.new TSV.get_stream(stream), :type => :flat
         
     | 
| 
       224 
225 
     | 
    
         
             
                dumper_options = parser.options.merge(options).merge(:type => :double)
         
     | 
| 
       225 
226 
     | 
    
         
             
                dumper = TSV::Dumper.new dumper_options
         
     | 
| 
       226 
     | 
    
         
            -
                dumper.init
         
     | 
| 
      
 227 
     | 
    
         
            +
                dumper.init unless noheader
         
     | 
| 
       227 
228 
     | 
    
         
             
                TSV.traverse parser, :into => dumper do |key,values|
         
     | 
| 
       228 
229 
     | 
    
         
             
                  key = key.first if Array === key
         
     | 
| 
       229 
230 
     | 
    
         
             
                  values = [values] unless Array === values
         
     | 
| 
         @@ -8,7 +8,19 @@ class Aborted < Exception; end 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            class RemoteServerError < Exception; end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
            class DependencyError <  
     | 
| 
      
 11 
     | 
    
         
            +
            class DependencyError < Aborted
         
     | 
| 
      
 12 
     | 
    
         
            +
              def initialize(msg)
         
     | 
| 
      
 13 
     | 
    
         
            +
                if defined? Step and Step === msg
         
     | 
| 
      
 14 
     | 
    
         
            +
                  step = msg
         
     | 
| 
      
 15 
     | 
    
         
            +
                  workflow = step.path.split("/")[-3]
         
     | 
| 
      
 16 
     | 
    
         
            +
                  new_msg = [workflow, step.short_path, step.messages.last] * " - "
         
     | 
| 
      
 17 
     | 
    
         
            +
                  new_msg = [step.path, step.messages.last] * ": "
         
     | 
| 
      
 18 
     | 
    
         
            +
                  super(new_msg)
         
     | 
| 
      
 19 
     | 
    
         
            +
                else
         
     | 
| 
      
 20 
     | 
    
         
            +
                  super(msg)
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
       12 
24 
     | 
    
         | 
| 
       13 
25 
     | 
    
         
             
            class KeepLocked < Exception
         
     | 
| 
       14 
26 
     | 
    
         
             
              attr_accessor :payload
         
     | 
| 
         @@ -28,7 +28,7 @@ module Misc 
     | 
|
| 
       28 
28 
     | 
    
         
             
                when nil
         
     | 
| 
       29 
29 
     | 
    
         
             
                  "nil"
         
     | 
| 
       30 
30 
     | 
    
         
             
                when (defined? Step and Step)
         
     | 
| 
       31 
     | 
    
         
            -
                  obj.path || Misc.fingerprint([obj.task.name, obj.inputs])
         
     | 
| 
      
 31 
     | 
    
         
            +
                  "<Step:"  << (obj.path || Misc.fingerprint([obj.task.name, obj.inputs])) << ">"
         
     | 
| 
       32 
32 
     | 
    
         
             
                when TrueClass
         
     | 
| 
       33 
33 
     | 
    
         
             
                  "true"
         
     | 
| 
       34 
34 
     | 
    
         
             
                when FalseClass
         
     | 
| 
         @@ -53,7 +53,7 @@ module Misc 
     | 
|
| 
       53 
53 
     | 
    
         
             
                  if (length = obj.length) > 10
         
     | 
| 
       54 
54 
     | 
    
         
             
                    "[#{length}--" <<  (obj.values_at(0,1, length / 2, -2, -1).collect{|e| fingerprint(e)} * ",") << "]"
         
     | 
| 
       55 
55 
     | 
    
         
             
                  else
         
     | 
| 
       56 
     | 
    
         
            -
                    "[" << (obj.collect{|e| fingerprint(e) } * ",") << "]"
         
     | 
| 
      
 56 
     | 
    
         
            +
                    "[" << (obj.collect{|e| fingerprint(e) } * ", ") << "]"
         
     | 
| 
       57 
57 
     | 
    
         
             
                  end
         
     | 
| 
       58 
58 
     | 
    
         
             
                when (defined? TSV and TSV)
         
     | 
| 
       59 
59 
     | 
    
         
             
                  obj.with_unnamed do
         
     | 
| 
         @@ -1,24 +1,30 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'net/http'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'rbbt-util'
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            class Net::HTTPGenericRequest
         
     | 
| 
       5 
     | 
    
         
            -
              alias old_send_request_with_body_stream send_request_with_body_stream
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
              def  
     | 
| 
       8 
     | 
    
         
            -
                 
     | 
| 
       9 
     | 
    
         
            -
                   
     | 
| 
       10 
     | 
    
         
            -
                     
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                   
     | 
| 
       14 
     | 
    
         
            -
                 
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            end
         
     | 
| 
      
 4 
     | 
    
         
            +
            #class Net::HTTPGenericRequest
         
     | 
| 
      
 5 
     | 
    
         
            +
            #  alias old_send_request_with_body_stream send_request_with_body_stream
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            #  def __send_request_with_body_stream(*args)
         
     | 
| 
      
 8 
     | 
    
         
            +
            #    begin
         
     | 
| 
      
 9 
     | 
    
         
            +
            #      pid = Process.fork do
         
     | 
| 
      
 10 
     | 
    
         
            +
            #        iii [:pre_chunk, Thread.current]
         
     | 
| 
      
 11 
     | 
    
         
            +
            #        return old_send_request_with_body_stream(*args)
         
     | 
| 
      
 12 
     | 
    
         
            +
            #      end
         
     | 
| 
      
 13 
     | 
    
         
            +
            #      Process.wait pid
         
     | 
| 
      
 14 
     | 
    
         
            +
            #    ensure
         
     | 
| 
      
 15 
     | 
    
         
            +
            #      iii [:pre_chunk_done, Thread.current]
         
     | 
| 
      
 16 
     | 
    
         
            +
            #    end
         
     | 
| 
      
 17 
     | 
    
         
            +
            #  end
         
     | 
| 
      
 18 
     | 
    
         
            +
            #end
         
     | 
| 
       17 
19 
     | 
    
         | 
| 
       18 
20 
     | 
    
         
             
            module RbbtMutiplartPayload
         
     | 
| 
       19 
21 
     | 
    
         
             
              BOUNDARY = "Rbbt_Param_Stream"
         
     | 
| 
       20 
22 
     | 
    
         
             
              EOL = "\r\n"
         
     | 
| 
       21 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
              def self.mutex
         
     | 
| 
      
 25 
     | 
    
         
            +
                @mutex ||= Mutex.new
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       22 
28 
     | 
    
         
             
              def self.input_header(name, filename = nil)
         
     | 
| 
       23 
29 
     | 
    
         | 
| 
       24 
30 
     | 
    
         
             
                if filename
         
     | 
| 
         @@ -43,9 +49,6 @@ module RbbtMutiplartPayload 
     | 
|
| 
       43 
49 
     | 
    
         
             
                header = input_header(name, filename)
         
     | 
| 
       44 
50 
     | 
    
         
             
                io.write "--" + BOUNDARY + EOL + header + EOL  + EOL
         
     | 
| 
       45 
51 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
                #while c = content.read(1024)
         
     | 
| 
       47 
     | 
    
         
            -
                #  io.write c
         
     | 
| 
       48 
     | 
    
         
            -
                #end
         
     | 
| 
       49 
52 
     | 
    
         
             
                while line = content.gets
         
     | 
| 
       50 
53 
     | 
    
         
             
                  io.puts line
         
     | 
| 
       51 
54 
     | 
    
         
             
                end
         
     | 
| 
         @@ -59,9 +62,6 @@ module RbbtMutiplartPayload 
     | 
|
| 
       59 
62 
     | 
    
         
             
              end
         
     | 
| 
       60 
63 
     | 
    
         | 
| 
       61 
64 
     | 
    
         
             
              def self.post_data_stream(inputs = nil, stream_input = nil, stream_io = nil, stream_filename = nil)
         
     | 
| 
       62 
     | 
    
         
            -
                #sout, sin = Misc.pipe
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                #Thread.new do
         
     | 
| 
       65 
65 
     | 
    
         
             
                Misc.open_pipe do |sin|
         
     | 
| 
       66 
66 
     | 
    
         
             
                  inputs.each do |input,content|
         
     | 
| 
       67 
67 
     | 
    
         
             
                    input = input.to_s
         
     | 
| 
         @@ -86,6 +86,7 @@ module RbbtMutiplartPayload 
     | 
|
| 
       86 
86 
     | 
    
         | 
| 
       87 
87 
     | 
    
         
             
                  RbbtMutiplartPayload.add_stream(sin, stream_input.to_s, stream_io, stream_filename) if stream_input
         
     | 
| 
       88 
88 
     | 
    
         
             
                  RbbtMutiplartPayload.close_stream(sin)
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
       89 
90 
     | 
    
         
             
                  sin.close unless sin.closed?
         
     | 
| 
       90 
91 
     | 
    
         
             
                end
         
     | 
| 
       91 
92 
     | 
    
         
             
              end
         
     | 
| 
         @@ -105,7 +106,7 @@ module RbbtMutiplartPayload 
     | 
|
| 
       105 
106 
     | 
    
         
             
                                      when File
         
     | 
| 
       106 
107 
     | 
    
         
             
                                        inputs[stream_input].path
         
     | 
| 
       107 
108 
     | 
    
         
             
                                      else
         
     | 
| 
       108 
     | 
    
         
            -
                                        'file'
         
     | 
| 
      
 109 
     | 
    
         
            +
                                        'file-rand-' + rand(10000000).to_s
         
     | 
| 
       109 
110 
     | 
    
         
             
                                      end
         
     | 
| 
       110 
111 
     | 
    
         
             
                end
         
     | 
| 
       111 
112 
     | 
    
         | 
| 
         @@ -120,14 +121,17 @@ module RbbtMutiplartPayload 
     | 
|
| 
       120 
121 
     | 
    
         
             
                  req.body = sout.read
         
     | 
| 
       121 
122 
     | 
    
         
             
                end
         
     | 
| 
       122 
123 
     | 
    
         | 
| 
       123 
     | 
    
         
            -
                Misc.open_pipe do |sin|
         
     | 
| 
      
 124 
     | 
    
         
            +
                Misc.open_pipe(true) do |sin|
         
     | 
| 
      
 125 
     | 
    
         
            +
                  sleep rand(10).to_f / 5
         
     | 
| 
       124 
126 
     | 
    
         
             
                  Net::HTTP.start(uri.hostname, uri.port) do |http|
         
     | 
| 
       125 
127 
     | 
    
         
             
                    http.request(req) do |res|
         
     | 
| 
      
 128 
     | 
    
         
            +
                      url_path = res["RBBT-STREAMING-JOB-URL"]
         
     | 
| 
       126 
129 
     | 
    
         
             
                      if Net::HTTPRedirection === res
         
     | 
| 
       127 
130 
     | 
    
         
             
                        sin.puts "LOCATION" if report_type
         
     | 
| 
       128 
131 
     | 
    
         
             
                        sin.write res["location"]
         
     | 
| 
       129 
     | 
    
         
            -
                      elsif stream_input
         
     | 
| 
       130 
     | 
    
         
            -
                         
     | 
| 
      
 132 
     | 
    
         
            +
                      elsif stream_input and url_path
         
     | 
| 
      
 133 
     | 
    
         
            +
                        url = URI::HTTP.build(:host => uri.hostname, :post => uri.port, :path => url_path)
         
     | 
| 
      
 134 
     | 
    
         
            +
                        sin.puts "STREAM: #{url.to_s}" if report_type
         
     | 
| 
       131 
135 
     | 
    
         
             
                        res.read_body do |c|
         
     | 
| 
       132 
136 
     | 
    
         
             
                          sin.write c
         
     | 
| 
       133 
137 
     | 
    
         
             
                        end
         
     | 
    
        data/lib/rbbt/util/misc/pipes.rb
    CHANGED
    
    | 
         @@ -77,6 +77,7 @@ module Misc 
     | 
|
| 
       77 
77 
     | 
    
         
             
                      Log.medium "Aborted open_pipe: #{$!.message}"
         
     | 
| 
       78 
78 
     | 
    
         
             
                    rescue Exception
         
     | 
| 
       79 
79 
     | 
    
         
             
                      Log.medium "Exception in open_pipe: #{$!.message}"
         
     | 
| 
      
 80 
     | 
    
         
            +
                      Log.exception $!
         
     | 
| 
       80 
81 
     | 
    
         
             
                      parent.raise $!
         
     | 
| 
       81 
82 
     | 
    
         
             
                      raise $!
         
     | 
| 
       82 
83 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -90,14 +91,12 @@ module Misc 
     | 
|
| 
       90 
91 
     | 
    
         
             
                stream_out1, stream_in1 = Misc.pipe
         
     | 
| 
       91 
92 
     | 
    
         
             
                stream_out2, stream_in2 = Misc.pipe
         
     | 
| 
       92 
93 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
                #if ConcurrentStream === stream 
         
     | 
| 
       94 
     | 
    
         
            -
                #  stream.annotate stream_out1
         
     | 
| 
       95 
     | 
    
         
            -
                #end
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
94 
     | 
    
         
             
                splitter_thread = Thread.new(Thread.current) do |parent|
         
     | 
| 
       98 
95 
     | 
    
         
             
                  begin
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
       99 
97 
     | 
    
         
             
                    skip1 = skip2 = false
         
     | 
| 
       100 
     | 
    
         
            -
                    while block = stream.read( 
     | 
| 
      
 98 
     | 
    
         
            +
                    while block = stream.read(1024)
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
       101 
100 
     | 
    
         
             
                      begin 
         
     | 
| 
       102 
101 
     | 
    
         
             
                        stream_in1.write block; 
         
     | 
| 
       103 
102 
     | 
    
         
             
                      rescue IOError
         
     | 
| 
         @@ -111,7 +110,9 @@ module Misc 
     | 
|
| 
       111 
110 
     | 
    
         
             
                        Log.medium("Tee stream 2 #{Misc.fingerprint stream} IOError: #{$!.message}");
         
     | 
| 
       112 
111 
     | 
    
         
             
                        skip2 = true
         
     | 
| 
       113 
112 
     | 
    
         
             
                      end unless skip2 
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
       114 
114 
     | 
    
         
             
                    end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
       115 
116 
     | 
    
         
             
                    stream_in1.close unless stream_in1.closed?
         
     | 
| 
       116 
117 
     | 
    
         
             
                    stream.join if stream.respond_to? :join
         
     | 
| 
       117 
118 
     | 
    
         
             
                    stream_in2.close unless stream_in2.closed?
         
     | 
| 
         @@ -585,7 +585,7 @@ module Workflow 
     | 
|
| 
       585 
585 
     | 
    
         
             
                dependencies.each do |dependency|
         
     | 
| 
       586 
586 
     | 
    
         
             
                  real_dependencies << case dependency
         
     | 
| 
       587 
587 
     | 
    
         
             
                  when Array
         
     | 
| 
       588 
     | 
    
         
            -
                    workflow,  
     | 
| 
      
 588 
     | 
    
         
            +
                    workflow, dep_task, options = dependency
         
     | 
| 
       589 
589 
     | 
    
         | 
| 
       590 
590 
     | 
    
         
             
                    _inputs = IndiferentHash.setup(inputs.dup)
         
     | 
| 
       591 
591 
     | 
    
         
             
                    options.each{|i,v|
         
     | 
| 
         @@ -595,9 +595,9 @@ module Workflow 
     | 
|
| 
       595 
595 
     | 
    
         
             
                        rec_dependency = all_d.select{|d| d.task_name.to_sym == v }.first
         
     | 
| 
       596 
596 
     | 
    
         | 
| 
       597 
597 
     | 
    
         
             
                        if rec_dependency.nil?
         
     | 
| 
       598 
     | 
    
         
            -
                          _inputs[i] = v
         
     | 
| 
      
 598 
     | 
    
         
            +
                          _inputs[i] = v unless _inputs.include? i
         
     | 
| 
       599 
599 
     | 
    
         
             
                        else
         
     | 
| 
       600 
     | 
    
         
            -
                          input_options = workflow.task_info( 
     | 
| 
      
 600 
     | 
    
         
            +
                          input_options = workflow.task_info(dep_task)[:input_options][i] || {}
         
     | 
| 
       601 
601 
     | 
    
         
             
                          if input_options[:stream]
         
     | 
| 
       602 
602 
     | 
    
         
             
                            #rec_dependency.run(true).grace unless rec_dependency.done? or rec_dependency.running?
         
     | 
| 
       603 
603 
     | 
    
         
             
                            _inputs[i] = rec_dependency
         
     | 
| 
         @@ -617,7 +617,7 @@ module Workflow 
     | 
|
| 
       617 
617 
     | 
    
         
             
                      end
         
     | 
| 
       618 
618 
     | 
    
         
             
                    } if options
         
     | 
| 
       619 
619 
     | 
    
         | 
| 
       620 
     | 
    
         
            -
                    res = workflow.job( 
     | 
| 
      
 620 
     | 
    
         
            +
                    res = workflow.job(dep_task, jobname, _inputs)
         
     | 
| 
       621 
621 
     | 
    
         
             
                    res
         
     | 
| 
       622 
622 
     | 
    
         
             
                  when Step
         
     | 
| 
       623 
623 
     | 
    
         
             
                    dependency
         
     | 
    
        data/lib/rbbt/workflow/step.rb
    CHANGED
    
    | 
         @@ -203,11 +203,8 @@ class Step 
     | 
|
| 
       203 
203 
     | 
    
         
             
                info_file = Step.info_file path
         
     | 
| 
       204 
204 
     | 
    
         
             
                pid_file = Step.pid_file path
         
     | 
| 
       205 
205 
     | 
    
         
             
                files_dir = Step.files_dir path
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
       206 
207 
     | 
    
         
             
                if Open.exists?(path) or Open.exists?(pid_file)
         
     | 
| 
       207 
     | 
    
         
            -
                  begin
         
     | 
| 
       208 
     | 
    
         
            -
                    self.abort if self.running?
         
     | 
| 
       209 
     | 
    
         
            -
                  rescue Exception
         
     | 
| 
       210 
     | 
    
         
            -
                  end
         
     | 
| 
       211 
208 
     | 
    
         | 
| 
       212 
209 
     | 
    
         
             
                  @result = nil
         
     | 
| 
       213 
210 
     | 
    
         
             
                  @pid = nil
         
     | 
| 
         @@ -224,6 +221,8 @@ class Step 
     | 
|
| 
       224 
221 
     | 
    
         
             
              end
         
     | 
| 
       225 
222 
     | 
    
         | 
| 
       226 
223 
     | 
    
         
             
              def clean
         
     | 
| 
      
 224 
     | 
    
         
            +
                Log.medium "Cleaning step: #{path}"
         
     | 
| 
      
 225 
     | 
    
         
            +
                abort if not done? and running?
         
     | 
| 
       227 
226 
     | 
    
         
             
                Step.clean(path)
         
     | 
| 
       228 
227 
     | 
    
         
             
                self
         
     | 
| 
       229 
228 
     | 
    
         
             
              end
         
     | 
| 
         @@ -250,7 +249,16 @@ class Step 
     | 
|
| 
       250 
249 
     | 
    
         
             
                rec_dependencies.each do |step| 
         
     | 
| 
       251 
250 
     | 
    
         
             
                  if Open.exists?(step.info_file) 
         
     | 
| 
       252 
251 
     | 
    
         
             
                    step.clean 
         
     | 
| 
       253 
     | 
    
         
            -
                   
     | 
| 
      
 252 
     | 
    
         
            +
                  end
         
     | 
| 
      
 253 
     | 
    
         
            +
                end
         
     | 
| 
      
 254 
     | 
    
         
            +
                self
         
     | 
| 
      
 255 
     | 
    
         
            +
              end
         
     | 
| 
      
 256 
     | 
    
         
            +
             
     | 
| 
      
 257 
     | 
    
         
            +
              def recursive_clean
         
     | 
| 
      
 258 
     | 
    
         
            +
                clean
         
     | 
| 
      
 259 
     | 
    
         
            +
                dependencies.each do |step| 
         
     | 
| 
      
 260 
     | 
    
         
            +
                  if Open.exists?(step.info_file) 
         
     | 
| 
      
 261 
     | 
    
         
            +
                    step.recursive_clean 
         
     | 
| 
       254 
262 
     | 
    
         
             
                  end
         
     | 
| 
       255 
263 
     | 
    
         
             
                end
         
     | 
| 
       256 
264 
     | 
    
         
             
                self
         
     | 
| 
         @@ -1,31 +1,55 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class Step
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
              attr_reader :stream, :dupped, :saved_stream
         
     | 
| 
      
 3 
     | 
    
         
            +
              attr_reader :stream, :dupped, :saved_stream, :inputs
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
              STREAM_CACHE = {}
         
     | 
| 
       6 
6 
     | 
    
         
             
              STREAM_CACHE_MUTEX = Mutex.new
         
     | 
| 
      
 7 
     | 
    
         
            +
              def self.purge_stream_cache
         
     | 
| 
      
 8 
     | 
    
         
            +
                Log.medium "Purging dup. stream cache"
         
     | 
| 
      
 9 
     | 
    
         
            +
                STREAM_CACHE_MUTEX.synchronize do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #STREAM_CACHE.collect{|k,s| 
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #  next
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #  Thread.new do
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #    Misc.consume_stream s
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #}
         
     | 
| 
      
 16 
     | 
    
         
            +
                  STREAM_CACHE.clear
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       7 
20 
     | 
    
         
             
              def self.dup_stream(stream)
         
     | 
| 
       8 
21 
     | 
    
         
             
                case stream
         
     | 
| 
       9 
     | 
    
         
            -
                when IO, File
         
     | 
| 
       10 
     | 
    
         
            -
                  return stream if stream.closed?
         
     | 
| 
      
 22 
     | 
    
         
            +
                when IO, File, Step
         
     | 
| 
      
 23 
     | 
    
         
            +
                  return stream if stream.respond_to?(:closed?) and stream.closed?
         
     | 
| 
      
 24 
     | 
    
         
            +
                  return stream if stream.respond_to?(:done?) and stream.done?
         
     | 
| 
       11 
25 
     | 
    
         | 
| 
       12 
26 
     | 
    
         
             
                  STREAM_CACHE_MUTEX.synchronize do
         
     | 
| 
       13 
     | 
    
         
            -
                     
     | 
| 
      
 27 
     | 
    
         
            +
                    stream_key = Misc.fingerprint(stream)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    current = STREAM_CACHE[stream_key]
         
     | 
| 
      
 29 
     | 
    
         
            +
                    case current
         
     | 
| 
       14 
30 
     | 
    
         
             
                    when nil
         
     | 
| 
       15 
     | 
    
         
            -
                      Log.medium "Not duplicating stream #{ 
     | 
| 
       16 
     | 
    
         
            -
                      STREAM_CACHE[ 
     | 
| 
      
 31 
     | 
    
         
            +
                      Log.medium "Not duplicating stream #{stream_key}"
         
     | 
| 
      
 32 
     | 
    
         
            +
                      STREAM_CACHE[stream_key] = stream
         
     | 
| 
       17 
33 
     | 
    
         
             
                    when File
         
     | 
| 
       18 
34 
     | 
    
         
             
                      if Open.exists? current.path 
         
     | 
| 
       19 
     | 
    
         
            -
                        Log.medium "Reopening file #{ 
     | 
| 
      
 35 
     | 
    
         
            +
                        Log.medium "Reopening file #{stream_key}"
         
     | 
| 
       20 
36 
     | 
    
         
             
                        Open.open(current.path)
         
     | 
| 
       21 
37 
     | 
    
         
             
                      else
         
     | 
| 
       22 
     | 
    
         
            -
                         
     | 
| 
       23 
     | 
    
         
            -
                        Misc. 
     | 
| 
      
 38 
     | 
    
         
            +
                        new = Misc.dup_stream(current)
         
     | 
| 
      
 39 
     | 
    
         
            +
                        Log.medium "Duplicating file #{stream_key} #{current.inspect} => #{Misc.fingerprint(new)}"
         
     | 
| 
      
 40 
     | 
    
         
            +
                        new
         
     | 
| 
       24 
41 
     | 
    
         
             
                      end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
                    when Step
         
     | 
| 
      
 43 
     | 
    
         
            +
                      job = current
         
     | 
| 
      
 44 
     | 
    
         
            +
                      current = job.result 
         
     | 
| 
      
 45 
     | 
    
         
            +
                      new = Misc.dup_stream(current)
         
     | 
| 
      
 46 
     | 
    
         
            +
                      job.result = current
         
     | 
| 
      
 47 
     | 
    
         
            +
                      Log.medium "Duplicating step #{stream_key} #{current.inspect} => #{Misc.fingerprint(new)}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                      new
         
     | 
| 
       26 
49 
     | 
    
         
             
                    else
         
     | 
| 
       27 
     | 
    
         
            -
                       
     | 
| 
       28 
     | 
    
         
            -
                      Misc. 
     | 
| 
      
 50 
     | 
    
         
            +
                      new = Misc.dup_stream(current)
         
     | 
| 
      
 51 
     | 
    
         
            +
                      Log.medium "Duplicating stream #{stream_key} #{ Misc.fingerprint(stream) } => #{Misc.fingerprint(new)}"
         
     | 
| 
      
 52 
     | 
    
         
            +
                      new
         
     | 
| 
       29 
53 
     | 
    
         
             
                    end
         
     | 
| 
       30 
54 
     | 
    
         
             
                  end
         
     | 
| 
       31 
55 
     | 
    
         
             
                when TSV::Dumper#, TSV::Parser
         
     | 
| 
         @@ -47,20 +71,86 @@ class Step 
     | 
|
| 
       47 
71 
     | 
    
         
             
                end
         
     | 
| 
       48 
72 
     | 
    
         
             
              end
         
     | 
| 
       49 
73 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
              def self. 
     | 
| 
       51 
     | 
    
         
            -
                return
         
     | 
| 
       52 
     | 
    
         
            -
                 
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
      
 74 
     | 
    
         
            +
              def self.prepare_for_execution(job)
         
     | 
| 
      
 75 
     | 
    
         
            +
                return if (job.done? and not job.dirty?) or 
         
     | 
| 
      
 76 
     | 
    
         
            +
                (job.streaming? and job.running?) or 
         
     | 
| 
      
 77 
     | 
    
         
            +
                (defined? WorkflowRESTClient and WorkflowRESTClient::RemoteStep === job and not (job.error? or job.aborted?))
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                job.clean if job.aborted? or (job.started? and not job.running? and not job.error?)
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                raise DependencyError, job if job.error?
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
              def execute_dependency(dependency)
         
     | 
| 
      
 85 
     | 
    
         
            +
                task_name = self.task_name
         
     | 
| 
      
 86 
     | 
    
         
            +
                begin
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  if dependency.done?
         
     | 
| 
      
 89 
     | 
    
         
            +
                    Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} done -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
      
 90 
     | 
    
         
            +
                    return
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  if not dependency.started?
         
     | 
| 
      
 94 
     | 
    
         
            +
                    Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} starting -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
      
 95 
     | 
    
         
            +
                    dependency.run(:stream)
         
     | 
| 
      
 96 
     | 
    
         
            +
                    raise TryAgain
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  dependency.grace
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                  if dependency.aborted?
         
     | 
| 
      
 102 
     | 
    
         
            +
                    Log.warn "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} aborted (clean and retry) -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
      
 103 
     | 
    
         
            +
                    dependency.clean
         
     | 
| 
      
 104 
     | 
    
         
            +
                    raise TryAgain
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                  if dependency.error?
         
     | 
| 
      
 108 
     | 
    
         
            +
                    Log.error "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} error -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
      
 109 
     | 
    
         
            +
                    raise DependencyError, [dependency.path, dependency.messages.last] * ": " if dependency.error?
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                  if dependency.streaming?
         
     | 
| 
      
 113 
     | 
    
         
            +
                    Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} streaming -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
      
 114 
     | 
    
         
            +
                    return
         
     | 
| 
      
 115 
     | 
    
         
            +
                  end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 118 
     | 
    
         
            +
                    Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} joining -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
      
 119 
     | 
    
         
            +
                    dependency.join
         
     | 
| 
      
 120 
     | 
    
         
            +
                    raise TryAgain unless dependency.done?
         
     | 
| 
      
 121 
     | 
    
         
            +
                    Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} joined -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
      
 122 
     | 
    
         
            +
                  rescue Aborted
         
     | 
| 
      
 123 
     | 
    
         
            +
                    raise TryAgain
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                rescue TryAgain
         
     | 
| 
      
 127 
     | 
    
         
            +
                  retry
         
     | 
| 
      
 128 
     | 
    
         
            +
                rescue Aborted
         
     | 
| 
      
 129 
     | 
    
         
            +
                  Log.error "Aborted dep. #{Log.color :red, dependency.task_name.to_s}"
         
     | 
| 
      
 130 
     | 
    
         
            +
                  raise $!
         
     | 
| 
      
 131 
     | 
    
         
            +
                rescue Interrupt
         
     | 
| 
      
 132 
     | 
    
         
            +
                  Log.error "Interrupted while in dep. #{Log.color :red, dependency.task_name.to_s}"
         
     | 
| 
      
 133 
     | 
    
         
            +
                  raise $!
         
     | 
| 
      
 134 
     | 
    
         
            +
                rescue Exception
         
     | 
| 
      
 135 
     | 
    
         
            +
                  Log.error "Exception in dep. #{ Log.color :red, dependency.task_name.to_s }"
         
     | 
| 
      
 136 
     | 
    
         
            +
                  Log.exception $!
         
     | 
| 
      
 137 
     | 
    
         
            +
                  raise $!
         
     | 
| 
      
 138 
     | 
    
         
            +
                end
         
     | 
| 
      
 139 
     | 
    
         
            +
              end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
              def dup_inputs
         
     | 
| 
      
 142 
     | 
    
         
            +
                return if @dupped or ENV["RBBT_NO_STREAM"] == 'true'
         
     | 
| 
      
 143 
     | 
    
         
            +
                Log.low "Dupping inputs for #{path}"
         
     | 
| 
      
 144 
     | 
    
         
            +
                dupped_inputs = @inputs.collect do |input|
         
     | 
| 
      
 145 
     | 
    
         
            +
                  Step.dup_stream input
         
     | 
| 
       59 
146 
     | 
    
         
             
                end
         
     | 
| 
      
 147 
     | 
    
         
            +
                @inputs.replace dupped_inputs
         
     | 
| 
      
 148 
     | 
    
         
            +
                @dupped = true
         
     | 
| 
       60 
149 
     | 
    
         
             
              end
         
     | 
| 
       61 
150 
     | 
    
         | 
| 
       62 
151 
     | 
    
         
             
              def get_stream
         
     | 
| 
       63 
152 
     | 
    
         
             
                @mutex.synchronize do
         
     | 
| 
      
 153 
     | 
    
         
            +
                  Log.low "Getting stream from #{path} #{!@saved_stream}"
         
     | 
| 
       64 
154 
     | 
    
         
             
                  begin
         
     | 
| 
       65 
155 
     | 
    
         
             
                    return nil if @saved_stream
         
     | 
| 
       66 
156 
     | 
    
         
             
                    if IO === @result 
         
     | 
| 
         @@ -72,13 +162,6 @@ class Step 
     | 
|
| 
       72 
162 
     | 
    
         
             
                end
         
     | 
| 
       73 
163 
     | 
    
         
             
              end
         
     | 
| 
       74 
164 
     | 
    
         | 
| 
       75 
     | 
    
         
            -
              def dup_inputs
         
     | 
| 
       76 
     | 
    
         
            -
                return if @dupped or ENV["RBBT_NO_STREAM"] == 'true'
         
     | 
| 
       77 
     | 
    
         
            -
                @inputs = @inputs.collect do |input|
         
     | 
| 
       78 
     | 
    
         
            -
                  Step.dup_stream input
         
     | 
| 
       79 
     | 
    
         
            -
                end
         
     | 
| 
       80 
     | 
    
         
            -
                @dupped = true
         
     | 
| 
       81 
     | 
    
         
            -
              end
         
     | 
| 
       82 
165 
     | 
    
         | 
| 
       83 
166 
     | 
    
         
             
              def _exec
         
     | 
| 
       84 
167 
     | 
    
         
             
                @exec = true if @exec.nil?
         
     | 
| 
         @@ -98,7 +181,7 @@ class Step 
     | 
|
| 
       98 
181 
     | 
    
         
             
              def checks
         
     | 
| 
       99 
182 
     | 
    
         
             
                rec_dependencies.collect{|dependency| (defined? WorkflowRESTClient and WorkflowRESTClient::RemoteStep === dependency) ? nil : dependency.path }.compact.uniq
         
     | 
| 
       100 
183 
     | 
    
         
             
              end
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
       102 
185 
     | 
    
         | 
| 
       103 
186 
     | 
    
         
             
              def kill_children
         
     | 
| 
       104 
187 
     | 
    
         
             
                begin
         
     | 
| 
         @@ -138,77 +221,39 @@ class Step 
     | 
|
| 
       138 
221 
     | 
    
         
             
                return if @seen.empty?
         
     | 
| 
       139 
222 
     | 
    
         | 
| 
       140 
223 
     | 
    
         
             
                log :dependencies, "#{Log.color :magenta, "Dependencies"} for step #{Log.color :yellow, task.name.to_s || ""}"
         
     | 
| 
       141 
     | 
    
         
            -
                dupping = []
         
     | 
| 
       142 
     | 
    
         
            -
                @seen.each do |dependency|
         
     | 
| 
       143 
     | 
    
         
            -
                  next if (dependency.done? and not dependency.dirty?) or 
         
     | 
| 
       144 
     | 
    
         
            -
                          (dependency.streaming? and dependency.running?) or 
         
     | 
| 
       145 
     | 
    
         
            -
                          (defined? WorkflowRESTClient and WorkflowRESTClient::RemoteStep === dependency and not (dependency.error? or dependency.aborted?))
         
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
                  dependency.clean if dependency.aborted? or (dependency.started? and not dependency.running? and not dependency.error?)
         
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
                  raise DependencyError, [dependency.short_path, dependency.messages.last] * ": " if dependency.error?
         
     | 
| 
       150 
224 
     | 
    
         | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
      
 225 
     | 
    
         
            +
                @seen.each do |dependency| 
         
     | 
| 
      
 226 
     | 
    
         
            +
                  Step.prepare_for_execution(dependency)
         
     | 
| 
       152 
227 
     | 
    
         
             
                end
         
     | 
| 
       153 
228 
     | 
    
         | 
| 
       154 
     | 
    
         
            -
                 
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
      
 229 
     | 
    
         
            +
                pre_deps = []
         
     | 
| 
      
 230 
     | 
    
         
            +
                last_deps = []
         
     | 
| 
       156 
231 
     | 
    
         
             
                @seen.each do |dependency| 
         
     | 
| 
       157 
     | 
    
         
            -
                   
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
                      Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} done -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
       163 
     | 
    
         
            -
                      next
         
     | 
| 
       164 
     | 
    
         
            -
                    end
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
                    if not dependency.started?
         
     | 
| 
       167 
     | 
    
         
            -
                      Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} starting -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
       168 
     | 
    
         
            -
                      dependency.run(:stream)
         
     | 
| 
       169 
     | 
    
         
            -
                      raise TryAgain
         
     | 
| 
       170 
     | 
    
         
            -
                    end
         
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
                    dependency.grace
         
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
                    if dependency.aborted?
         
     | 
| 
       175 
     | 
    
         
            -
                      Log.warn "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} aborted (clean and retry) -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
       176 
     | 
    
         
            -
                      dependency.clean
         
     | 
| 
       177 
     | 
    
         
            -
                      raise TryAgain
         
     | 
| 
      
 232 
     | 
    
         
            +
                  if dependencies.include? dependency
         
     | 
| 
      
 233 
     | 
    
         
            +
                    if dependency.inputs.flatten.select{|i| Step === i}.any?
         
     | 
| 
      
 234 
     | 
    
         
            +
                      last_deps << dependency
         
     | 
| 
      
 235 
     | 
    
         
            +
                    else
         
     | 
| 
      
 236 
     | 
    
         
            +
                      pre_deps << dependency
         
     | 
| 
       178 
237 
     | 
    
         
             
                    end
         
     | 
| 
       179 
238 
     | 
    
         | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
      
 239 
     | 
    
         
            +
                  else
         
     | 
| 
      
 240 
     | 
    
         
            +
                    pre_deps << dependency
         
     | 
| 
      
 241 
     | 
    
         
            +
                  end
         
     | 
| 
      
 242 
     | 
    
         
            +
                end
         
     | 
| 
       184 
243 
     | 
    
         | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
      
 244 
     | 
    
         
            +
                pre_deps.each do |dependency|
         
     | 
| 
      
 245 
     | 
    
         
            +
                  dependency.dup_inputs
         
     | 
| 
      
 246 
     | 
    
         
            +
                  execute_dependency(dependency)
         
     | 
| 
      
 247 
     | 
    
         
            +
                end
         
     | 
| 
       189 
248 
     | 
    
         | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
                      raise TryAgain unless dependency.done?
         
     | 
| 
       194 
     | 
    
         
            -
                      Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} joined -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
         
     | 
| 
       195 
     | 
    
         
            -
                    rescue Aborted
         
     | 
| 
       196 
     | 
    
         
            -
                      raise TryAgain
         
     | 
| 
       197 
     | 
    
         
            -
                    end
         
     | 
| 
      
 249 
     | 
    
         
            +
                last_deps.each do |dependency|
         
     | 
| 
      
 250 
     | 
    
         
            +
                  dependency.dup_inputs
         
     | 
| 
      
 251 
     | 
    
         
            +
                end
         
     | 
| 
       198 
252 
     | 
    
         | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
                  rescue Aborted
         
     | 
| 
       202 
     | 
    
         
            -
                    Log.error "Aborted dep. #{Log.color :red, dependency.task_name.to_s}"
         
     | 
| 
       203 
     | 
    
         
            -
                    raise $!
         
     | 
| 
       204 
     | 
    
         
            -
                  rescue Interrupt
         
     | 
| 
       205 
     | 
    
         
            -
                    Log.error "Interrupted while in dep. #{Log.color :red, dependency.task_name.to_s}"
         
     | 
| 
       206 
     | 
    
         
            -
                    raise $!
         
     | 
| 
       207 
     | 
    
         
            -
                  rescue Exception
         
     | 
| 
       208 
     | 
    
         
            -
                    Log.error "Exception in dep. #{ Log.color :red, dependency.task_name.to_s }"
         
     | 
| 
       209 
     | 
    
         
            -
                    raise $!
         
     | 
| 
       210 
     | 
    
         
            -
                  end
         
     | 
| 
      
 253 
     | 
    
         
            +
                last_deps.each do |dependency|
         
     | 
| 
      
 254 
     | 
    
         
            +
                  execute_dependency(dependency)
         
     | 
| 
       211 
255 
     | 
    
         
             
                end
         
     | 
| 
      
 256 
     | 
    
         
            +
             
     | 
| 
       212 
257 
     | 
    
         
             
              end
         
     | 
| 
       213 
258 
     | 
    
         | 
| 
       214 
259 
     | 
    
         
             
              def run(no_load = false)
         
     | 
| 
         @@ -243,6 +288,7 @@ class Step 
     | 
|
| 
       243 
288 
     | 
    
         
             
                        stop_dependencies
         
     | 
| 
       244 
289 
     | 
    
         
             
                        raise $!
         
     | 
| 
       245 
290 
     | 
    
         
             
                      end
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
       246 
292 
     | 
    
         
             
                      set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]}
         
     | 
| 
       247 
293 
     | 
    
         | 
| 
       248 
294 
     | 
    
         
             
                      set_info :inputs, Misc.remove_long_items(Misc.zip2hash(task.inputs, @inputs)) unless task.inputs.nil?
         
     | 
| 
         @@ -295,6 +341,7 @@ class Step 
     | 
|
| 
       295 
341 
     | 
    
         
             
                            Log.exception $!
         
     | 
| 
       296 
342 
     | 
    
         
             
                          ensure
         
     | 
| 
       297 
343 
     | 
    
         
             
                            join
         
     | 
| 
      
 344 
     | 
    
         
            +
                            Step.purge_stream_cache
         
     | 
| 
       298 
345 
     | 
    
         
             
                            FileUtils.rm pid_file if File.exists?(pid_file)
         
     | 
| 
       299 
346 
     | 
    
         
             
                          end
         
     | 
| 
       300 
347 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -312,6 +359,7 @@ class Step 
     | 
|
| 
       312 
359 
     | 
    
         
             
                        set_info :total_time_elapsed, (total_time_elapsed = done_time - issue_time)
         
     | 
| 
       313 
360 
     | 
    
         
             
                        set_info :time_elapsed, (time_elapsed = done_time - start_time)
         
     | 
| 
       314 
361 
     | 
    
         
             
                        log :done, "#{Log.color :magenta, "Completed"} step #{Log.color :yellow, task.name.to_s || ""} in #{time_elapsed.to_i}+#{(total_time_elapsed - time_elapsed).to_i} sec."
         
     | 
| 
      
 362 
     | 
    
         
            +
                        Step.purge_stream_cache
         
     | 
| 
       315 
363 
     | 
    
         
             
                        FileUtils.rm pid_file if File.exists?(pid_file)
         
     | 
| 
       316 
364 
     | 
    
         
             
                      end
         
     | 
| 
       317 
365 
     | 
    
         | 
| 
         @@ -322,6 +370,7 @@ class Step 
     | 
|
| 
       322 
370 
     | 
    
         
             
                      @result ||= result
         
     | 
| 
       323 
371 
     | 
    
         
             
                      self
         
     | 
| 
       324 
372 
     | 
    
         
             
                    else
         
     | 
| 
      
 373 
     | 
    
         
            +
                      Step.purge_stream_cache
         
     | 
| 
       325 
374 
     | 
    
         
             
                      @result = prepare_result result, @task.result_description
         
     | 
| 
       326 
375 
     | 
    
         
             
                    end
         
     | 
| 
       327 
376 
     | 
    
         
             
                  end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rbbt-util
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 5. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 5.20.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Miguel Vazquez
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2016-05- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2016-05-19 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: rake
         
     |