Class Tap::Joins::Gate
In: lib/tap/joins/gate.rb
Parent: Join

Similar to a synchronized merge, but collects all results regardless of where they come from. Gates enque themselves when called as a join, and won‘t let results pass until they get run as a task.

  % tap load a -- load b - inspect - gate 0,1 2
  ["a", "b"]

Gates are useful in conjunction with iteration where a single task may feed multiple results to a single join; in this case a sync merge doesn‘t produce the desired behavior of collecting the results.

  % tap load/yaml "[1, 2, 3]" -:i inspect -:.gate inspect
  1
  2
  3
  [1, 2, 3]

  % tap load/yaml "[1, 2, 3]" -:i inspect -:.sync inspect
  1
  [1]
  2
  [2]
  3
  [3]

When a limit is specified, the gate will collect results up to the limit and then pass the results. Any leftover results are still passed at the end.

  % tap load/yaml "[1, 2, 3]" -:i inspect - inspect - gate 1 2 --limit 2
  1
  2
  [1, 2]
  3
  [3]

Methods

call   new  

Attributes

results  [R]  An array of results collected thusfar.

Configurations

limit  [RW]  Pass results after limit (nil)

Public Class methods

[Source]

    # File lib/tap/joins/gate.rb, line 49
49:       def initialize(config={}, app=Tap::App.current)
50:         super
51:         @results = nil
52:       end

Public Instance methods

[Source]

    # File lib/tap/joins/gate.rb, line 54
54:       def call(result)
55:         if @results
56:           # Results are set, so self is already enqued and collecting
57:           # results.  If the input is the collection, then it's time
58:           # to execute the results and reset.  Otherwise, just
59:           # collect the input and wait.
60:           
61:           if result == @results
62:             @results = nil
63:             super(result)
64:           else
65:             @results << result
66:             
67:             if limit && @results.length >= limit
68:               super(@results.dup)
69:               @results.clear
70:             end
71:           end
72:           
73:         else
74:           # No results are set, so this is a first call and self is
75:           # not enqued.  Setup the collection.
76:           
77:           @results = [result]
78:           app.enq(self, @results)
79:         end
80:         
81:         self
82:       end

[Validate]