sensu-redis 1.6.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c2ae81e88a971e4f2a7e4dd8a4fb8fa5d293d0d9
4
- data.tar.gz: 469995301c9de2f01dbafd4865ba342b6337499d
3
+ metadata.gz: 5bfbf215d8c3a1975203dc6f5c08d65e54ff3167
4
+ data.tar.gz: 9ba122e38b68809b037ddf97a338729a6d8104fc
5
5
  SHA512:
6
- metadata.gz: 3c5493adc40c41ae6e7fc38da259d239bc807e0a56dc835b6c4e4dfaa22b0c034246b057bddc95e4760be6889782f244af99ee1d8cb444695834ee68c691f9ba
7
- data.tar.gz: 0cddcba167fc57f6b6e61f9513034716790a51125d6f957721f9fcda60586fc7937943c67fdd3647c89531b03e3b3e0e1eb7cff3b91e322da2b30627a413fe80
6
+ metadata.gz: 0416a9108788879d8cb8a6f688142a85b87f9c5d5a324c0e8301f823557f3d8994b5e2413719e178ed785579fd7e452de6d3ac3c03e7251f6199eef600081b7f
7
+ data.tar.gz: 84569b024c3cae5f170ddc0e3c5fa39ebff6b838ed7c6952190c54e236534743f159e7b61c753153ded0d6137b835a991166887dd248fad9f6330d314e98866c
data/README.md CHANGED
@@ -2,9 +2,6 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/sensu/sensu-redis.svg?branch=master)](https://travis-ci.org/sensu/sensu-redis)
4
4
 
5
- [![Code Climate](https://codeclimate.com/github/sensu/sensu-redis.png)](https://codeclimate.com/github/sensu/sensu-redis)
6
- [![Code Climate Coverage](https://codeclimate.com/github/sensu/sensu-redis/coverage.png)](https://codeclimate.com/github/sensu/sensu-redis)
7
-
8
5
  ## Installation
9
6
 
10
7
  Add this line to your application's Gemfile:
data/lib/sensu/redis.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "rubygems"
2
+ require "sensu/redis/utilities"
2
3
  require "sensu/redis/client"
3
4
  require "sensu/redis/sentinel"
4
5
  require "eventmachine"
@@ -7,6 +8,15 @@ require "uri"
7
8
  module Sensu
8
9
  module Redis
9
10
  class << self
11
+ include Utilities
12
+
13
+ # Set the Redis logger.
14
+ #
15
+ # @param logger [Object] Redis logger.
16
+ def logger=(logger)
17
+ @logger = logger
18
+ end
19
+
10
20
  # Parse a Redis URL. An argument error exception is thrown if
11
21
  # this method is unable to parse the provided URL string.
12
22
  #
@@ -34,18 +44,35 @@ module Sensu
34
44
  sentinel = Sentinel.new(options)
35
45
  sentinel.resolve do |host, port|
36
46
  redis = EM.connect(host, port, Client, options)
47
+ redis.logger = @logger
37
48
  redis.sentinel = sentinel
38
49
  block.call(redis)
39
50
  end
40
51
  end
41
52
 
42
53
  # Connect to the current Redis master directly, using the
43
- # provided connection options.
54
+ # provided connection options. This method uses `resolve_host()`
55
+ # to first resolve the provided host, if it's not already an IP
56
+ # address. Resolving the hostname upfront guards against lookup
57
+ # failures that would cause the Sensu process to crash. Upfront
58
+ # hostname resolution also allows this Redis library to work
59
+ # with Amazon AWS ElastiCache & where DNS is used as a failover
60
+ # mechanism.
44
61
  #
45
62
  # @param options [Hash]
46
63
  # @yield callback to be called with the redis connection object.
47
64
  def connect_direct(options, &block)
48
- block.call(EM.connect(options[:host], options[:port], Client, options))
65
+ resolve_host(options[:host]) do |ip_address|
66
+ if ip_address.nil?
67
+ EM::Timer.new(1) do
68
+ connect_direct(options, &block)
69
+ end
70
+ else
71
+ redis = EM.connect(ip_address, options[:port], Client, options)
72
+ redis.logger = @logger
73
+ block.call(redis)
74
+ end
75
+ end
49
76
  end
50
77
 
51
78
  # Connect to Redis using the provided connection options.
@@ -1,13 +1,15 @@
1
1
  require "sensu/redis/client/constants"
2
2
  require "sensu/redis/client/errors"
3
+ require "sensu/redis/utilities"
3
4
  require "eventmachine"
4
5
 
5
6
  module Sensu
6
7
  module Redis
7
8
  class Client < EM::Connection
8
9
  include EM::Deferrable
10
+ include Utilities
9
11
 
10
- attr_accessor :sentinel, :auto_reconnect, :reconnect_on_error
12
+ attr_accessor :logger, :sentinel, :auto_reconnect, :reconnect_on_error
11
13
 
12
14
  # Initialize the connection, creating the Redis command methods,
13
15
  # and setting the default connection options and callbacks.
@@ -81,13 +83,28 @@ module Sensu
81
83
 
82
84
  # Reconnect to Redis. The before reconnect callback is first
83
85
  # called if not already reconnecting. This method uses a 1
84
- # second delay before attempting a reconnect.
86
+ # second delay before attempting a reconnect. The method
87
+ # `determine_address()` is used to determine the correct host
88
+ # and port to reconnect to, either via Sentinel (new master) or
89
+ # the previous host and port. This method uses `resolve_host()`
90
+ # to first resolve the determined host, if it's not already an
91
+ # IP address. Resolving the hostname upfront guards against
92
+ # lookup failures that would cause the Sensu process to crash.
93
+ # Upfront hostname resolution also allows this Redis library to
94
+ # work with Amazon AWS ElastiCache & where DNS is used as a
95
+ # failover mechanism.
85
96
  def reconnect!
86
97
  @reconnect_callbacks[:before].call unless @reconnecting
87
98
  @reconnecting = true
88
99
  EM.add_timer(1) do
89
100
  determine_address do |host, port|
90
- reconnect(host, port)
101
+ resolve_host(host) do |ip_address|
102
+ if ip_address.nil?
103
+ reconnect!
104
+ else
105
+ reconnect(ip_address, port)
106
+ end
107
+ end
91
108
  end
92
109
  end
93
110
  end
@@ -55,7 +55,6 @@ module Sensu
55
55
  end
56
56
  end
57
57
 
58
-
59
58
  # Create a Sentinel master resolve timeout, causing the previous
60
59
  # attempt to fail/cancel, while beginning another attempt.
61
60
  #
@@ -0,0 +1,68 @@
1
+ require "ipaddr"
2
+ require "socket"
3
+
4
+ module Sensu
5
+ module Redis
6
+ module Utilities
7
+ # Determine if a host is an IP address (or DNS hostname).
8
+ #
9
+ # @param host [String]
10
+ # @return [TrueClass, FalseClass]
11
+ def ip_address?(host)
12
+ begin
13
+ ip_address = IPAddr.new(host)
14
+ ip_address.ipv4? || ip_address.ipv6?
15
+ rescue IPAddr::InvalidAddressError
16
+ false
17
+ end
18
+ end
19
+
20
+ # Resolve a hostname to an IP address for a host. This method
21
+ # will return `nil` to the provided block when the hostname
22
+ # cannot be resolved to an IP address.
23
+ #
24
+ # @param host [String]
25
+ # @param block [Proc] called with the result of the DNS
26
+ # query (IP address).
27
+ def resolve_hostname(host, &block)
28
+ resolve = Proc.new do
29
+ begin
30
+ info = case RUBY_PLATFORM
31
+ when /linux/
32
+ flags = Socket::AI_NUMERICSERV | Socket::AI_ADDRCONFIG
33
+ Socket.getaddrinfo(host, nil, Socket::AF_UNSPEC, nil, nil, flags)
34
+ else
35
+ Socket.getaddrinfo(host, nil)
36
+ end
37
+ info.first.nil? ? nil : info.first[2]
38
+ rescue => error
39
+ @logger.error("redis connection error", {
40
+ :reason => "unable to resolve hostname",
41
+ :host => host,
42
+ :error => error.to_s
43
+ }) if @logger
44
+ nil
45
+ end
46
+ end
47
+ EM.defer(resolve, block)
48
+ end
49
+
50
+ # Resolve a hostname to an IP address for a host. This method
51
+ # will return the provided host to the provided block if it
52
+ # is already an IP address. This method will return `nil` to the
53
+ # provided block when the hostname cannot be resolved to an
54
+ # IP address.
55
+ #
56
+ # @param host [String]
57
+ # @param block [Proc] called with the result of the DNS
58
+ # query (IP address).
59
+ def resolve_host(host, &block)
60
+ if ip_address?(host)
61
+ yield host
62
+ else
63
+ resolve_hostname(host, &block)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
data/sensu-redis.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "sensu-redis"
5
- spec.version = "1.6.1"
5
+ spec.version = "2.0.0"
6
6
  spec.authors = ["Sean Porter"]
7
7
  spec.email = ["portertech@gmail.com"]
8
8
  spec.summary = "The Sensu Redis client library"
@@ -20,5 +20,4 @@ Gem::Specification.new do |spec|
20
20
  spec.add_development_dependency "bundler", "~> 1.6"
21
21
  spec.add_development_dependency "rake", "10.5.0"
22
22
  spec.add_development_dependency "rspec"
23
- spec.add_development_dependency "codeclimate-test-reporter" unless RUBY_VERSION < "1.9"
24
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu-redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Porter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-12 00:00:00.000000000 Z
11
+ date: 2016-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eventmachine
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
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
69
  description: The Sensu Redis client library
84
70
  email:
85
71
  - portertech@gmail.com
@@ -94,6 +80,7 @@ files:
94
80
  - lib/sensu/redis/client/constants.rb
95
81
  - lib/sensu/redis/client/errors.rb
96
82
  - lib/sensu/redis/sentinel.rb
83
+ - lib/sensu/redis/utilities.rb
97
84
  - sensu-redis.gemspec
98
85
  homepage: https://github.com/sensu/sensu-redis
99
86
  licenses: