fluq 0.7.5 → 0.8.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/.gitignore +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +12 -1
- data/Gemfile.lock +44 -8
- data/README.md +24 -6
- data/Rakefile +8 -1
- data/benchmark/socket.rb +13 -25
- data/examples/config/multi.rb +52 -0
- data/examples/config/simple.rb +15 -0
- data/fluq.gemspec +3 -3
- data/lib/fluq.rb +22 -16
- data/lib/fluq/cli.rb +3 -12
- data/lib/fluq/dsl.rb +2 -45
- data/lib/fluq/dsl/base.rb +11 -0
- data/lib/fluq/dsl/feed.rb +24 -0
- data/lib/fluq/dsl/root.rb +35 -0
- data/lib/fluq/event.rb +9 -28
- data/lib/fluq/feed.rb +40 -5
- data/lib/fluq/format.rb +6 -0
- data/lib/fluq/format/base.rb +42 -0
- data/lib/fluq/format/json.rb +17 -0
- data/lib/fluq/format/lines.rb +27 -0
- data/lib/fluq/format/msgpack.rb +28 -0
- data/lib/fluq/format/tsv.rb +19 -0
- data/lib/fluq/handler.rb +1 -1
- data/lib/fluq/handler/base.rb +11 -38
- data/lib/fluq/handler/log.rb +12 -14
- data/lib/fluq/handler/noop.rb +2 -0
- data/lib/fluq/input/base.rb +33 -29
- data/lib/fluq/input/socket.rb +46 -16
- data/lib/fluq/mixins.rb +2 -2
- data/lib/fluq/runner.rb +41 -0
- data/lib/fluq/testing.rb +5 -11
- data/lib/fluq/version.rb +1 -1
- data/lib/fluq/worker.rb +73 -0
- data/spec/fluq/dsl/feed_spec.rb +33 -0
- data/spec/fluq/dsl/root_spec.rb +20 -0
- data/spec/fluq/event_spec.rb +17 -12
- data/spec/fluq/feed_spec.rb +24 -0
- data/spec/fluq/format/base_spec.rb +9 -0
- data/spec/fluq/format/json_spec.rb +22 -0
- data/spec/fluq/format/lines_spec.rb +20 -0
- data/spec/fluq/format/msgpack_spec.rb +22 -0
- data/spec/fluq/format/tsv_spec.rb +21 -0
- data/spec/fluq/handler/base_spec.rb +7 -52
- data/spec/fluq/handler/log_spec.rb +11 -14
- data/spec/fluq/handler/{null_spec.rb → noop_spec.rb} +1 -3
- data/spec/fluq/input/base_spec.rb +48 -15
- data/spec/fluq/input/socket_spec.rb +34 -26
- data/spec/fluq/mixins/loggable_spec.rb +2 -2
- data/spec/fluq/runner_spec.rb +18 -0
- data/spec/fluq/worker_spec.rb +87 -0
- data/spec/fluq_spec.rb +1 -2
- data/spec/scenario/config/nested/feed1.rb +6 -0
- data/spec/scenario/config/test.rb +8 -2
- data/spec/spec_helper.rb +7 -26
- metadata +62 -62
- data/benchmark/logging.rb +0 -37
- data/examples/common.rb +0 -3
- data/examples/simple.rb +0 -5
- data/lib/fluq/buffer.rb +0 -6
- data/lib/fluq/buffer/base.rb +0 -51
- data/lib/fluq/buffer/file.rb +0 -68
- data/lib/fluq/feed/base.rb +0 -37
- data/lib/fluq/feed/json.rb +0 -28
- data/lib/fluq/feed/msgpack.rb +0 -27
- data/lib/fluq/feed/tsv.rb +0 -30
- data/lib/fluq/handler/null.rb +0 -4
- data/lib/fluq/input/socket/connection.rb +0 -41
- data/lib/fluq/mixins/logger.rb +0 -26
- data/lib/fluq/reactor.rb +0 -79
- data/spec/fluq/buffer/base_spec.rb +0 -21
- data/spec/fluq/buffer/file_spec.rb +0 -47
- data/spec/fluq/dsl_spec.rb +0 -43
- data/spec/fluq/feed/base_spec.rb +0 -15
- data/spec/fluq/feed/json_spec.rb +0 -27
- data/spec/fluq/feed/msgpack_spec.rb +0 -27
- data/spec/fluq/feed/tsv_spec.rb +0 -27
- data/spec/fluq/input/socket/connection_spec.rb +0 -35
- data/spec/fluq/mixins/logger_spec.rb +0 -25
- data/spec/fluq/reactor_spec.rb +0 -69
- data/spec/scenario/config/nested/common.rb +0 -3
    
        data/examples/common.rb
    DELETED
    
    
    
        data/examples/simple.rb
    DELETED
    
    
    
        data/lib/fluq/buffer.rb
    DELETED
    
    
    
        data/lib/fluq/buffer/base.rb
    DELETED
    
    | @@ -1,51 +0,0 @@ | |
| 1 | 
            -
            class FluQ::Buffer::Base
         | 
| 2 | 
            -
              MAX_SIZE = 256 * 1024 * 1024 # 256M
         | 
| 3 | 
            -
             | 
| 4 | 
            -
              # @attr_reader [Hash] config
         | 
| 5 | 
            -
              attr_reader :config
         | 
| 6 | 
            -
             | 
| 7 | 
            -
              # @param [Hash] options various configuration options
         | 
| 8 | 
            -
              def initialize(options = {})
         | 
| 9 | 
            -
                super()
         | 
| 10 | 
            -
                @config = defaults.merge(options)
         | 
| 11 | 
            -
              end
         | 
| 12 | 
            -
             | 
| 13 | 
            -
              # @return [String] name identifier
         | 
| 14 | 
            -
              def name
         | 
| 15 | 
            -
                @name ||= self.class.name.split("::").last.downcase
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
              # @abstract
         | 
| 19 | 
            -
              # @yield over io object
         | 
| 20 | 
            -
              # @yieldparam [IO] io
         | 
| 21 | 
            -
              def drain
         | 
| 22 | 
            -
                yield StringIO.new
         | 
| 23 | 
            -
              end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
              # @abstract
         | 
| 26 | 
            -
              # @return [Integer] the size
         | 
| 27 | 
            -
              def size
         | 
| 28 | 
            -
                0
         | 
| 29 | 
            -
              end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
              # @return [Boolean] true if size exceeds limit
         | 
| 32 | 
            -
              def full?
         | 
| 33 | 
            -
                size >= config[:max_size]
         | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
              # @abstract data writer
         | 
| 37 | 
            -
              # @param [String] data binary string
         | 
| 38 | 
            -
              def write(data)
         | 
| 39 | 
            -
              end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
              # @abstract callback, close buffer
         | 
| 42 | 
            -
              def close
         | 
| 43 | 
            -
              end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
              protected
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                def defaults
         | 
| 48 | 
            -
                  { max_size: MAX_SIZE }
         | 
| 49 | 
            -
                end
         | 
| 50 | 
            -
             | 
| 51 | 
            -
            end
         | 
    
        data/lib/fluq/buffer/file.rb
    DELETED
    
    | @@ -1,68 +0,0 @@ | |
| 1 | 
            -
            class FluQ::Buffer::File < FluQ::Buffer::Base
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              # @attr_reader [File] file instance
         | 
| 4 | 
            -
              attr_reader :file
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              # @see FluQ::Buffer::Base#initialize
         | 
| 7 | 
            -
              def initialize(*)
         | 
| 8 | 
            -
                super
         | 
| 9 | 
            -
                @file = new_file
         | 
| 10 | 
            -
                @size = 0
         | 
| 11 | 
            -
              end
         | 
| 12 | 
            -
             | 
| 13 | 
            -
              # @see FluQ::Buffer::Base#name
         | 
| 14 | 
            -
              def name
         | 
| 15 | 
            -
                @name ||= [super, File.basename(file.path)].join("-")
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
              # @see FluQ::Buffer::Base#write
         | 
| 19 | 
            -
              def write(data)
         | 
| 20 | 
            -
                file.write(data)
         | 
| 21 | 
            -
              end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
              # @see FluQ::Buffer::Base#size
         | 
| 24 | 
            -
              def size
         | 
| 25 | 
            -
                file.size
         | 
| 26 | 
            -
              end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
              # @see FluQ::Buffer::Base#close
         | 
| 29 | 
            -
              def close
         | 
| 30 | 
            -
                file.close unless file.closed?
         | 
| 31 | 
            -
                File.unlink(file.path) if File.exists?(file.path)
         | 
| 32 | 
            -
              end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
              # @see FluQ::Buffer::Base#drain
         | 
| 35 | 
            -
              def drain
         | 
| 36 | 
            -
                file.close unless file.closed?
         | 
| 37 | 
            -
                io = File.open(file.path, 'rb', encoding: Encoding::BINARY)
         | 
| 38 | 
            -
                yield(io)
         | 
| 39 | 
            -
              ensure
         | 
| 40 | 
            -
                io.close if io
         | 
| 41 | 
            -
              end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
              protected
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                def defaults
         | 
| 46 | 
            -
                  super.merge(path: "tmp/buffers")
         | 
| 47 | 
            -
                end
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                def new_file
         | 
| 50 | 
            -
                  path = nil
         | 
| 51 | 
            -
                  incr = 0
         | 
| 52 | 
            -
                  path = root.join(generate_name(incr+=1)) until path && !path.exist?
         | 
| 53 | 
            -
                  file = path.open("wb", encoding: Encoding::BINARY)
         | 
| 54 | 
            -
                  file.sync = true
         | 
| 55 | 
            -
                  file
         | 
| 56 | 
            -
                end
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                def root
         | 
| 59 | 
            -
                  @root ||= FluQ.root.join(config[:path]).tap do |full_path|
         | 
| 60 | 
            -
                    FileUtils.mkdir_p full_path.to_s
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
                end
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                def generate_name(index)
         | 
| 65 | 
            -
                  "fb-#{(Time.now.utc.to_f * 1000).round}.#{index}"
         | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
            end
         | 
    
        data/lib/fluq/feed/base.rb
    DELETED
    
    | @@ -1,37 +0,0 @@ | |
| 1 | 
            -
            class FluQ::Feed::Base
         | 
| 2 | 
            -
              include Enumerable
         | 
| 3 | 
            -
              include FluQ::Mixins::Loggable
         | 
| 4 | 
            -
              extend FluQ::Mixins::Loggable
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              # @abstract enumerator
         | 
| 7 | 
            -
              # @param [String] raw event string
         | 
| 8 | 
            -
              # @return [FluQ::Event] event
         | 
| 9 | 
            -
              def self.to_event(raw)
         | 
| 10 | 
            -
              end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
              # @attr_reader [FluQ::Buffer::Base] buffer
         | 
| 13 | 
            -
              attr_reader :buffer
         | 
| 14 | 
            -
             | 
| 15 | 
            -
              # @param [FluQ::Buffer::Base] buffer
         | 
| 16 | 
            -
              def initialize(buffer)
         | 
| 17 | 
            -
                @buffer = buffer
         | 
| 18 | 
            -
              end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
              # @yield ober a feed of events
         | 
| 21 | 
            -
              # @yieldparam [FluQ::Event] event
         | 
| 22 | 
            -
              def each
         | 
| 23 | 
            -
                each_raw do |raw|
         | 
| 24 | 
            -
                  event = self.class.to_event(raw)
         | 
| 25 | 
            -
                  yield event if event
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              protected
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                # @abstract enumerator
         | 
| 32 | 
            -
                # @yield ober a feed of raw events
         | 
| 33 | 
            -
                # @yieldparam [String] raw event
         | 
| 34 | 
            -
                def each_raw
         | 
| 35 | 
            -
                end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
            end
         | 
    
        data/lib/fluq/feed/json.rb
    DELETED
    
    | @@ -1,28 +0,0 @@ | |
| 1 | 
            -
            class FluQ::Feed::Json < FluQ::Feed::Base
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              # @see FluQ::Feed::Base.to_event
         | 
| 4 | 
            -
              def self.to_event(raw)
         | 
| 5 | 
            -
                case hash = Oj.load(raw)
         | 
| 6 | 
            -
                when Hash
         | 
| 7 | 
            -
                  FluQ::Event.new hash.delete("="), hash.delete("@"), hash
         | 
| 8 | 
            -
                else
         | 
| 9 | 
            -
                  logger.warn "buffer contained invalid event #{hash.inspect}"
         | 
| 10 | 
            -
                  nil
         | 
| 11 | 
            -
                end
         | 
| 12 | 
            -
              rescue Oj::ParseError
         | 
| 13 | 
            -
                logger.warn "buffer contained invalid line #{raw.inspect}"
         | 
| 14 | 
            -
                nil
         | 
| 15 | 
            -
              end
         | 
| 16 | 
            -
             | 
| 17 | 
            -
              protected
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                # @see [FluQ::Feed::Base] each_raw
         | 
| 20 | 
            -
                def each_raw
         | 
| 21 | 
            -
                  buffer.drain do |io|
         | 
| 22 | 
            -
                    while line = io.gets
         | 
| 23 | 
            -
                      yield line
         | 
| 24 | 
            -
                    end
         | 
| 25 | 
            -
                  end
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
            end
         | 
    
        data/lib/fluq/feed/msgpack.rb
    DELETED
    
    | @@ -1,27 +0,0 @@ | |
| 1 | 
            -
            class FluQ::Feed::Msgpack < FluQ::Feed::Base
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              # @see FluQ::Feed::Base.to_event
         | 
| 4 | 
            -
              def self.to_event(raw)
         | 
| 5 | 
            -
                raw = MessagePack.unpack(raw) if raw.is_a?(String)
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                case raw
         | 
| 8 | 
            -
                when Hash
         | 
| 9 | 
            -
                  FluQ::Event.new raw.delete("="), raw.delete("@"), raw
         | 
| 10 | 
            -
                else
         | 
| 11 | 
            -
                  logger.warn "buffer contained invalid event #{raw.inspect}"
         | 
| 12 | 
            -
                  nil
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
              end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
              protected
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                # @see [FluQ::Feed::Base] each
         | 
| 19 | 
            -
                def each_raw(&block)
         | 
| 20 | 
            -
                  buffer.drain do |io|
         | 
| 21 | 
            -
                    pac = MessagePack::Unpacker.new(io)
         | 
| 22 | 
            -
                    pac.each(&block)
         | 
| 23 | 
            -
                  end
         | 
| 24 | 
            -
                rescue EOFError
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
            end
         | 
    
        data/lib/fluq/feed/tsv.rb
    DELETED
    
    | @@ -1,30 +0,0 @@ | |
| 1 | 
            -
            class FluQ::Feed::Tsv < FluQ::Feed::Base
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              # @see FluQ::Feed::Base.to_event
         | 
| 4 | 
            -
              def self.to_event(raw)
         | 
| 5 | 
            -
                tag, timestamp, json = raw.split("\t")
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                case hash = Oj.load(json)
         | 
| 8 | 
            -
                when Hash
         | 
| 9 | 
            -
                  FluQ::Event.new tag, timestamp, hash
         | 
| 10 | 
            -
                else
         | 
| 11 | 
            -
                  logger.warn "buffer contained invalid event #{hash.inspect}"
         | 
| 12 | 
            -
                  nil
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
              rescue Oj::ParseError, ArgumentError
         | 
| 15 | 
            -
                logger.warn "buffer contained invalid line #{raw.inspect}"
         | 
| 16 | 
            -
                nil
         | 
| 17 | 
            -
              end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
              protected
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                # @see [FluQ::Feed::Base] each_raw
         | 
| 22 | 
            -
                def each_raw
         | 
| 23 | 
            -
                  buffer.drain do |io|
         | 
| 24 | 
            -
                    while line = io.gets
         | 
| 25 | 
            -
                      yield line
         | 
| 26 | 
            -
                    end
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
                end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            end
         | 
    
        data/lib/fluq/handler/null.rb
    DELETED
    
    
| @@ -1,41 +0,0 @@ | |
| 1 | 
            -
            class FluQ::Input::Socket::Connection < EventMachine::Connection
         | 
| 2 | 
            -
              include FluQ::Mixins::Loggable
         | 
| 3 | 
            -
             | 
| 4 | 
            -
              # Constructor
         | 
| 5 | 
            -
              # @param [FluQ::Input::Socket] parent the input
         | 
| 6 | 
            -
              def initialize(parent)
         | 
| 7 | 
            -
                super()
         | 
| 8 | 
            -
                @parent = parent
         | 
| 9 | 
            -
              end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
              # Callback
         | 
| 12 | 
            -
              def post_init
         | 
| 13 | 
            -
                self.comm_inactivity_timeout = 60
         | 
| 14 | 
            -
              end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
              # Callback
         | 
| 17 | 
            -
              def receive_data(data)
         | 
| 18 | 
            -
                buffer.write(data)
         | 
| 19 | 
            -
                flush! if buffer.full?
         | 
| 20 | 
            -
              rescue => ex
         | 
| 21 | 
            -
                logger.crash "#{self.class.name} failure: #{ex.message} (#{ex.class.name})", ex
         | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
              # Callback
         | 
| 25 | 
            -
              def unbind
         | 
| 26 | 
            -
                flush!
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              protected
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                def buffer
         | 
| 32 | 
            -
                  @buffer ||= @parent.new_buffer
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                def flush!
         | 
| 36 | 
            -
                  current = buffer
         | 
| 37 | 
            -
                  @buffer = nil
         | 
| 38 | 
            -
                  @parent.flush!(current)
         | 
| 39 | 
            -
                end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
            end
         | 
    
        data/lib/fluq/mixins/logger.rb
    DELETED
    
    | @@ -1,26 +0,0 @@ | |
| 1 | 
            -
            module FluQ::Mixins::Logger
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              def exception_handlers
         | 
| 4 | 
            -
                @exception_handlers ||= []
         | 
| 5 | 
            -
              end
         | 
| 6 | 
            -
             | 
| 7 | 
            -
              def exception_handler(&block)
         | 
| 8 | 
            -
                exception_handlers << block
         | 
| 9 | 
            -
              end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
              def crash(string, exception)
         | 
| 12 | 
            -
                if exception.respond_to?(:backtrace) && exception.backtrace
         | 
| 13 | 
            -
                  trace = exception.backtrace.map {|line| "  #{line}" }.join("\n")
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
                error [string, trace].compact.join("\n")
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                exception_handlers.each do |handler|
         | 
| 18 | 
            -
                  begin
         | 
| 19 | 
            -
                    handler.call(exception)
         | 
| 20 | 
            -
                  rescue => ex
         | 
| 21 | 
            -
                    error "EXCEPTION HANDLER CRASHED: #{ex.message}"
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
                end
         | 
| 24 | 
            -
              end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
            end
         | 
    
        data/lib/fluq/reactor.rb
    DELETED
    
    | @@ -1,79 +0,0 @@ | |
| 1 | 
            -
            class FluQ::Reactor
         | 
| 2 | 
            -
              include FluQ::Mixins::Loggable
         | 
| 3 | 
            -
             | 
| 4 | 
            -
              # attr_reader [Array] handlers
         | 
| 5 | 
            -
              attr_reader :handlers
         | 
| 6 | 
            -
             | 
| 7 | 
            -
              # attr_reader [Array] inputs
         | 
| 8 | 
            -
              attr_reader :inputs
         | 
| 9 | 
            -
             | 
| 10 | 
            -
              # Runs the reactor within EventMachine
         | 
| 11 | 
            -
              def self.run
         | 
| 12 | 
            -
                EM.run do
         | 
| 13 | 
            -
                  EM.threadpool_size = 100
         | 
| 14 | 
            -
                  yield new
         | 
| 15 | 
            -
                end
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
              # Constructor
         | 
| 19 | 
            -
              def initialize
         | 
| 20 | 
            -
                super
         | 
| 21 | 
            -
                @handlers    = []
         | 
| 22 | 
            -
                @inputs      = []
         | 
| 23 | 
            -
              end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
              # Listens to an input
         | 
| 26 | 
            -
              # @param [Class<FluQ::Input::Base>] klass input class
         | 
| 27 | 
            -
              # @param [multiple] args initialization arguments
         | 
| 28 | 
            -
              def listen(klass, *args)
         | 
| 29 | 
            -
                input = klass.new(self, *args).tap(&:run)
         | 
| 30 | 
            -
                inputs.push(input)
         | 
| 31 | 
            -
                logger.info "Listening to #{input.name}"
         | 
| 32 | 
            -
                input
         | 
| 33 | 
            -
              end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
              # Registers a handler
         | 
| 36 | 
            -
              # @param [Class<FluQ::Handler::Base>] klass handler class
         | 
| 37 | 
            -
              # @param [multiple] args initialization arguments
         | 
| 38 | 
            -
              def register(klass, *args)
         | 
| 39 | 
            -
                handler = klass.new(self, *args)
         | 
| 40 | 
            -
                if handlers.any? {|h| h.name == handler.name }
         | 
| 41 | 
            -
                  raise ArgumentError, "Handler '#{handler.name}' is already registered. Please provide a unique :name option"
         | 
| 42 | 
            -
                end
         | 
| 43 | 
            -
                handlers.push(handler)
         | 
| 44 | 
            -
                logger.info "Registered #{handler.name}"
         | 
| 45 | 
            -
                handler
         | 
| 46 | 
            -
              end
         | 
| 47 | 
            -
             | 
| 48 | 
            -
              # @param [Array<Event>] events to process
         | 
| 49 | 
            -
              def process(events)
         | 
| 50 | 
            -
                on_events events
         | 
| 51 | 
            -
                true
         | 
| 52 | 
            -
              end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
              # @return [String] introspection
         | 
| 55 | 
            -
              def inspect
         | 
| 56 | 
            -
                "#<#{self.class.name} inputs: #{inputs.size}, handlers: #{handlers.size}>"
         | 
| 57 | 
            -
              end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
              protected
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                def on_events(events)
         | 
| 62 | 
            -
                  handlers.map do |handler|
         | 
| 63 | 
            -
                    Thread.new { handle(handler, Time.now, events) }
         | 
| 64 | 
            -
                  end.each(&:join)
         | 
| 65 | 
            -
                end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                def handle(handler, start, events)
         | 
| 68 | 
            -
                  matching = handler.select(events)
         | 
| 69 | 
            -
                  ::Timeout.timeout handler.config[:timeout] do
         | 
| 70 | 
            -
                    handler.on_events(matching)
         | 
| 71 | 
            -
                  end unless matching.empty?
         | 
| 72 | 
            -
                  logger.info { "#{handler.name} processed #{matching.size}/#{events.size} events in #{((Time.now - start) * 1000).round}ms" }
         | 
| 73 | 
            -
                rescue Timeout::Error => tx
         | 
| 74 | 
            -
                  logger.crash "#{handler.class.name} #{handler.name} timeout out after #{handler.config[:timeout]}s", tx
         | 
| 75 | 
            -
                rescue => ex
         | 
| 76 | 
            -
                  logger.crash "#{handler.class.name} #{handler.name} failed: #{ex.class.name} #{ex.message}", ex
         | 
| 77 | 
            -
                end
         | 
| 78 | 
            -
             | 
| 79 | 
            -
            end
         | 
| @@ -1,21 +0,0 @@ | |
| 1 | 
            -
            require 'spec_helper'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            describe FluQ::Buffer::Base do
         | 
| 4 | 
            -
             | 
| 5 | 
            -
              its(:config)  { should == {max_size: 268435456} }
         | 
| 6 | 
            -
              its(:size)    { should be(0) }
         | 
| 7 | 
            -
              its(:name)    { should == "base" }
         | 
| 8 | 
            -
              it { should respond_to(:write) }
         | 
| 9 | 
            -
              it { should respond_to(:close) }
         | 
| 10 | 
            -
              it { should_not be_full }
         | 
| 11 | 
            -
             | 
| 12 | 
            -
              it 'should drain' do
         | 
| 13 | 
            -
                subject.drain {|io| io.should be_instance_of(StringIO) }
         | 
| 14 | 
            -
              end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
              describe 'when size exeeds limit' do
         | 
| 17 | 
            -
                before { subject.stub size: 268435457 }
         | 
| 18 | 
            -
                it { should be_full }
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
            end
         |