ffwd 0.1.7 → 0.2.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 +7 -0
 - data/lib/ffwd.rb +34 -10
 - data/lib/ffwd/core.rb +13 -11
 - data/lib/ffwd/core/emitter.rb +0 -2
 - data/lib/ffwd/core/interface.rb +5 -2
 - data/lib/ffwd/core/processor.rb +4 -5
 - data/lib/ffwd/debug/monitor_session.rb +3 -6
 - data/lib/ffwd/debug/tcp.rb +17 -12
 - data/lib/ffwd/handler.rb +1 -1
 - data/lib/ffwd/plugin.rb +20 -15
 - data/lib/ffwd/plugin/json.rb +12 -20
 - data/lib/ffwd/plugin/json/connection.rb +4 -2
 - data/lib/ffwd/plugin/log.rb +17 -2
 - data/lib/ffwd/plugin/log/writer.rb +4 -0
 - data/lib/ffwd/plugin_channel.rb +8 -8
 - data/lib/ffwd/processor.rb +11 -4
 - data/lib/ffwd/processor/count.rb +16 -6
 - data/lib/ffwd/processor/histogram.rb +26 -15
 - data/lib/ffwd/processor/rate.rb +16 -6
 - data/lib/ffwd/protocol/tcp.rb +47 -88
 - data/lib/ffwd/protocol/tcp/bind.rb +22 -10
 - data/lib/ffwd/protocol/tcp/connection.rb +23 -6
 - data/lib/ffwd/protocol/tcp/flushing_connect.rb +42 -25
 - data/lib/ffwd/protocol/tcp/plain_connect.rb +15 -3
 - data/lib/ffwd/protocol/udp.rb +42 -17
 - data/lib/ffwd/protocol/udp/bind.rb +21 -10
 - data/lib/ffwd/protocol/udp/connect.rb +22 -9
 - data/lib/ffwd/retrier.rb +4 -1
 - data/lib/ffwd/schema.rb +10 -3
 - data/lib/ffwd/statistics/collector.rb +31 -23
 - data/lib/ffwd/test/protocol.rb +42 -0
 - data/lib/ffwd/tunnel/tcp.rb +3 -1
 - data/lib/ffwd/utils.rb +7 -0
 - data/lib/ffwd/version.rb +1 -1
 - metadata +56 -68
 - data/lib/ffwd/circular_buffer.rb +0 -78
 - data/lib/ffwd/statistics.rb +0 -29
 - data/lib/ffwd/tunnel.rb +0 -27
 
| 
         @@ -13,19 +13,35 @@ 
     | 
|
| 
       13 
13 
     | 
    
         
             
            # License for the specific language governing permissions and limitations under
         
     | 
| 
       14 
14 
     | 
    
         
             
            # the License.
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
      
 16 
     | 
    
         
            +
            require_relative '../../utils'
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       16 
18 
     | 
    
         
             
            module FFWD::TCP
         
     | 
| 
       17 
19 
     | 
    
         
             
              class Connection
         
     | 
| 
       18 
20 
     | 
    
         
             
                INITIAL_TIMEOUT = 2
         
     | 
| 
       19 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
                # default flush period, if non-zero will cause the connection to be buffered.
         
     | 
| 
      
 23 
     | 
    
         
            +
                DEFAULT_FLUSH_PERIOD = 10
         
     | 
| 
      
 24 
     | 
    
         
            +
                # default amount of bytes that the outbound connection will allow in its
         
     | 
| 
      
 25 
     | 
    
         
            +
                # application-level buffer.
         
     | 
| 
      
 26 
     | 
    
         
            +
                DEFAULT_TCP_OUTBOUND_LIMIT = 2 ** 20
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       20 
28 
     | 
    
         
             
                attr_reader :log, :peer, :reporter_meta
         
     | 
| 
       21 
29 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                def  
     | 
| 
      
 30 
     | 
    
         
            +
                def self.prepare opts
         
     | 
| 
      
 31 
     | 
    
         
            +
                  opts[:flush_period] ||= DEFAULT_FLUSH_PERIOD
         
     | 
| 
      
 32 
     | 
    
         
            +
                  opts[:tcp_outbound_limit] ||= DEFAULT_TCP_OUTBOUND_LIMIT
         
     | 
| 
      
 33 
     | 
    
         
            +
                  opts[:ignored] = (opts[:ignored] || []).map{|v| Utils.check_ignored v}
         
     | 
| 
      
 34 
     | 
    
         
            +
                  opts
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def initialize log, host, port, handler, config
         
     | 
| 
       23 
38 
     | 
    
         
             
                  @log = log
         
     | 
| 
       24 
39 
     | 
    
         
             
                  @host = host
         
     | 
| 
       25 
40 
     | 
    
         
             
                  @port = port
         
     | 
| 
       26 
41 
     | 
    
         
             
                  @handler = handler
         
     | 
| 
       27 
     | 
    
         
            -
                  @ 
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
                  @config = config
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  @tcp_outbound_limit = config[:tcp_outbound_limit]
         
     | 
| 
       29 
45 
     | 
    
         | 
| 
       30 
46 
     | 
    
         
             
                  @peer = "#{host}:#{port}"
         
     | 
| 
       31 
47 
     | 
    
         
             
                  @closing = false
         
     | 
| 
         @@ -39,8 +55,9 @@ module FFWD::TCP 
     | 
|
| 
       39 
55 
     | 
    
         | 
| 
       40 
56 
     | 
    
         
             
                # Start attempting to connect.
         
     | 
| 
       41 
57 
     | 
    
         
             
                def connect
         
     | 
| 
       42 
     | 
    
         
            -
                   
     | 
| 
       43 
     | 
    
         
            -
                   
     | 
| 
      
 58 
     | 
    
         
            +
                  @c = EM.connect @host, @port, @handler, self, @config
         
     | 
| 
      
 59 
     | 
    
         
            +
                  log.info "Connect to tcp://#{@host}:#{@port}"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  log.info "  config: #{@config.inspect}"
         
     | 
| 
       44 
61 
     | 
    
         
             
                end
         
     | 
| 
       45 
62 
     | 
    
         | 
| 
       46 
63 
     | 
    
         
             
                # Explicitly disconnect and discard any reconnect attempts..
         
     | 
| 
         @@ -101,7 +118,7 @@ module FFWD::TCP 
     | 
|
| 
       101 
118 
     | 
    
         | 
| 
       102 
119 
     | 
    
         
             
                # Check if a connection is writable or not.
         
     | 
| 
       103 
120 
     | 
    
         
             
                def writable?
         
     | 
| 
       104 
     | 
    
         
            -
                  not @c.nil? and @open and @c.get_outbound_data_size < @ 
     | 
| 
      
 121 
     | 
    
         
            +
                  not @c.nil? and @open and @c.get_outbound_data_size < @tcp_outbound_limit
         
     | 
| 
       105 
122 
     | 
    
         
             
                end
         
     | 
| 
       106 
123 
     | 
    
         
             
              end
         
     | 
| 
       107 
124 
     | 
    
         
             
            end
         
     | 
| 
         @@ -21,6 +21,14 @@ module FFWD::TCP 
     | 
|
| 
       21 
21 
     | 
    
         
             
              class FlushingConnect
         
     | 
| 
       22 
22 
     | 
    
         
             
                include FFWD::Reporter
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
                # percent of maximum events/metrics which will cause a flush.
         
     | 
| 
      
 25 
     | 
    
         
            +
                DEFAULT_FORCED_FLUSH_FACTOR = 0.8
         
     | 
| 
      
 26 
     | 
    
         
            +
                # defaults for buffered connections.
         
     | 
| 
      
 27 
     | 
    
         
            +
                # maximum amount of events to buffer up.
         
     | 
| 
      
 28 
     | 
    
         
            +
                DEFAULT_EVENT_LIMIT = 1000
         
     | 
| 
      
 29 
     | 
    
         
            +
                # maximum amount of metrics to buffer up.
         
     | 
| 
      
 30 
     | 
    
         
            +
                DEFAULT_METRIC_LIMIT = 10000
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
       24 
32 
     | 
    
         
             
                setup_reporter :keys => [
         
     | 
| 
       25 
33 
     | 
    
         
             
                  :dropped_events, :dropped_metrics,
         
     | 
| 
       26 
34 
     | 
    
         
             
                  :sent_events, :sent_metrics,
         
     | 
| 
         @@ -34,49 +42,55 @@ module FFWD::TCP 
     | 
|
| 
       34 
42 
     | 
    
         
             
                  @c.reporter_meta
         
     | 
| 
       35 
43 
     | 
    
         
             
                end
         
     | 
| 
       36 
44 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                def  
     | 
| 
       38 
     | 
    
         
            -
                   
     | 
| 
       39 
     | 
    
         
            -
                   
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
                def self.prepare opts
         
     | 
| 
      
 46 
     | 
    
         
            +
                  opts[:forced_flush_factor] ||= DEFAULT_FORCED_FLUSH_FACTOR
         
     | 
| 
      
 47 
     | 
    
         
            +
                  opts[:event_limit] ||= DEFAULT_EVENT_LIMIT
         
     | 
| 
      
 48 
     | 
    
         
            +
                  opts[:metric_limit] ||= DEFAULT_METRIC_LIMIT
         
     | 
| 
      
 49 
     | 
    
         
            +
                  opts
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                def initialize(core, log, connection, config)
         
     | 
| 
       41 
53 
     | 
    
         
             
                  @log = log
         
     | 
| 
       42 
54 
     | 
    
         
             
                  @c = connection
         
     | 
| 
       43 
55 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
                   
     | 
| 
       45 
     | 
    
         
            -
                   
     | 
| 
       46 
     | 
    
         
            -
                   
     | 
| 
       47 
     | 
    
         
            -
                   
     | 
| 
       48 
     | 
    
         
            -
                   
     | 
| 
      
 56 
     | 
    
         
            +
                  flush_period = config[:flush_period]
         
     | 
| 
      
 57 
     | 
    
         
            +
                  ignored = config[:ignored]
         
     | 
| 
      
 58 
     | 
    
         
            +
                  forced_flush_factor = config[:forced_flush_factor]
         
     | 
| 
      
 59 
     | 
    
         
            +
                  event_limit = config[:event_limit]
         
     | 
| 
      
 60 
     | 
    
         
            +
                  metric_limit = config[:metric_limit]
         
     | 
| 
       49 
61 
     | 
    
         | 
| 
       50 
62 
     | 
    
         
             
                  @event_buffer = []
         
     | 
| 
       51 
63 
     | 
    
         
             
                  @metric_buffer = []
         
     | 
| 
       52 
64 
     | 
    
         
             
                  @timer = nil
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                  subs = []
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @subs = []
         
     | 
| 
       55 
66 
     | 
    
         | 
| 
       56 
67 
     | 
    
         
             
                  core.starting do
         
     | 
| 
       57 
     | 
    
         
            -
                     
     | 
| 
       58 
     | 
    
         
            -
                    @timer = EM::PeriodicTimer.new(@flush_period){flush!}
         
     | 
| 
      
 68 
     | 
    
         
            +
                    @c.connect
         
     | 
| 
       59 
69 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                     
     | 
| 
       61 
     | 
    
         
            -
                      @event_buffer, @event_limit, @event_flush_limit, :dropped_events)
         
     | 
| 
       62 
     | 
    
         
            -
                    metric_consumer = setup_consumer(
         
     | 
| 
       63 
     | 
    
         
            -
                      @metric_buffer, @metric_limit, @metric_flush_limit, :dropped_metrics)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    @timer = EM::PeriodicTimer.new(flush_period){flush!}
         
     | 
| 
       64 
71 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
                     
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
      
 72 
     | 
    
         
            +
                    unless ignored.include? :events
         
     | 
| 
      
 73 
     | 
    
         
            +
                      event_consumer = setup_consumer(
         
     | 
| 
      
 74 
     | 
    
         
            +
                        @event_buffer, forced_flush_factor, event_limit, :dropped_events)
         
     | 
| 
      
 75 
     | 
    
         
            +
                      @subs << core.output.event_subscribe(&event_consumer)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    end
         
     | 
| 
       67 
77 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
                     
     | 
| 
      
 78 
     | 
    
         
            +
                    unless ignored.include? :metrics
         
     | 
| 
      
 79 
     | 
    
         
            +
                      metric_consumer = setup_consumer(
         
     | 
| 
      
 80 
     | 
    
         
            +
                        @metric_buffer, forced_flush_factor, metric_limit, :dropped_metrics)
         
     | 
| 
      
 81 
     | 
    
         
            +
                      @subs << core.output.metric_subscribe(&metric_consumer)
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
       69 
83 
     | 
    
         
             
                  end
         
     | 
| 
       70 
84 
     | 
    
         | 
| 
       71 
85 
     | 
    
         
             
                  core.stopping do
         
     | 
| 
       72 
     | 
    
         
            -
                     
     | 
| 
      
 86 
     | 
    
         
            +
                    @c.disconnect
         
     | 
| 
       73 
87 
     | 
    
         | 
| 
       74 
88 
     | 
    
         
             
                    if @timer
         
     | 
| 
       75 
89 
     | 
    
         
             
                      @timer.cancel
         
     | 
| 
       76 
90 
     | 
    
         
             
                      @timer = nil
         
     | 
| 
       77 
91 
     | 
    
         
             
                    end
         
     | 
| 
       78 
92 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
                    @ 
     | 
| 
      
 93 
     | 
    
         
            +
                    @subs.each(&:unsubscribe).clear
         
     | 
| 
       80 
94 
     | 
    
         
             
                  end
         
     | 
| 
       81 
95 
     | 
    
         
             
                end
         
     | 
| 
       82 
96 
     | 
    
         | 
| 
         @@ -116,16 +130,19 @@ module FFWD::TCP 
     | 
|
| 
       116 
130 
     | 
    
         | 
| 
       117 
131 
     | 
    
         
             
                private
         
     | 
| 
       118 
132 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
                def setup_consumer buffer,  
     | 
| 
      
 133 
     | 
    
         
            +
                def setup_consumer buffer, drop, flush, statistics_key
         
     | 
| 
      
 134 
     | 
    
         
            +
                  drop_limit = drop
         
     | 
| 
      
 135 
     | 
    
         
            +
                  forced_flush_limit = drop * flush
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
       120 
137 
     | 
    
         
             
                  proc do |e|
         
     | 
| 
       121 
     | 
    
         
            -
                    if buffer.size >=  
     | 
| 
      
 138 
     | 
    
         
            +
                    if buffer.size >= drop_limit
         
     | 
| 
       122 
139 
     | 
    
         
             
                      increment statistics_key, 1
         
     | 
| 
       123 
140 
     | 
    
         
             
                      next
         
     | 
| 
       124 
141 
     | 
    
         
             
                    end
         
     | 
| 
       125 
142 
     | 
    
         | 
| 
       126 
143 
     | 
    
         
             
                    buffer << e
         
     | 
| 
       127 
144 
     | 
    
         | 
| 
       128 
     | 
    
         
            -
                    if buffer.size >=  
     | 
| 
      
 145 
     | 
    
         
            +
                    if buffer.size >= forced_flush_limit
         
     | 
| 
       129 
146 
     | 
    
         
             
                      increment :forced_flush, 1
         
     | 
| 
       130 
147 
     | 
    
         
             
                      flush!
         
     | 
| 
       131 
148 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -19,6 +19,10 @@ module FFWD::TCP 
     | 
|
| 
       19 
19 
     | 
    
         
             
              class PlainConnect
         
     | 
| 
       20 
20 
     | 
    
         
             
                include FFWD::Reporter
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
                def self.prepare opts
         
     | 
| 
      
 23 
     | 
    
         
            +
                  opts
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       22 
26 
     | 
    
         
             
                setup_reporter :keys => [
         
     | 
| 
       23 
27 
     | 
    
         
             
                  :dropped_events, :dropped_metrics,
         
     | 
| 
       24 
28 
     | 
    
         
             
                  :sent_events, :sent_metrics,
         
     | 
| 
         @@ -33,16 +37,24 @@ module FFWD::TCP 
     | 
|
| 
       33 
37 
     | 
    
         | 
| 
       34 
38 
     | 
    
         
             
                INITIAL_TIMEOUT = 2
         
     | 
| 
       35 
39 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                def initialize core, log, connection
         
     | 
| 
      
 40 
     | 
    
         
            +
                def initialize core, log, connection, config
         
     | 
| 
       37 
41 
     | 
    
         
             
                  @log = log
         
     | 
| 
       38 
42 
     | 
    
         
             
                  @c = connection
         
     | 
| 
       39 
43 
     | 
    
         | 
| 
      
 44 
     | 
    
         
            +
                  ignored = config[:ignored]
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       40 
46 
     | 
    
         
             
                  subs = []
         
     | 
| 
       41 
47 
     | 
    
         | 
| 
       42 
48 
     | 
    
         
             
                  core.starting do
         
     | 
| 
       43 
49 
     | 
    
         
             
                    @c.connect
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                     
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    unless ignored.include? :events
         
     | 
| 
      
 52 
     | 
    
         
            +
                      subs << core.output.event_subscribe{|e| handle_event e}
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                    unless ignored.include? :metrics
         
     | 
| 
      
 56 
     | 
    
         
            +
                      subs << core.output.metric_subscribe{|e| handle_metric e}
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
       46 
58 
     | 
    
         
             
                  end
         
     | 
| 
       47 
59 
     | 
    
         | 
| 
       48 
60 
     | 
    
         
             
                  core.stopping do
         
     | 
    
        data/lib/ffwd/protocol/udp.rb
    CHANGED
    
    | 
         @@ -13,36 +13,61 @@ 
     | 
|
| 
       13 
13 
     | 
    
         
             
            # License for the specific language governing permissions and limitations under
         
     | 
| 
       14 
14 
     | 
    
         
             
            # the License.
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
            require_relative '../utils'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require_relative '../tunnel/udp'
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
       18 
19 
     | 
    
         
             
            require_relative 'udp/connect'
         
     | 
| 
       19 
20 
     | 
    
         
             
            require_relative 'udp/bind'
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
            require_relative '../tunnel'
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
22 
     | 
    
         
             
            module FFWD::UDP
         
     | 
| 
       24 
23 
     | 
    
         
             
              def self.family
         
     | 
| 
       25 
24 
     | 
    
         
             
                :udp
         
     | 
| 
       26 
25 
     | 
    
         
             
              end
         
     | 
| 
       27 
26 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
               
     | 
| 
      
 27 
     | 
    
         
            +
              class SetupOutput
         
     | 
| 
      
 28 
     | 
    
         
            +
                attr_reader :config
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def initialize config, log, handler
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @config = config
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @log = log
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @handler = handler
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @config = Connect.prepare Hash[@config]
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def connect core
         
     | 
| 
      
 38 
     | 
    
         
            +
                  raise "Missing required key :host" if (host = @config[:host]).nil?
         
     | 
| 
      
 39 
     | 
    
         
            +
                  raise "Missing required key :port" if (port = @config[:port]).nil?
         
     | 
| 
      
 40 
     | 
    
         
            +
                  Connect.new core, @log, host, port, @handler, @config
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
       29 
43 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
              def self.connect  
     | 
| 
       31 
     | 
    
         
            -
                 
     | 
| 
       32 
     | 
    
         
            -
                raise "Missing required key :port" if (port = opts[:port]).nil?
         
     | 
| 
       33 
     | 
    
         
            -
                Connect.new core, log, host, port, handler
         
     | 
| 
      
 44 
     | 
    
         
            +
              def self.connect config, log, handler
         
     | 
| 
      
 45 
     | 
    
         
            +
                SetupOutput.new config, log, handler
         
     | 
| 
       34 
46 
     | 
    
         
             
              end
         
     | 
| 
       35 
47 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
               
     | 
| 
       37 
     | 
    
         
            -
                 
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                 
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
              class SetupInput
         
     | 
| 
      
 49 
     | 
    
         
            +
                attr_reader :config
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def initialize config, log, connection
         
     | 
| 
      
 52 
     | 
    
         
            +
                  @config = config
         
     | 
| 
      
 53 
     | 
    
         
            +
                  @log = log
         
     | 
| 
      
 54 
     | 
    
         
            +
                  @connection = connection
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                def bind core
         
     | 
| 
      
 58 
     | 
    
         
            +
                  raise "Missing required key :host" if (host = @config[:host]).nil?
         
     | 
| 
      
 59 
     | 
    
         
            +
                  raise "Missing required key :port" if (port = @config[:port]).nil?
         
     | 
| 
      
 60 
     | 
    
         
            +
                  @config = Bind.prepare Hash[@config]
         
     | 
| 
      
 61 
     | 
    
         
            +
                  Bind.new core, @log, host, port, @connection, @config
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                def tunnel core, plugin
         
     | 
| 
      
 65 
     | 
    
         
            +
                  raise "Missing required key :port" if (port = @config[:port]).nil?
         
     | 
| 
      
 66 
     | 
    
         
            +
                  FFWD::Tunnel::UDP.new port, core, plugin, @log, @connection, @config
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
       41 
68 
     | 
    
         
             
              end
         
     | 
| 
       42 
69 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
              def self. 
     | 
| 
       44 
     | 
    
         
            -
                 
     | 
| 
       45 
     | 
    
         
            -
                FFWD.tunnel self.family, port, core, plugin, log, connection, args
         
     | 
| 
      
 70 
     | 
    
         
            +
              def self.bind config, log, connection
         
     | 
| 
      
 71 
     | 
    
         
            +
                SetupInput.new config, log, connection
         
     | 
| 
       46 
72 
     | 
    
         
             
              end
         
     | 
| 
       47 
73 
     | 
    
         
             
            end
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
         @@ -22,42 +22,53 @@ module FFWD::UDP 
     | 
|
| 
       22 
22 
     | 
    
         
             
              class Bind
         
     | 
| 
       23 
23 
     | 
    
         
             
                include FFWD::Reporter
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
      
 25 
     | 
    
         
            +
                DEFAULT_REBIND_TIMEOUT = 10
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def self.prepare opts
         
     | 
| 
      
 28 
     | 
    
         
            +
                  opts[:rebind_timeout] ||= DEFAULT_REBIND_TIMEOUT
         
     | 
| 
      
 29 
     | 
    
         
            +
                  opts
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
       25 
32 
     | 
    
         
             
                setup_reporter :keys => [
         
     | 
| 
       26 
33 
     | 
    
         
             
                  :received_events, :received_metrics,
         
     | 
| 
       27 
34 
     | 
    
         
             
                  :failed_events, :failed_metrics
         
     | 
| 
       28 
35 
     | 
    
         
             
                ]
         
     | 
| 
       29 
36 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                attr_reader :reporter_meta
         
     | 
| 
      
 37 
     | 
    
         
            +
                attr_reader :reporter_meta, :log, :config
         
     | 
| 
       31 
38 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                def initialize core, log, host, port, connection,  
     | 
| 
      
 39 
     | 
    
         
            +
                def initialize core, log, host, port, connection, config
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @log = log
         
     | 
| 
       33 
41 
     | 
    
         
             
                  @peer = "#{host}:#{port}"
         
     | 
| 
       34 
42 
     | 
    
         
             
                  @reporter_meta = {
         
     | 
| 
       35 
43 
     | 
    
         
             
                    :type => connection.plugin_type,
         
     | 
| 
       36 
44 
     | 
    
         
             
                    :listen => @peer, :family => 'udp'
         
     | 
| 
       37 
45 
     | 
    
         
             
                  }
         
     | 
| 
       38 
46 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                   
     | 
| 
      
 47 
     | 
    
         
            +
                  rebind_timeout = config[:rebind_timeout]
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  @socket = nil
         
     | 
| 
       40 
50 
     | 
    
         | 
| 
       41 
51 
     | 
    
         
             
                  info = "udp://#{@peer}"
         
     | 
| 
       42 
52 
     | 
    
         | 
| 
       43 
53 
     | 
    
         
             
                  r = FFWD.retry :timeout => rebind_timeout do |a|
         
     | 
| 
       44 
     | 
    
         
            -
                    @ 
     | 
| 
      
 54 
     | 
    
         
            +
                    @socket = EM.open_datagram_socket host, port, connection, self, core, config
         
     | 
| 
       45 
55 
     | 
    
         
             
                    log.info "Bind on #{info} (attempt #{a})"
         
     | 
| 
      
 56 
     | 
    
         
            +
                    log.info "  config: #{config.inspect}"
         
     | 
| 
       46 
57 
     | 
    
         
             
                  end
         
     | 
| 
       47 
58 
     | 
    
         | 
| 
       48 
59 
     | 
    
         
             
                  r.error do |a, t, e|
         
     | 
| 
       49 
     | 
    
         
            -
                    log. 
     | 
| 
      
 60 
     | 
    
         
            +
                    log.warning "Bind on #{info} failed, retry ##{a} in #{t}s: #{e}"
         
     | 
| 
       50 
61 
     | 
    
         
             
                  end
         
     | 
| 
       51 
62 
     | 
    
         | 
| 
       52 
63 
     | 
    
         
             
                  r.depend_on core
         
     | 
| 
       53 
64 
     | 
    
         | 
| 
       54 
65 
     | 
    
         
             
                  core.stopping do
         
     | 
| 
       55 
     | 
    
         
            -
                     
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                      @sig.unbind
         
     | 
| 
       59 
     | 
    
         
            -
                      @sig = nil
         
     | 
| 
      
 66 
     | 
    
         
            +
                    if @socket
         
     | 
| 
      
 67 
     | 
    
         
            +
                      @socket.unbind
         
     | 
| 
      
 68 
     | 
    
         
            +
                      @socket = nil
         
     | 
| 
       60 
69 
     | 
    
         
             
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    log.info "Unbound #{info}"
         
     | 
| 
       61 
72 
     | 
    
         
             
                  end
         
     | 
| 
       62 
73 
     | 
    
         
             
                end
         
     | 
| 
       63 
74 
     | 
    
         
             
              end
         
     | 
| 
         @@ -22,19 +22,26 @@ module FFWD::UDP 
     | 
|
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
                RESOLVE_TIMEOUT = 10
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                 
     | 
| 
      
 25 
     | 
    
         
            +
                def self.prepare config
         
     | 
| 
      
 26 
     | 
    
         
            +
                  config[:ignored] = (config[:ignored] || []).map{|v| Utils.check_ignored v}
         
     | 
| 
      
 27 
     | 
    
         
            +
                  config
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                attr_reader :reporter_meta, :log, :config
         
     | 
| 
       26 
31 
     | 
    
         | 
| 
       27 
32 
     | 
    
         
             
                setup_reporter :keys => [
         
     | 
| 
       28 
33 
     | 
    
         
             
                  :dropped_events, :dropped_metrics,
         
     | 
| 
       29 
34 
     | 
    
         
             
                  :sent_events, :sent_metrics
         
     | 
| 
       30 
35 
     | 
    
         
             
                ]
         
     | 
| 
       31 
36 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                def initialize core, log, host, port, handler
         
     | 
| 
      
 37 
     | 
    
         
            +
                def initialize core, log, host, port, handler, config
         
     | 
| 
       33 
38 
     | 
    
         
             
                  @log = log
         
     | 
| 
       34 
39 
     | 
    
         
             
                  @host = host
         
     | 
| 
       35 
40 
     | 
    
         
             
                  @port = port
         
     | 
| 
       36 
41 
     | 
    
         
             
                  @handler = handler
         
     | 
| 
       37 
42 
     | 
    
         | 
| 
      
 43 
     | 
    
         
            +
                  ignored = config[:ignored]
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
       38 
45 
     | 
    
         
             
                  @bind_host = "0.0.0.0"
         
     | 
| 
       39 
46 
     | 
    
         
             
                  @host_ip = nil
         
     | 
| 
       40 
47 
     | 
    
         
             
                  @c = nil
         
     | 
| 
         @@ -45,7 +52,7 @@ module FFWD::UDP 
     | 
|
| 
       45 
52 
     | 
    
         | 
| 
       46 
53 
     | 
    
         
             
                  info = "udp://#{@peer}"
         
     | 
| 
       47 
54 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                  subs = []
         
     | 
| 
      
 55 
     | 
    
         
            +
                  @subs = []
         
     | 
| 
       49 
56 
     | 
    
         | 
| 
       50 
57 
     | 
    
         
             
                  r = FFWD.retry :timeout => RESOLVE_TIMEOUT do |a|
         
     | 
| 
       51 
58 
     | 
    
         
             
                    unless @host_ip
         
     | 
| 
         @@ -53,16 +60,22 @@ module FFWD::UDP 
     | 
|
| 
       53 
60 
     | 
    
         
             
                      raise "Could not resolve: #{@host}" if @host_ip.nil?
         
     | 
| 
       54 
61 
     | 
    
         
             
                    end
         
     | 
| 
       55 
62 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                    @c = EM.open_datagram_socket 
     | 
| 
      
 63 
     | 
    
         
            +
                    @c = EM.open_datagram_socket @bind_host, nil, @handler, self, config
         
     | 
| 
       57 
64 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
                     
     | 
| 
      
 65 
     | 
    
         
            +
                    unless ignored.include? :events
         
     | 
| 
      
 66 
     | 
    
         
            +
                      @subs << core.output.event_subscribe{|e| handle_event e}
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    unless ignored.include? :metrics
         
     | 
| 
      
 70 
     | 
    
         
            +
                      @subs << core.output.metric_subscribe{|m| handle_metric m}
         
     | 
| 
      
 71 
     | 
    
         
            +
                    end
         
     | 
| 
       59 
72 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                     
     | 
| 
       61 
     | 
    
         
            -
                     
     | 
| 
      
 73 
     | 
    
         
            +
                    log.info "Connect to #{info} (attempt #{a})"
         
     | 
| 
      
 74 
     | 
    
         
            +
                    log.info "  config: #{config.inspect}"
         
     | 
| 
       62 
75 
     | 
    
         
             
                  end
         
     | 
| 
       63 
76 
     | 
    
         | 
| 
       64 
77 
     | 
    
         
             
                  r.error do |a, t, e|
         
     | 
| 
       65 
     | 
    
         
            -
                    log. 
     | 
| 
      
 78 
     | 
    
         
            +
                    log.warning "Connect to #{info} failed, retry ##{a} in #{t}s: #{e}"
         
     | 
| 
       66 
79 
     | 
    
         
             
                  end
         
     | 
| 
       67 
80 
     | 
    
         | 
| 
       68 
81 
     | 
    
         
             
                  r.depend_on core
         
     | 
| 
         @@ -73,7 +86,7 @@ module FFWD::UDP 
     | 
|
| 
       73 
86 
     | 
    
         
             
                      @c = nil
         
     | 
| 
       74 
87 
     | 
    
         
             
                    end
         
     | 
| 
       75 
88 
     | 
    
         | 
| 
       76 
     | 
    
         
            -
                    subs.each(&:unsubscribe).clear
         
     | 
| 
      
 89 
     | 
    
         
            +
                    @subs.each(&:unsubscribe).clear
         
     | 
| 
       77 
90 
     | 
    
         
             
                  end
         
     | 
| 
       78 
91 
     | 
    
         
             
                end
         
     | 
| 
       79 
92 
     | 
    
         | 
    
        data/lib/ffwd/retrier.rb
    CHANGED
    
    | 
         @@ -22,10 +22,13 @@ module FFWD 
     | 
|
| 
       22 
22 
     | 
    
         
             
              class Retrier
         
     | 
| 
       23 
23 
     | 
    
         
             
                include FFWD::Lifecycle
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
      
 25 
     | 
    
         
            +
                MAX_FACTOR = 7
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
       25 
27 
     | 
    
         
             
                def initialize timeout, &block
         
     | 
| 
       26 
28 
     | 
    
         
             
                  @block = block
         
     | 
| 
       27 
29 
     | 
    
         
             
                  @timer = nil
         
     | 
| 
       28 
30 
     | 
    
         
             
                  @timeout = timeout
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @max_timeout = timeout * 2**MAX_FACTOR
         
     | 
| 
       29 
32 
     | 
    
         
             
                  @current_timeout = @timeout
         
     | 
| 
       30 
33 
     | 
    
         
             
                  @attempt = 0
         
     | 
| 
       31 
34 
     | 
    
         
             
                  @error_callbacks = []
         
     | 
| 
         @@ -56,7 +59,7 @@ module FFWD 
     | 
|
| 
       56 
59 
     | 
    
         
             
                  end
         
     | 
| 
       57 
60 
     | 
    
         | 
| 
       58 
61 
     | 
    
         
             
                  @timer = EM::Timer.new(@current_timeout) do
         
     | 
| 
       59 
     | 
    
         
            -
                    @current_timeout *= 2
         
     | 
| 
      
 62 
     | 
    
         
            +
                    @current_timeout *= 2 unless @current_timeout >= @max_timeout
         
     | 
| 
       60 
63 
     | 
    
         
             
                    @timer = nil
         
     | 
| 
       61 
64 
     | 
    
         
             
                    try_block
         
     | 
| 
       62 
65 
     | 
    
         
             
                  end
         
     |