sensu-redis 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +9 -0
 - data/.travis.yml +4 -0
 - data/Gemfile +4 -0
 - data/README.md +36 -0
 - data/Rakefile +1 -0
 - data/bin/console +14 -0
 - data/bin/setup +7 -0
 - data/lib/sensu/redis.rb +43 -0
 - data/lib/sensu/redis/commands.rb +93 -0
 - data/lib/sensu/redis/connection.rb +112 -0
 - data/lib/sensu/redis/constants.rb +96 -0
 - data/lib/sensu/redis/errors.rb +19 -0
 - data/lib/sensu/redis/parser.rb +66 -0
 - data/lib/sensu/redis/processor.rb +79 -0
 - data/sensu-redis.gemspec +24 -0
 - metadata +131 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 1dd63d72bb8617b4a11636fc4f49f601fdc58f97
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 1ecffe0185d61f8b98cdbb485c1d56d5d1da9e52
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: b29df8a599bb52c350a4fd0aacdde00b1472ad58ef77782d02ba06878ab0b43dbec9ef2c0c514fcf9ec9b63a2c760f92f6de155a0bf9b8dfbdfe00d31bd5afeb
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: d6d503398789220f4433ffacd6cf18d20b5a5930bfd3bf0acee9743e5d6c31f169b8235198f2b92b5fd8c2805b45029cbca4c83aba9a319b2e70d91d7d2ae3ee
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Sensu::Redis
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sensu/redis`. To experiment with that code, run `bin/console` for an interactive prompt.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            TODO: Delete this and the text above, and describe your gem
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            Add this line to your application's Gemfile:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
            gem 'sensu-redis'
         
     | 
| 
      
 13 
     | 
    
         
            +
            ```
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            And then execute:
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                $ bundle
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            Or install it yourself as:
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                $ gem install sensu-redis
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            TODO: Write usage instructions here
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            ## Development
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            ## Contributing
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/sensu-redis.
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "bundler/gem_tasks"
         
     | 
    
        data/bin/console
    ADDED
    
    | 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "bundler/setup"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "sensu/redis"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            # You can add fixtures and/or initialization code here to make experimenting
         
     | 
| 
      
 7 
     | 
    
         
            +
            # with your gem easier. You can also use a different console, if you like.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # (If you use this, don't forget to add pry to your Gemfile!)
         
     | 
| 
      
 10 
     | 
    
         
            +
            # require "pry"
         
     | 
| 
      
 11 
     | 
    
         
            +
            # Pry.start
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            require "irb"
         
     | 
| 
      
 14 
     | 
    
         
            +
            IRB.start
         
     | 
    
        data/bin/setup
    ADDED
    
    
    
        data/lib/sensu/redis.rb
    ADDED
    
    | 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "rubygems"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "sensu/redis/parser"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "sensu/redis/processor"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "sensu/redis/commands"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "sensu/redis/connection"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "eventmachine"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "uri"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            module Sensu
         
     | 
| 
      
 10 
     | 
    
         
            +
              module Redis
         
     | 
| 
      
 11 
     | 
    
         
            +
                class Client < EM::Connection
         
     | 
| 
      
 12 
     | 
    
         
            +
                  include EM::Deferrable
         
     | 
| 
      
 13 
     | 
    
         
            +
                  include Parser
         
     | 
| 
      
 14 
     | 
    
         
            +
                  include Processor
         
     | 
| 
      
 15 
     | 
    
         
            +
                  include Commands
         
     | 
| 
      
 16 
     | 
    
         
            +
                  include Connection
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 19 
     | 
    
         
            +
                    def parse_url(url)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 21 
     | 
    
         
            +
                        uri = URI.parse(url)
         
     | 
| 
      
 22 
     | 
    
         
            +
                        {
         
     | 
| 
      
 23 
     | 
    
         
            +
                          :host => uri.host,
         
     | 
| 
      
 24 
     | 
    
         
            +
                          :port => uri.port,
         
     | 
| 
      
 25 
     | 
    
         
            +
                          :password => uri.password
         
     | 
| 
      
 26 
     | 
    
         
            +
                        }
         
     | 
| 
      
 27 
     | 
    
         
            +
                      rescue
         
     | 
| 
      
 28 
     | 
    
         
            +
                        raise ArgumentError, "invalid redis url"
         
     | 
| 
      
 29 
     | 
    
         
            +
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    def connect(options={})
         
     | 
| 
      
 33 
     | 
    
         
            +
                      if options.is_a?(String)
         
     | 
| 
      
 34 
     | 
    
         
            +
                        options = parse_url(options)
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
                      options[:host] ||= "127.0.0.1"
         
     | 
| 
      
 37 
     | 
    
         
            +
                      options[:port] = (options[:port] || 6379).to_i
         
     | 
| 
      
 38 
     | 
    
         
            +
                      EM.connect(options[:host], options[:port], self, options)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,93 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "sensu/redis/constants"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "sensu/redis/errors"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Sensu
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Redis
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Sensu Module for requesting Redis commands, intended to be
         
     | 
| 
      
 7 
     | 
    
         
            +
                # included by Sensu::Redis::Client.
         
     | 
| 
      
 8 
     | 
    
         
            +
                #
         
     | 
| 
      
 9 
     | 
    
         
            +
                # You can read about RESP @ http://redis.io/topics/protocol
         
     | 
| 
      
 10 
     | 
    
         
            +
                module Commands
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # Determine the byte size of a string.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # @param string [String]
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # @return [Integer] string byte size.
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def get_size(string)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    string.respond_to?(:bytesize) ? string.bytesize : string.size
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  # Send a Redis command using RESP multi bulk. This method is
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # called by the Redis command methods, which are created by
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # `create_command_methods()`, it simply implements RESP and
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # sends commands to Redis via EM connection `send_data()`.
         
     | 
| 
      
 23 
     | 
    
         
            +
                  def send_command(*arguments)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    command = "*#{arguments.size}#{DELIM}"
         
     | 
| 
      
 25 
     | 
    
         
            +
                    arguments.each do |value|
         
     | 
| 
      
 26 
     | 
    
         
            +
                      value = value.to_s
         
     | 
| 
      
 27 
     | 
    
         
            +
                      command << "$#{get_size(value)}#{DELIM}#{value}#{DELIM}"
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
                    if @deferred_status
         
     | 
| 
      
 30 
     | 
    
         
            +
                      send_data(command)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    else
         
     | 
| 
      
 32 
     | 
    
         
            +
                      callback { send_data(command) }
         
     | 
| 
      
 33 
     | 
    
         
            +
                    end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  # Create Redis command methods. Command methods just wrap
         
     | 
| 
      
 37 
     | 
    
         
            +
                  # `send_command()` and enqueue a response callback. This method
         
     | 
| 
      
 38 
     | 
    
         
            +
                  # MUST be called in the connection object's `initialize()`.
         
     | 
| 
      
 39 
     | 
    
         
            +
                  def create_command_methods!
         
     | 
| 
      
 40 
     | 
    
         
            +
                    @response_callbacks ||= []
         
     | 
| 
      
 41 
     | 
    
         
            +
                    REDIS_COMMANDS.each do |command|
         
     | 
| 
      
 42 
     | 
    
         
            +
                      self.class.send(:define_method, command.to_sym) do |*arguments, &block|
         
     | 
| 
      
 43 
     | 
    
         
            +
                        send_command(command, *arguments)
         
     | 
| 
      
 44 
     | 
    
         
            +
                        @response_callbacks << [RESPONSE_PROCESSORS[command], block]
         
     | 
| 
      
 45 
     | 
    
         
            +
                      end
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  # Authenticate to Redis and select the correct DB, when
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # applicable. The auth and select Redis commands must be the
         
     | 
| 
      
 51 
     | 
    
         
            +
                  # first commands (& callbacks) to run.
         
     | 
| 
      
 52 
     | 
    
         
            +
                  #
         
     | 
| 
      
 53 
     | 
    
         
            +
                  # @param password [String]
         
     | 
| 
      
 54 
     | 
    
         
            +
                  # @param db [Integer]
         
     | 
| 
      
 55 
     | 
    
         
            +
                  def auth_and_select_db(password=nil, db=nil)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    callbacks = @callbacks || []
         
     | 
| 
      
 57 
     | 
    
         
            +
                    @callbacks = []
         
     | 
| 
      
 58 
     | 
    
         
            +
                    send_command(AUTH_COMMAND, password) if password
         
     | 
| 
      
 59 
     | 
    
         
            +
                    send_command(SELECT_COMMAND, db) if db
         
     | 
| 
      
 60 
     | 
    
         
            +
                    callbacks.each { |block| callback(&block) }
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  # Subscribe to a Redis PubSub channel.
         
     | 
| 
      
 64 
     | 
    
         
            +
                  #
         
     | 
| 
      
 65 
     | 
    
         
            +
                  # @param channel [String]
         
     | 
| 
      
 66 
     | 
    
         
            +
                  def subscribe(channel, &block)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    @pubsub_callbacks ||= Hash.new([])
         
     | 
| 
      
 68 
     | 
    
         
            +
                    @pubsub_callbacks[channel] << block
         
     | 
| 
      
 69 
     | 
    
         
            +
                    send_command(SUBSCRIBE_COMMAND, channel, &block)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  # Unsubscribe to one or more Redis PubSub channels. If a channel
         
     | 
| 
      
 73 
     | 
    
         
            +
                  # is provided, this method will unsubscribe from it. If a
         
     | 
| 
      
 74 
     | 
    
         
            +
                  # channel is not provided, this method will unsubscribe from all
         
     | 
| 
      
 75 
     | 
    
         
            +
                  # Redis PubSub channels.
         
     | 
| 
      
 76 
     | 
    
         
            +
                  #
         
     | 
| 
      
 77 
     | 
    
         
            +
                  # @param channel [String]
         
     | 
| 
      
 78 
     | 
    
         
            +
                  def unsubscribe(channel=nil, &block)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    @pubsub_callbacks ||= Hash.new([])
         
     | 
| 
      
 80 
     | 
    
         
            +
                    arguments = [UNSUBSCRIBE_COMMAND]
         
     | 
| 
      
 81 
     | 
    
         
            +
                    if channel
         
     | 
| 
      
 82 
     | 
    
         
            +
                      @pubsub_callbacks[channel] = [block]
         
     | 
| 
      
 83 
     | 
    
         
            +
                      arguments << channel
         
     | 
| 
      
 84 
     | 
    
         
            +
                    else
         
     | 
| 
      
 85 
     | 
    
         
            +
                      @pubsub_callbacks.each_key do |key|
         
     | 
| 
      
 86 
     | 
    
         
            +
                        @pubsub_callbacks[key] = [block]
         
     | 
| 
      
 87 
     | 
    
         
            +
                      end
         
     | 
| 
      
 88 
     | 
    
         
            +
                    end
         
     | 
| 
      
 89 
     | 
    
         
            +
                    send_command(arguments)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,112 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "sensu/redis/constants"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "sensu/redis/errors"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Sensu
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Redis
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Sensu Module connecting to Redis.
         
     | 
| 
      
 7 
     | 
    
         
            +
                module Connection
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def initialize(options={})
         
     | 
| 
      
 9 
     | 
    
         
            +
                    create_command_methods!
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @host = options[:host]
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @port = options[:port]
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @db = (options[:db] || 0).to_i
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @password = options[:password]
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @auto_reconnect = options.fetch(:auto_reconnect, true)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @reconnect_on_error = options.fetch(:reconnect_on_error, true)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @error_callback = lambda do |error|
         
     | 
| 
      
 17 
     | 
    
         
            +
                      raise(error)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @reconnect_callbacks = {
         
     | 
| 
      
 20 
     | 
    
         
            +
                      :before => lambda{},
         
     | 
| 
      
 21 
     | 
    
         
            +
                      :after  => lambda{}
         
     | 
| 
      
 22 
     | 
    
         
            +
                    }
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  # Set the on error callback.
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def on_error(&block)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    @error_callback = block
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  # Set the before reconnect callback.
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def before_reconnect(&block)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @reconnect_callbacks[:before] = block
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  # Set the after reconnect callback.
         
     | 
| 
      
 36 
     | 
    
         
            +
                  def after_reconnect(&block)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @reconnect_callbacks[:after] = block
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  # Create an error and pass it to the error callback.
         
     | 
| 
      
 41 
     | 
    
         
            +
                  #
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # @param klass [Class]
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # @param message [String]
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def error(klass, message)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    redis_error = klass.new(message)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @error_callback.call(redis_error)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  # Determine if connected to Redis.
         
     | 
| 
      
 50 
     | 
    
         
            +
                  def connected?
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @connected || false
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  # Reconnect to Redis. The before reconnect callback is first
         
     | 
| 
      
 55 
     | 
    
         
            +
                  # call if not already reconnecting. This method uses a 1 second
         
     | 
| 
      
 56 
     | 
    
         
            +
                  # delay before attempting a reconnect.
         
     | 
| 
      
 57 
     | 
    
         
            +
                  def reconnect!
         
     | 
| 
      
 58 
     | 
    
         
            +
                    @reconnect_callbacks[:before].call unless @reconnecting
         
     | 
| 
      
 59 
     | 
    
         
            +
                    @reconnecting = true
         
     | 
| 
      
 60 
     | 
    
         
            +
                    EM.add_timer(1) do
         
     | 
| 
      
 61 
     | 
    
         
            +
                      reconnect(@host, @port)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  # Close the Redis connection after writing the current
         
     | 
| 
      
 66 
     | 
    
         
            +
                  # command/data.
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def close
         
     | 
| 
      
 68 
     | 
    
         
            +
                    @closing = true
         
     | 
| 
      
 69 
     | 
    
         
            +
                    close_connection_after_writing
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  # Called by EM when the connection closes, either intentionally
         
     | 
| 
      
 73 
     | 
    
         
            +
                  # or unexpectedly.
         
     | 
| 
      
 74 
     | 
    
         
            +
                  def unbind
         
     | 
| 
      
 75 
     | 
    
         
            +
                    @deferred_status = nil
         
     | 
| 
      
 76 
     | 
    
         
            +
                    @response_callbacks = []
         
     | 
| 
      
 77 
     | 
    
         
            +
                    @multibulk_count = false
         
     | 
| 
      
 78 
     | 
    
         
            +
                    if @closing
         
     | 
| 
      
 79 
     | 
    
         
            +
                      @reconnecting = false
         
     | 
| 
      
 80 
     | 
    
         
            +
                    elsif ((@connected || @reconnecting) && @auto_reconnect) || @reconnect_on_error
         
     | 
| 
      
 81 
     | 
    
         
            +
                      reconnect!
         
     | 
| 
      
 82 
     | 
    
         
            +
                    elsif @connected
         
     | 
| 
      
 83 
     | 
    
         
            +
                      error(ConnectionError, "connection closed")
         
     | 
| 
      
 84 
     | 
    
         
            +
                    else
         
     | 
| 
      
 85 
     | 
    
         
            +
                      error(ConnectionError, "unable to connect to redis server")
         
     | 
| 
      
 86 
     | 
    
         
            +
                    end
         
     | 
| 
      
 87 
     | 
    
         
            +
                    @connected = false
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  # Validate the connection, ensuring that the Redis release
         
     | 
| 
      
 91 
     | 
    
         
            +
                  # supports Sensu's required Redis commands. A connection error
         
     | 
| 
      
 92 
     | 
    
         
            +
                  # is thrown if Redis's version does not meet the requirement.
         
     | 
| 
      
 93 
     | 
    
         
            +
                  def validate_connection!
         
     | 
| 
      
 94 
     | 
    
         
            +
                    info do |redis_info|
         
     | 
| 
      
 95 
     | 
    
         
            +
                      if redis_info[:redis_version] < "1.3.14"
         
     | 
| 
      
 96 
     | 
    
         
            +
                        error(ConnectionError, "redis version must be >= 2.0 RC 1")
         
     | 
| 
      
 97 
     | 
    
         
            +
                      end
         
     | 
| 
      
 98 
     | 
    
         
            +
                    end
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                  # Called by EM when the connection is established.
         
     | 
| 
      
 102 
     | 
    
         
            +
                  def connection_completed
         
     | 
| 
      
 103 
     | 
    
         
            +
                    @connected = true
         
     | 
| 
      
 104 
     | 
    
         
            +
                    auth_and_select_db(@password, @db)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    validate_connection!
         
     | 
| 
      
 106 
     | 
    
         
            +
                    @reconnect_callbacks[:after].call if @reconnecting
         
     | 
| 
      
 107 
     | 
    
         
            +
                    @reconnecting = false
         
     | 
| 
      
 108 
     | 
    
         
            +
                    succeed
         
     | 
| 
      
 109 
     | 
    
         
            +
                  end
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
              end
         
     | 
| 
      
 112 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,96 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sensu
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Redis
         
     | 
| 
      
 3 
     | 
    
         
            +
                # RESP (REdis Serialization Protocol) response type characters and
         
     | 
| 
      
 4 
     | 
    
         
            +
                # delimiter (http://redis.io/topics/protocol).
         
     | 
| 
      
 5 
     | 
    
         
            +
                OK = "OK".freeze
         
     | 
| 
      
 6 
     | 
    
         
            +
                MINUS = "-".freeze
         
     | 
| 
      
 7 
     | 
    
         
            +
                PLUS = "+".freeze
         
     | 
| 
      
 8 
     | 
    
         
            +
                COLON = ":".freeze
         
     | 
| 
      
 9 
     | 
    
         
            +
                DOLLAR = "$".freeze
         
     | 
| 
      
 10 
     | 
    
         
            +
                ASTERISK = "*".freeze
         
     | 
| 
      
 11 
     | 
    
         
            +
                DELIM = "\r\n".freeze
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                # Redis response line parser incomplete data return value.
         
     | 
| 
      
 14 
     | 
    
         
            +
                INCOMPLETE = "incomp".freeze
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                # Used to return empty array reponses.
         
     | 
| 
      
 17 
     | 
    
         
            +
                EMPTY_ARRAY = [].freeze
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                # Redis response boolean values.
         
     | 
| 
      
 20 
     | 
    
         
            +
                TRUE_VALUES = %w[1 OK].freeze
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # Redis pubsub response type values.
         
     | 
| 
      
 23 
     | 
    
         
            +
                PUBSUB_RESPONSES = %w[message unsubscribe].freeze
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                # Redis commands that are supported by this library.
         
     | 
| 
      
 26 
     | 
    
         
            +
                REDIS_COMMANDS = [
         
     | 
| 
      
 27 
     | 
    
         
            +
                  "set",
         
     | 
| 
      
 28 
     | 
    
         
            +
                  "setnx",
         
     | 
| 
      
 29 
     | 
    
         
            +
                  "get",
         
     | 
| 
      
 30 
     | 
    
         
            +
                  "getset",
         
     | 
| 
      
 31 
     | 
    
         
            +
                  "del",
         
     | 
| 
      
 32 
     | 
    
         
            +
                  "info",
         
     | 
| 
      
 33 
     | 
    
         
            +
                  "sadd",
         
     | 
| 
      
 34 
     | 
    
         
            +
                  "smembers",
         
     | 
| 
      
 35 
     | 
    
         
            +
                  "sismembers",
         
     | 
| 
      
 36 
     | 
    
         
            +
                  "srem",
         
     | 
| 
      
 37 
     | 
    
         
            +
                  "scard",
         
     | 
| 
      
 38 
     | 
    
         
            +
                  "hset",
         
     | 
| 
      
 39 
     | 
    
         
            +
                  "hsetnx",
         
     | 
| 
      
 40 
     | 
    
         
            +
                  "hget",
         
     | 
| 
      
 41 
     | 
    
         
            +
                  "hgetall",
         
     | 
| 
      
 42 
     | 
    
         
            +
                  "hdel",
         
     | 
| 
      
 43 
     | 
    
         
            +
                  "hincrby",
         
     | 
| 
      
 44 
     | 
    
         
            +
                  "rpush",
         
     | 
| 
      
 45 
     | 
    
         
            +
                  "lpush",
         
     | 
| 
      
 46 
     | 
    
         
            +
                  "ltrim",
         
     | 
| 
      
 47 
     | 
    
         
            +
                  "lrange",
         
     | 
| 
      
 48 
     | 
    
         
            +
                  "exists",
         
     | 
| 
      
 49 
     | 
    
         
            +
                  "ttl",
         
     | 
| 
      
 50 
     | 
    
         
            +
                  "expire",
         
     | 
| 
      
 51 
     | 
    
         
            +
                  "flushdb",
         
     | 
| 
      
 52 
     | 
    
         
            +
                  "incr"
         
     | 
| 
      
 53 
     | 
    
         
            +
                ].freeze
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                # Redis DB select command.
         
     | 
| 
      
 56 
     | 
    
         
            +
                SELECT_COMMAND = "select".freeze
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                # Redis authentication command.
         
     | 
| 
      
 59 
     | 
    
         
            +
                AUTH_COMMAND = "auth".freeze
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                # Redis PubSub subscribe command.
         
     | 
| 
      
 62 
     | 
    
         
            +
                SUBSCRIBE_COMMAND = "subscribe".freeze
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                # Redis PubSub unsubscribe command.
         
     | 
| 
      
 65 
     | 
    
         
            +
                UNSUBSCRIBE_COMMAND = "unsubscribe".freeze
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                # Boolean Redis response value processor.
         
     | 
| 
      
 68 
     | 
    
         
            +
                BOOLEAN_PROCESSOR = lambda{|r| TRUE_VALUES.include?(r.to_s)}
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                # Redis response value processors.
         
     | 
| 
      
 71 
     | 
    
         
            +
                RESPONSE_PROCESSORS = {
         
     | 
| 
      
 72 
     | 
    
         
            +
                  "exists" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 73 
     | 
    
         
            +
                  "sadd" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 74 
     | 
    
         
            +
                  "srem" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 75 
     | 
    
         
            +
                  "setnx" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 76 
     | 
    
         
            +
                  "del" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 77 
     | 
    
         
            +
                  "expire" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 78 
     | 
    
         
            +
                  "select" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 79 
     | 
    
         
            +
                  "hset" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 80 
     | 
    
         
            +
                  "hdel" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 81 
     | 
    
         
            +
                  "hsetnx" => BOOLEAN_PROCESSOR,
         
     | 
| 
      
 82 
     | 
    
         
            +
                  "hgetall" => lambda{|r| Hash[*r]},
         
     | 
| 
      
 83 
     | 
    
         
            +
                  "info" => lambda{|r|
         
     | 
| 
      
 84 
     | 
    
         
            +
                    info = {}
         
     | 
| 
      
 85 
     | 
    
         
            +
                    r.each_line do |line|
         
     | 
| 
      
 86 
     | 
    
         
            +
                      line.chomp!
         
     | 
| 
      
 87 
     | 
    
         
            +
                      unless line.empty?
         
     | 
| 
      
 88 
     | 
    
         
            +
                        k, v = line.split(":", 2)
         
     | 
| 
      
 89 
     | 
    
         
            +
                        info[k.to_sym] = v
         
     | 
| 
      
 90 
     | 
    
         
            +
                      end
         
     | 
| 
      
 91 
     | 
    
         
            +
                    end
         
     | 
| 
      
 92 
     | 
    
         
            +
                    info
         
     | 
| 
      
 93 
     | 
    
         
            +
                  }
         
     | 
| 
      
 94 
     | 
    
         
            +
                }
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sensu
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Redis
         
     | 
| 
      
 3 
     | 
    
         
            +
                # Error class for Redis connection errors.
         
     | 
| 
      
 4 
     | 
    
         
            +
                class ConnectionError < StandardError; end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                # Error class for Redis protocol (RESP) errors.
         
     | 
| 
      
 7 
     | 
    
         
            +
                class ProtocolError < StandardError; end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                # Error class for Redis command errors.
         
     | 
| 
      
 10 
     | 
    
         
            +
                class CommandError < StandardError
         
     | 
| 
      
 11 
     | 
    
         
            +
                  attr_accessor :code
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def initialize(*args)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    args[0] = "redis returned error code: #{args[0]}"
         
     | 
| 
      
 15 
     | 
    
         
            +
                    super
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,66 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "sensu/redis/constants"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "sensu/redis/errors"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Sensu
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Redis
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Sensu Module for parsing RESP (REdis Serialization Protocol).
         
     | 
| 
      
 7 
     | 
    
         
            +
                # You can read about RESP @ http://redis.io/topics/protocol
         
     | 
| 
      
 8 
     | 
    
         
            +
                # This module calls methods provided by other Sensu Redis modules:
         
     | 
| 
      
 9 
     | 
    
         
            +
                #   Sensu::Redis::Processor.dispatch_error()
         
     | 
| 
      
 10 
     | 
    
         
            +
                #   Sensu::Redis::Processor.dispatch_response()
         
     | 
| 
      
 11 
     | 
    
         
            +
                #   Sensu::Redis::Processor.begin_multibulk()
         
     | 
| 
      
 12 
     | 
    
         
            +
                #   Sensu::Redis::Connection.error()
         
     | 
| 
      
 13 
     | 
    
         
            +
                module Parser
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # Parse a RESP line.
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # @param line [String]
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def parse_line(line)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    # Trim off the response type and delimiter (\r\n).
         
     | 
| 
      
 19 
     | 
    
         
            +
                    response = line.slice(1..-3)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    # First character indicates response type.
         
     | 
| 
      
 21 
     | 
    
         
            +
                    case line[0, 1]
         
     | 
| 
      
 22 
     | 
    
         
            +
                    when MINUS # Error, e.g. -ERR
         
     | 
| 
      
 23 
     | 
    
         
            +
                      dispatch_error(response)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    when PLUS # String, e.g. +OK
         
     | 
| 
      
 25 
     | 
    
         
            +
                      dispatch_response(response)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    when DOLLAR # Bulk string, e.g. $3\r\nfoo\r\n
         
     | 
| 
      
 27 
     | 
    
         
            +
                      response_size = Integer(response)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      if response_size == -1 # No data, return nil.
         
     | 
| 
      
 29 
     | 
    
         
            +
                        dispatch_response(nil)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      elsif @buffer.size >= response_size + 2 # Complete data.
         
     | 
| 
      
 31 
     | 
    
         
            +
                        dispatch_response(@buffer.slice!(0, response_size))
         
     | 
| 
      
 32 
     | 
    
         
            +
                        @buffer.slice!(0,2) # Discard delimeter (\r\n).
         
     | 
| 
      
 33 
     | 
    
         
            +
                      else # Incomplete, have data pushed back into buffer.
         
     | 
| 
      
 34 
     | 
    
         
            +
                        return INCOMPLETE
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
                    when COLON # Integer, e.g. :8
         
     | 
| 
      
 37 
     | 
    
         
            +
                      dispatch_response(Integer(response))
         
     | 
| 
      
 38 
     | 
    
         
            +
                    when ASTERISK # Array, e.g. *2\r\n$3\r\foo\r\n$3\r\nbar\r\n
         
     | 
| 
      
 39 
     | 
    
         
            +
                      multibulk_count = Integer(response)
         
     | 
| 
      
 40 
     | 
    
         
            +
                      if multibulk_count == -1 || multibulk_count == 0 # No data, return [].
         
     | 
| 
      
 41 
     | 
    
         
            +
                        dispatch_response(EMPTY_ARRAY)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      else
         
     | 
| 
      
 43 
     | 
    
         
            +
                        begin_multibulk(multibulk_count) # Accumulate responses.
         
     | 
| 
      
 44 
     | 
    
         
            +
                      end
         
     | 
| 
      
 45 
     | 
    
         
            +
                    else
         
     | 
| 
      
 46 
     | 
    
         
            +
                      error(ProtocolError, "response type not recognized: #{line.strip}")
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  # EM connection receive data, parse incoming data using RESP
         
     | 
| 
      
 51 
     | 
    
         
            +
                  # (`parse_line()`).
         
     | 
| 
      
 52 
     | 
    
         
            +
                  #
         
     | 
| 
      
 53 
     | 
    
         
            +
                  # @param data [String]
         
     | 
| 
      
 54 
     | 
    
         
            +
                  def receive_data(data)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    (@buffer ||= '') << data
         
     | 
| 
      
 56 
     | 
    
         
            +
                    while index = @buffer.index(DELIM)
         
     | 
| 
      
 57 
     | 
    
         
            +
                      line = @buffer.slice!(0, index+2)
         
     | 
| 
      
 58 
     | 
    
         
            +
                      if parse_line(line) == INCOMPLETE
         
     | 
| 
      
 59 
     | 
    
         
            +
                        @buffer[0...0] = line
         
     | 
| 
      
 60 
     | 
    
         
            +
                        break
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,79 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "sensu/redis/constants"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "sensu/redis/errors"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Sensu
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Redis
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Sensu Module for processing Redis responses.
         
     | 
| 
      
 7 
     | 
    
         
            +
                # This module calls methods provided by other Sensu Redis modules:
         
     | 
| 
      
 8 
     | 
    
         
            +
                #   Sensu::Redis::Connection.error()
         
     | 
| 
      
 9 
     | 
    
         
            +
                module Processor
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # Fetch the next Redis command response callback. Response
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # callbacks may include an optional response processor block,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # i.e. "1" -> true.
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # @return [Array] processor, callback.
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def fetch_response_callback
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @response_callbacks ||= []
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @response_callbacks.shift
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  # Begin a multi bulk response array for an expected number of
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # responses. Using this method causes `dispatch_response()` to
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # wait until all of the expected responses have been added to
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # the array, before the Redis command reponse callback is
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # called.
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # @param multibulk_count [Integer] number of expected responses.
         
     | 
| 
      
 27 
     | 
    
         
            +
                  def begin_multibulk(multibulk_count)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @multibulk_count = multibulk_count
         
     | 
| 
      
 29 
     | 
    
         
            +
                    @multibulk_values = []
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  # Dispatch a Redis error, dropping the associated Redis command
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # response callback, and passing a Redis error object to the
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # error callback (if set).
         
     | 
| 
      
 35 
     | 
    
         
            +
                  #
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # @param code [String] Redis error code.
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def dispatch_error(code)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    fetch_response_callback
         
     | 
| 
      
 39 
     | 
    
         
            +
                    error(CommandError, code)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  # Dispatch a response. If a multi bulk response has begun, this
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # method will build the completed response array before the
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # associated Redis command response callback is called. If one
         
     | 
| 
      
 45 
     | 
    
         
            +
                  # or more pubsub callbacks are defined, the approprate pubsub
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # callbacks are called, provided with the pubsub response. Redis
         
     | 
| 
      
 47 
     | 
    
         
            +
                  # command response callbacks may have an optional processor
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # block, responsible for producing a value with the correct
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # type, e.g. "1" -> true (boolean).
         
     | 
| 
      
 50 
     | 
    
         
            +
                  #
         
     | 
| 
      
 51 
     | 
    
         
            +
                  # @param value [Object]
         
     | 
| 
      
 52 
     | 
    
         
            +
                  def dispatch_response(value)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    if @multibulk_count
         
     | 
| 
      
 54 
     | 
    
         
            +
                      @multibulk_values << value
         
     | 
| 
      
 55 
     | 
    
         
            +
                      @multibulk_count -= 1
         
     | 
| 
      
 56 
     | 
    
         
            +
                      if @multibulk_count == 0
         
     | 
| 
      
 57 
     | 
    
         
            +
                        value = @multibulk_values
         
     | 
| 
      
 58 
     | 
    
         
            +
                        @multibulk_count = false
         
     | 
| 
      
 59 
     | 
    
         
            +
                      else
         
     | 
| 
      
 60 
     | 
    
         
            +
                        return
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    if @pubsub_callbacks && value.is_a?(Array)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      if PUBSUB_RESPONSES.include?(value[0])
         
     | 
| 
      
 65 
     | 
    
         
            +
                        @pubsub_callbacks[value[1]].each do |block|
         
     | 
| 
      
 66 
     | 
    
         
            +
                          block.call(*value) if block
         
     | 
| 
      
 67 
     | 
    
         
            +
                        end
         
     | 
| 
      
 68 
     | 
    
         
            +
                        return
         
     | 
| 
      
 69 
     | 
    
         
            +
                      end
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
                    processor, block = fetch_response_callback
         
     | 
| 
      
 72 
     | 
    
         
            +
                    if block
         
     | 
| 
      
 73 
     | 
    
         
            +
                      value = processor.call(value) if processor
         
     | 
| 
      
 74 
     | 
    
         
            +
                      block.call(value)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
    
        data/sensu-redis.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Gem::Specification.new do |spec|
         
     | 
| 
      
 4 
     | 
    
         
            +
              spec.name          = "sensu-redis"
         
     | 
| 
      
 5 
     | 
    
         
            +
              spec.version       = "0.1.0"
         
     | 
| 
      
 6 
     | 
    
         
            +
              spec.authors       = ["Sean Porter"]
         
     | 
| 
      
 7 
     | 
    
         
            +
              spec.email         = ["portertech@gmail.com"]
         
     | 
| 
      
 8 
     | 
    
         
            +
              spec.summary       = "The Sensu Redis client library"
         
     | 
| 
      
 9 
     | 
    
         
            +
              spec.description   = "The Sensu Redis client library"
         
     | 
| 
      
 10 
     | 
    
         
            +
              spec.homepage      = "https://github.com/sensu/sensu-redis"
         
     | 
| 
      
 11 
     | 
    
         
            +
              spec.license       = "MIT"
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              spec.files         = `git ls-files -z`.split("\x0")
         
     | 
| 
      
 14 
     | 
    
         
            +
              spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         
     | 
| 
      
 15 
     | 
    
         
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         
     | 
| 
      
 16 
     | 
    
         
            +
              spec.require_paths = ["lib"]
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              spec.add_dependency "eventmachine"
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              spec.add_development_dependency "bundler", "~> 1.6"
         
     | 
| 
      
 21 
     | 
    
         
            +
              spec.add_development_dependency "rake", "10.5.0"
         
     | 
| 
      
 22 
     | 
    
         
            +
              spec.add_development_dependency "rspec"
         
     | 
| 
      
 23 
     | 
    
         
            +
              spec.add_development_dependency "codeclimate-test-reporter" unless RUBY_VERSION < "1.9"
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,131 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: sensu-redis
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Sean Porter
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2016-03-11 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: eventmachine
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 27 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 28 
     | 
    
         
            +
              name: bundler
         
     | 
| 
      
 29 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '1.6'
         
     | 
| 
      
 34 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 35 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 37 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 38 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '1.6'
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 43 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 44 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 45 
     | 
    
         
            +
                - - '='
         
     | 
| 
      
 46 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: 10.5.0
         
     | 
| 
      
 48 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 49 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - '='
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: 10.5.0
         
     | 
| 
      
 55 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 62 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 63 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 64 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 65 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 66 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 67 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 68 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: codeclimate-test-reporter
         
     | 
| 
      
 71 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 72 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 73 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 74 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 75 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 76 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 77 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 78 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 79 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 80 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 81 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 82 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 83 
     | 
    
         
            +
            description: The Sensu Redis client library
         
     | 
| 
      
 84 
     | 
    
         
            +
            email:
         
     | 
| 
      
 85 
     | 
    
         
            +
            - portertech@gmail.com
         
     | 
| 
      
 86 
     | 
    
         
            +
            executables:
         
     | 
| 
      
 87 
     | 
    
         
            +
            - console
         
     | 
| 
      
 88 
     | 
    
         
            +
            - setup
         
     | 
| 
      
 89 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 90 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 91 
     | 
    
         
            +
            files:
         
     | 
| 
      
 92 
     | 
    
         
            +
            - ".gitignore"
         
     | 
| 
      
 93 
     | 
    
         
            +
            - ".travis.yml"
         
     | 
| 
      
 94 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 95 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 96 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 97 
     | 
    
         
            +
            - bin/console
         
     | 
| 
      
 98 
     | 
    
         
            +
            - bin/setup
         
     | 
| 
      
 99 
     | 
    
         
            +
            - lib/sensu/redis.rb
         
     | 
| 
      
 100 
     | 
    
         
            +
            - lib/sensu/redis/commands.rb
         
     | 
| 
      
 101 
     | 
    
         
            +
            - lib/sensu/redis/connection.rb
         
     | 
| 
      
 102 
     | 
    
         
            +
            - lib/sensu/redis/constants.rb
         
     | 
| 
      
 103 
     | 
    
         
            +
            - lib/sensu/redis/errors.rb
         
     | 
| 
      
 104 
     | 
    
         
            +
            - lib/sensu/redis/parser.rb
         
     | 
| 
      
 105 
     | 
    
         
            +
            - lib/sensu/redis/processor.rb
         
     | 
| 
      
 106 
     | 
    
         
            +
            - sensu-redis.gemspec
         
     | 
| 
      
 107 
     | 
    
         
            +
            homepage: https://github.com/sensu/sensu-redis
         
     | 
| 
      
 108 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 109 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 110 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 111 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 112 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 113 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 114 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 115 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 116 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 117 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 118 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 119 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 120 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 121 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 122 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 123 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 124 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 125 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 126 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 127 
     | 
    
         
            +
            rubygems_version: 2.4.5.1
         
     | 
| 
      
 128 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 129 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 130 
     | 
    
         
            +
            summary: The Sensu Redis client library
         
     | 
| 
      
 131 
     | 
    
         
            +
            test_files: []
         
     |