em-hiredis-sentinel 0.1.1
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 +24 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +41 -0
- data/Rakefile +2 -0
- data/em-hiredis-sentinel.gemspec +23 -0
- data/examples/getting_started.rb +28 -0
- data/examples/pubsub.rb +21 -0
- data/lib/em-hiredis-sentinel/base_client.rb +139 -0
- data/lib/em-hiredis-sentinel/client.rb +11 -0
- data/lib/em-hiredis-sentinel/pubsub_client.rb +12 -0
- data/lib/em-hiredis-sentinel/version.rb +9 -0
- data/lib/em-hiredis-sentinel.rb +14 -0
- metadata +99 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: c8ccc312f11d82490c468f1f9c1d57b0c6bf5d4b
         | 
| 4 | 
            +
              data.tar.gz: 897d83b49139778d1d4301211299e0f879e4653e
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 9b7a1da78bd352bbb479b38eb896390f19d3737235ef3db6d4cbf6fd1da23a3ea1c54d19889773d5d11ad2bb884596ed8e48cdec0c2bad327bfc9693247a4731
         | 
| 7 | 
            +
              data.tar.gz: a4f59fc33c645c0526979d3b04d80e9325231004b311b0ab475c17816a6daedcc8bc7eac60b236528bdc3ad0e0425edaf8b33e90e3c07d22515d761136b24181
         | 
    
        data/.gitignore
    ADDED
    
    | @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            *.gem
         | 
| 2 | 
            +
            *.rbc
         | 
| 3 | 
            +
            .bundle
         | 
| 4 | 
            +
            .config
         | 
| 5 | 
            +
            .yardoc
         | 
| 6 | 
            +
            Gemfile.lock
         | 
| 7 | 
            +
            InstalledFiles
         | 
| 8 | 
            +
            _yardoc
         | 
| 9 | 
            +
            coverage
         | 
| 10 | 
            +
            doc/
         | 
| 11 | 
            +
            lib/bundler/man
         | 
| 12 | 
            +
            pkg
         | 
| 13 | 
            +
            rdoc
         | 
| 14 | 
            +
            spec/reports
         | 
| 15 | 
            +
            test/tmp
         | 
| 16 | 
            +
            test/version_tmp
         | 
| 17 | 
            +
            tmp
         | 
| 18 | 
            +
            *.bundle
         | 
| 19 | 
            +
            *.so
         | 
| 20 | 
            +
            *.o
         | 
| 21 | 
            +
            *.a
         | 
| 22 | 
            +
            mkmf.log
         | 
| 23 | 
            +
            .idea/
         | 
| 24 | 
            +
            *.log
         | 
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            Copyright (c) 2014 Justin Schneck
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            MIT License
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining
         | 
| 6 | 
            +
            a copy of this software and associated documentation files (the
         | 
| 7 | 
            +
            "Software"), to deal in the Software without restriction, including
         | 
| 8 | 
            +
            without limitation the rights to use, copy, modify, merge, publish,
         | 
| 9 | 
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 10 | 
            +
            permit persons to whom the Software is furnished to do so, subject to
         | 
| 11 | 
            +
            the following conditions:
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            The above copyright notice and this permission notice shall be
         | 
| 14 | 
            +
            included in all copies or substantial portions of the Software.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 17 | 
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 18 | 
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 19 | 
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 20 | 
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 21 | 
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 22 | 
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            # Em::Hiredis::Sentinel
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Sentinel Support for em-hiredis. Currently this gem does not fully monkey patch the em-hiredis gem in place.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ## Installation
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Add this line to your application's Gemfile:
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                gem 'em-hiredis-sentinel'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            And then execute:
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                $ bundle
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            Or install it yourself as:
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                $ gem install em-hiredis-sentinel
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ## Usage
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                require 'em-hiredis-sentinel'
         | 
| 22 | 
            +
                redis_sentinel = EM::Hiredis::Client.new('127.0.0.1',6379,nil,nil,
         | 
| 23 | 
            +
                                                            :sentinels => [
         | 
| 24 | 
            +
                                                                {:host => '127.0.0.1', :port => 26379},
         | 
| 25 | 
            +
                                                                {:host => '127.0.0.1', :port => 26380},
         | 
| 26 | 
            +
                                                                {:host => '127.0.0.1', :port => 26381}
         | 
| 27 | 
            +
                                                            ],
         | 
| 28 | 
            +
                                                            :master_name => 'mymaster').connect
         | 
| 29 | 
            +
             | 
| 30 | 
            +
             | 
| 31 | 
            +
            ## Contributing
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            1. Fork it ( https://github.com/[my-github-username]/em-hiredis-sentinel/fork )
         | 
| 34 | 
            +
            2. Create your feature branch (`git checkout -b my-new-feature`)
         | 
| 35 | 
            +
            3. Commit your changes (`git commit -am 'Add some feature'`)
         | 
| 36 | 
            +
            4. Push to the branch (`git push origin my-new-feature`)
         | 
| 37 | 
            +
            5. Create a new Pull Request
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            ## TODO
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            1. Add RSpec tests
         | 
    
        data/Rakefile
    ADDED
    
    
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
            require 'em-hiredis-sentinel/version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |spec|
         | 
| 7 | 
            +
              spec.name          = "em-hiredis-sentinel"
         | 
| 8 | 
            +
              spec.version       = EventMachine::Hiredis::Sentinel::VERSION
         | 
| 9 | 
            +
              spec.authors       = ["Justin Schneck"]
         | 
| 10 | 
            +
              spec.email         = ["jschneck@mac.com"]
         | 
| 11 | 
            +
              spec.summary       = %q{Redis Sentinel for em-hiredis}
         | 
| 12 | 
            +
              spec.description   = %q{}
         | 
| 13 | 
            +
              spec.homepage      = ""
         | 
| 14 | 
            +
              spec.license       = "MIT"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              spec.files         = `git ls-files -z`.split("\x0")
         | 
| 17 | 
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 18 | 
            +
              spec.require_paths = ["lib"]
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              spec.add_development_dependency "bundler", "~> 1.6"
         | 
| 21 | 
            +
              spec.add_development_dependency "rake"
         | 
| 22 | 
            +
              spec.add_dependency 'em-hiredis'
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            $:.unshift(File.expand_path('../../lib', __FILE__))
         | 
| 2 | 
            +
            require 'em-hiredis-sentinel'
         | 
| 3 | 
            +
            require 'logger'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            EM.run {
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              EM::Hiredis.logger = Logger.new('output.log')
         | 
| 8 | 
            +
             | 
| 9 | 
            +
             | 
| 10 | 
            +
              redis_sentinel = EM::Hiredis::Client.new('127.0.0.1',6379,nil,nil,
         | 
| 11 | 
            +
                                                            :sentinels => [
         | 
| 12 | 
            +
                                                                {:host => '127.0.0.1', :port => 26379},
         | 
| 13 | 
            +
                                                                {:host => '127.0.0.1', :port => 26380},
         | 
| 14 | 
            +
                                                                {:host => '127.0.0.1', :port => 26381}
         | 
| 15 | 
            +
                                                            ],
         | 
| 16 | 
            +
                                                            :master_name => 'mymaster').connect
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              EM.add_periodic_timer(1) {
         | 
| 19 | 
            +
                puts "Connected: #{redis_sentinel.connected?}"
         | 
| 20 | 
            +
                response_deferrable = redis_sentinel.get('foo')
         | 
| 21 | 
            +
                response_deferrable.callback { |value|
         | 
| 22 | 
            +
                  puts value
         | 
| 23 | 
            +
                }
         | 
| 24 | 
            +
                response_deferrable.errback { |e|
         | 
| 25 | 
            +
                  puts e
         | 
| 26 | 
            +
                }
         | 
| 27 | 
            +
              }
         | 
| 28 | 
            +
            }
         | 
    
        data/examples/pubsub.rb
    ADDED
    
    | @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            $:.unshift(File.expand_path('../../lib', __FILE__))
         | 
| 2 | 
            +
            require 'em-hiredis-sentinel'
         | 
| 3 | 
            +
            require 'logger'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            EM.run {
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              EM::Hiredis.logger = Logger.new('output.log')
         | 
| 8 | 
            +
             | 
| 9 | 
            +
             | 
| 10 | 
            +
              redis_sentinel = EM::Hiredis::Client.new('127.0.0.1',6379,nil,nil,
         | 
| 11 | 
            +
                                                            :sentinels => [
         | 
| 12 | 
            +
                                                                {:host => '127.0.0.1', :port => 26379},
         | 
| 13 | 
            +
                                                                {:host => '127.0.0.1', :port => 26380},
         | 
| 14 | 
            +
                                                                {:host => '127.0.0.1', :port => 26381}
         | 
| 15 | 
            +
                                                            ],
         | 
| 16 | 
            +
                                                            :master_name => 'mymaster').connect
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              redis_sentinel.pubsub.subscribe('foo') { |msg|
         | 
| 19 | 
            +
                puts msg
         | 
| 20 | 
            +
              }
         | 
| 21 | 
            +
            }
         | 
| @@ -0,0 +1,139 @@ | |
| 1 | 
            +
            module EventMachine::Hiredis
         | 
| 2 | 
            +
              class BaseClient
         | 
| 3 | 
            +
                class_eval {
         | 
| 4 | 
            +
                  attr_reader :sentinel_options
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def initialize_with_sentinel(host = 'localhost', port = 6379, password = nil, db = nil, sentinel_options={})
         | 
| 7 | 
            +
                    #@options = sentinel_options.dup
         | 
| 8 | 
            +
                    puts "SentinelOptions: #{sentinel_options}"
         | 
| 9 | 
            +
                    initialize_without_sentinel(host,port,password,db)
         | 
| 10 | 
            +
                    if sentinel_options.nil? || sentinel_options.empty?
         | 
| 11 | 
            +
                      return
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    @sentinel_options = sentinel_options.dup
         | 
| 15 | 
            +
                    @master_name = @sentinel_options[:master_name]
         | 
| 16 | 
            +
                    @sentinels_options = _parse_sentinel_options(@sentinel_options[:sentinels])
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    @current_sentinel = EM::Hiredis::Client.new(@sentinels_options[0][:host],@sentinels_options[0][:port]).connect
         | 
| 19 | 
            +
                    @current_sentinel.on(:disconnected) {
         | 
| 20 | 
            +
                      EM::Hiredis.logger.info('Sentinel Failed')
         | 
| 21 | 
            +
                      try_next_sentinel
         | 
| 22 | 
            +
                    }
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    #discover_master
         | 
| 25 | 
            +
                    watch_sentinel
         | 
| 26 | 
            +
                    
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  alias initialize_without_sentinel initialize
         | 
| 30 | 
            +
                  alias initialize initialize_with_sentinel
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def watch_sentinel
         | 
| 33 | 
            +
                    pubsub = @current_sentinel.pubsub
         | 
| 34 | 
            +
                    pubsub.punsubscribe('*')
         | 
| 35 | 
            +
                    pubsub.psubscribe('*')
         | 
| 36 | 
            +
                    pubsub.on(:pmessage) { |pattern, channel, message|
         | 
| 37 | 
            +
                      puts "Channel:#{channel}"
         | 
| 38 | 
            +
                      puts "Message:#{message}"
         | 
| 39 | 
            +
                      next if channel != '+switch-master'
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                      master_name, old_host, old_port, new_host, new_port = message.split(" ")
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                      next if master_name != @master_name
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      #@options.merge!(host: new_host, port: new_port.to_i)
         | 
| 46 | 
            +
                      EM::Hiredis.logger.info("Failover: #{old_host}:#{old_port} => #{new_host}:#{new_port}")
         | 
| 47 | 
            +
                      close_connection
         | 
| 48 | 
            +
                      @host, @port = new_host,new_port.to_i
         | 
| 49 | 
            +
                      reconnect_connection
         | 
| 50 | 
            +
                    }
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  def try_next_sentinel
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    sentinel_options = @sentinels_options.shift
         | 
| 56 | 
            +
                    @sentinels_options.push sentinel_options
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    puts "Trying next sentinel: #{sentinel_options[:host]}:#{sentinel_options[:port]}" #if @logger && @logger.debug?
         | 
| 59 | 
            +
                    @current_sentinel.close_connection
         | 
| 60 | 
            +
                    @current_sentinel.configure("redis://#{sentinel_options[:host]}:#{sentinel_options[:port]}")
         | 
| 61 | 
            +
                    @current_sentinel.reconnect_connection
         | 
| 62 | 
            +
                    unless @switching_sentinels
         | 
| 63 | 
            +
                      @switching_sentinels = true
         | 
| 64 | 
            +
                      @sentinel_timer = EM.add_periodic_timer(1) {
         | 
| 65 | 
            +
                        puts 'Trying New Sentinel Connection'
         | 
| 66 | 
            +
                        if @current_sentinel.connected?
         | 
| 67 | 
            +
                          @switching_sentinels = false
         | 
| 68 | 
            +
                          @sentinel_timer.cancel
         | 
| 69 | 
            +
                          #watch_sentinel
         | 
| 70 | 
            +
                        else
         | 
| 71 | 
            +
                          try_next_sentinel
         | 
| 72 | 
            +
                        end
         | 
| 73 | 
            +
                      }
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  def discover_master
         | 
| 78 | 
            +
                    response_deferrable = @current_sentinel.sentinel("get-master-addr-by-name", @master_name)
         | 
| 79 | 
            +
                    response_deferrable.callback { |value|
         | 
| 80 | 
            +
                      master_host, master_port = value
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                      if master_host && master_port
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                        # An ip:port pair
         | 
| 85 | 
            +
                        #@options.merge!(:host => master_host, :port => master_port.to_i, :password => @master_password)
         | 
| 86 | 
            +
                        #close_connection
         | 
| 87 | 
            +
                        @host, @port = master_host,master_port.to_i
         | 
| 88 | 
            +
                        reconnect_connection
         | 
| 89 | 
            +
                        refresh_sentinels_list
         | 
| 90 | 
            +
                      else
         | 
| 91 | 
            +
                        EM.next_tick {
         | 
| 92 | 
            +
                          self.discover_master
         | 
| 93 | 
            +
                        }
         | 
| 94 | 
            +
                      end
         | 
| 95 | 
            +
                    }
         | 
| 96 | 
            +
                    response_deferrable.errback { |e|
         | 
| 97 | 
            +
                      EM.next_tick {
         | 
| 98 | 
            +
                        self.discover_master
         | 
| 99 | 
            +
                      }
         | 
| 100 | 
            +
                    }
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  def refresh_sentinels_list
         | 
| 104 | 
            +
                    response_deferrable = @current_sentinel.sentinel("sentinels", @master_name)
         | 
| 105 | 
            +
                    response_deferrable.callback { |sentinels|
         | 
| 106 | 
            +
                      sentinels.each { |sentinel|
         | 
| 107 | 
            +
                        @sentinels_options << {:host => sentinel[3], :port => sentinel[5]}
         | 
| 108 | 
            +
                        @sentinels_options.uniq! {|h| h.values_at(:host, :port) }
         | 
| 109 | 
            +
                      }
         | 
| 110 | 
            +
                    }
         | 
| 111 | 
            +
                    response_deferrable.errback { |e|
         | 
| 112 | 
            +
                      try_next_sentinel
         | 
| 113 | 
            +
                    }
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                  private
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  def _parse_sentinel_options(options)
         | 
| 119 | 
            +
                    return if options.nil?
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                    sentinel_options = []
         | 
| 122 | 
            +
                    options.each do |opts|
         | 
| 123 | 
            +
                      opts = opts[:url] if opts.is_a?(Hash) && opts.key?(:url)
         | 
| 124 | 
            +
                      case opts
         | 
| 125 | 
            +
                        when Hash
         | 
| 126 | 
            +
                          sentinel_options << opts
         | 
| 127 | 
            +
                        else
         | 
| 128 | 
            +
                          uri = URI.parse(opts)
         | 
| 129 | 
            +
                          sentinel_options << {
         | 
| 130 | 
            +
                              :host => uri.host,
         | 
| 131 | 
            +
                              :port => uri.port
         | 
| 132 | 
            +
                          }
         | 
| 133 | 
            +
                      end
         | 
| 134 | 
            +
                    end
         | 
| 135 | 
            +
                    sentinel_options
         | 
| 136 | 
            +
                  end
         | 
| 137 | 
            +
                }    
         | 
| 138 | 
            +
              end
         | 
| 139 | 
            +
            end
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            module EventMachine::Hiredis
         | 
| 2 | 
            +
              class PubsubClient < BaseClient
         | 
| 3 | 
            +
                class_eval {
         | 
| 4 | 
            +
                  def initialize(host='localhost', port='6379', password=nil, db=nil, sentinel_options={})
         | 
| 5 | 
            +
                    puts "Initializing with sentinel: #{sentinel_options}"
         | 
| 6 | 
            +
                    @subs, @psubs = [], []
         | 
| 7 | 
            +
                    @pubsub_defs = Hash.new { |h,k| h[k] = [] }
         | 
| 8 | 
            +
                    super
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                }
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            require 'em-hiredis'
         | 
| 2 | 
            +
            require 'em-hiredis-sentinel/client'
         | 
| 3 | 
            +
            require 'em-hiredis-sentinel/base_client'
         | 
| 4 | 
            +
            require 'em-hiredis-sentinel/pubsub_client'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module EventMachine::Hiredis
         | 
| 7 | 
            +
              class_eval {
         | 
| 8 | 
            +
                def self.connect_sentinel(options={})
         | 
| 9 | 
            +
                  # Should Return an EM-Hiredis client with added sentinel support
         | 
| 10 | 
            +
                  sentinel_client = EM::Hiredis::Sentinel::Client.new options
         | 
| 11 | 
            +
                  sentinel_client.redis_client
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              }
         | 
| 14 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,99 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: em-hiredis-sentinel
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.1.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Justin Schneck
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2014-06-10 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: bundler
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '1.6'
         | 
| 20 | 
            +
              type: :development
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - "~>"
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '1.6'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: rake
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - ">="
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '0'
         | 
| 34 | 
            +
              type: :development
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - ">="
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: em-hiredis
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - ">="
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '0'
         | 
| 48 | 
            +
              type: :runtime
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - ">="
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '0'
         | 
| 55 | 
            +
            description: ''
         | 
| 56 | 
            +
            email:
         | 
| 57 | 
            +
            - jschneck@mac.com
         | 
| 58 | 
            +
            executables: []
         | 
| 59 | 
            +
            extensions: []
         | 
| 60 | 
            +
            extra_rdoc_files: []
         | 
| 61 | 
            +
            files:
         | 
| 62 | 
            +
            - ".gitignore"
         | 
| 63 | 
            +
            - Gemfile
         | 
| 64 | 
            +
            - LICENSE.txt
         | 
| 65 | 
            +
            - README.md
         | 
| 66 | 
            +
            - Rakefile
         | 
| 67 | 
            +
            - em-hiredis-sentinel.gemspec
         | 
| 68 | 
            +
            - examples/getting_started.rb
         | 
| 69 | 
            +
            - examples/pubsub.rb
         | 
| 70 | 
            +
            - lib/em-hiredis-sentinel.rb
         | 
| 71 | 
            +
            - lib/em-hiredis-sentinel/base_client.rb
         | 
| 72 | 
            +
            - lib/em-hiredis-sentinel/client.rb
         | 
| 73 | 
            +
            - lib/em-hiredis-sentinel/pubsub_client.rb
         | 
| 74 | 
            +
            - lib/em-hiredis-sentinel/version.rb
         | 
| 75 | 
            +
            homepage: ''
         | 
| 76 | 
            +
            licenses:
         | 
| 77 | 
            +
            - MIT
         | 
| 78 | 
            +
            metadata: {}
         | 
| 79 | 
            +
            post_install_message: 
         | 
| 80 | 
            +
            rdoc_options: []
         | 
| 81 | 
            +
            require_paths:
         | 
| 82 | 
            +
            - lib
         | 
| 83 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 84 | 
            +
              requirements:
         | 
| 85 | 
            +
              - - ">="
         | 
| 86 | 
            +
                - !ruby/object:Gem::Version
         | 
| 87 | 
            +
                  version: '0'
         | 
| 88 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 89 | 
            +
              requirements:
         | 
| 90 | 
            +
              - - ">="
         | 
| 91 | 
            +
                - !ruby/object:Gem::Version
         | 
| 92 | 
            +
                  version: '0'
         | 
| 93 | 
            +
            requirements: []
         | 
| 94 | 
            +
            rubyforge_project: 
         | 
| 95 | 
            +
            rubygems_version: 2.2.2
         | 
| 96 | 
            +
            signing_key: 
         | 
| 97 | 
            +
            specification_version: 4
         | 
| 98 | 
            +
            summary: Redis Sentinel for em-hiredis
         | 
| 99 | 
            +
            test_files: []
         |