dalli-elasticache-with-timeout 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ee4bcc3e0b25e6151f1250f43fb854558fb73e2b
4
+ data.tar.gz: 07358013afde109fa151bb56d5264bdcac2f8147
5
+ SHA512:
6
+ metadata.gz: 4005310aaa6f86fd121201b26996aeafb273768d71c00e34a4f9472f2b7edab8f6b399605152b7a3acadc02f75010589fc4f1f26a8aead7775b77e892fd5e935
7
+ data.tar.gz: efb8bd9bf2d6ee50ca1a04af09df8269687016ffc07f4d26b001fdacd7ba664d80a6add1720ab1227edc558d295c41b9885969f41a19769865f44191d8457231
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ Dalli ElastiCache [![Gem Version](https://badge.fury.io/rb/dalli-elasticache.svg)](http://badge.fury.io/rb/dalli-elasticache) [![Build Status](https://travis-ci.org/ktheory/dalli-elasticache.svg)](https://travis-ci.org/ktheory/dalli-elasticache) [![Code Climate](https://codeclimate.com/github/ktheory/dalli-elasticache.png)](https://codeclimate.com/github/ktheory/dalli-elasticache)
2
+ =================
3
+
4
+ Use [AWS ElastiCache AutoDiscovery](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/AutoDiscovery.html) to automatically configure your [Dalli memcached client](https://github.com/mperham/dalli) with all the nodes in your cluster.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ Install the [rubygem](https://rubygems.org/gems/dalli-elasticache):
10
+
11
+ ```ruby
12
+ # in your Gemfile
13
+ gem 'dalli-elasticache'
14
+ ```
15
+
16
+ Setup for Rails 3.x and Newer
17
+ -----------------------------
18
+
19
+ Configure your environment-specific application settings:
20
+
21
+ ```ruby
22
+ # in config/environments/production.rb
23
+ endpoint = "my-cluster-name.abc123.cfg.use1.cache.amazonaws.com:11211"
24
+ elasticache = Dalli::ElastiCache.new(endpoint)
25
+
26
+ config.cache_store = :dalli_store, elasticache.servers, {:expires_in => 1.day, :compress => true}
27
+ ```
28
+
29
+ Note that the ElastiCache server list will be refreshed each time an app server process starts.
30
+
31
+ Client Usage
32
+ ------------
33
+
34
+ Create an ElastiCache instance:
35
+
36
+ ```ruby
37
+ config_endpoint = "aaron-scratch.vfdnac.cfg.use1.cache.amazonaws.com:11211"
38
+
39
+ # Options for configuring the Dalli::Client
40
+ dalli_options = {
41
+ :expires_in => 24 * 60 * 60,
42
+ :namespace => "my_app",
43
+ :compress => true
44
+ }
45
+
46
+ elasticache = Dalli::ElastiCache.new(config_endpoint, dalli_options)
47
+ ```
48
+
49
+ Fetch information about the Memcached nodes:
50
+
51
+ ```ruby
52
+ # Dalli::Client with configuration from the AutoDiscovery endpoint
53
+ elasticache.client
54
+ # => #<Dalli::Client ... @servers=["aaron-scratch.vfdnac.0001.use1.cache.amazonaws.com:11211", ...]>
55
+
56
+ # Node addresses
57
+ elasticache.servers
58
+ # => ["aaron-scratch.vfdnac.0001.use1.cache.amazonaws.com:11211", "aaron-scratch.vfdnac.0002.use1.cache.amazonaws.com:11211"]
59
+
60
+ # Number of times the cluster configuration has changed
61
+ elasticache.version
62
+ # => 12
63
+
64
+ # Memcached version of the cluster
65
+ elasticache.engine_version
66
+ # => "1.4.14"
67
+
68
+ # Refresh data from the endpoint
69
+ elasticache.refresh
70
+
71
+ # Refresh and get client with new configuration
72
+ elasticache.refresh.client
73
+ ```
74
+
75
+ License
76
+ -------
77
+
78
+ Copyright 2013 Aaron Suggs
79
+
80
+ Released under an [MIT License](http://opensource.org/licenses/MIT)
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:test)
7
+
8
+ task :default => :test
@@ -0,0 +1,2 @@
1
+ # Support default bundler require path
2
+ require 'dalli/elasticache'
@@ -0,0 +1,49 @@
1
+ require 'dalli'
2
+ require 'socket'
3
+ require 'dalli/elasticache/version'
4
+ require 'dalli/elasticache/auto_discovery/endpoint'
5
+ require 'dalli/elasticache/auto_discovery/config_response'
6
+ require 'dalli/elasticache/auto_discovery/stats_response'
7
+
8
+ module Dalli
9
+ class ElastiCache
10
+ attr_reader :endpoint, :options
11
+
12
+ def initialize(config_endpoint, options={})
13
+ cluster_timeout = (options || {}).delete(:cluster_timeout) || (options || {}).delete('cluster_timeout')
14
+ @endpoint = Dalli::Elasticache::AutoDiscovery::Endpoint.new(config_endpoint, cluster_timeout)
15
+ @options = options
16
+ end
17
+
18
+ # Dalli::Client configured to connect to the cluster's nodes
19
+ def client
20
+ Dalli::Client.new(servers, options)
21
+ end
22
+
23
+ # The number of times the cluster configuration has been changed
24
+ #
25
+ # Returns an integer
26
+ def version
27
+ endpoint.config.version
28
+ end
29
+
30
+ # The cache engine version of the cluster
31
+ def engine_version
32
+ endpoint.engine_version
33
+ end
34
+
35
+ # List of cluster server nodes with ip addresses and ports
36
+ # Always use host name instead of private elasticache IPs as internal IPs can change after a node is rebooted
37
+ def servers
38
+ endpoint.config.nodes.map{ |h| "#{h[:host]}:#{h[:port]}" }
39
+ end
40
+
41
+ # Clear all cached data from the cluster endpoint
42
+ def refresh
43
+ config_endpoint = "#{endpoint.host}:#{endpoint.port}"
44
+ @endpoint = Dalli::Elasticache::AutoDiscovery::Endpoint.new(config_endpoint, endpoint.timeout)
45
+
46
+ self
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,49 @@
1
+ module Dalli
2
+ module Elasticache
3
+ module AutoDiscovery
4
+
5
+ # This class wraps the raw ASCII response from an Auto Discovery endpoint
6
+ # and provides methods for extracting data from that response.
7
+ #
8
+ # http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/AutoDiscovery.AddingToYourClientLibrary.html
9
+
10
+ class ConfigResponse
11
+
12
+ # The raw response text
13
+ attr_reader :text
14
+
15
+ # Matches the version line of the response
16
+ VERSION_REGEX = /^(\d+)$/
17
+
18
+ # Matches strings like "my-cluster.001.cache.aws.com|10.154.182.29|11211"
19
+ NODE_REGEX = /(([-.a-zA-Z0-9]+)\|(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)\|(\d+))/
20
+ NODE_LIST_REGEX = /^(#{NODE_REGEX}\s*)+$/
21
+
22
+ def initialize(response_text)
23
+ @text = response_text.to_s
24
+ end
25
+
26
+ # The number of times the configuration has been changed
27
+ #
28
+ # Returns an integer
29
+ def version
30
+ VERSION_REGEX.match(@text)[1].to_i
31
+ end
32
+
33
+ # Node hosts, ip addresses, and ports
34
+ #
35
+ # Returns an Array of Hashes with values for :host, :ip and :port
36
+ def nodes
37
+ NODE_LIST_REGEX.match(@text).to_s.scan(NODE_REGEX).map do |match|
38
+ {
39
+ :host => match[1],
40
+ :ip => match[2],
41
+ :port => match[3].to_i
42
+ }
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,128 @@
1
+ module Dalli
2
+ module Elasticache
3
+ module AutoDiscovery
4
+ class Endpoint
5
+ class Timeout < StandardError; end;
6
+
7
+ # Endpoint configuration
8
+ attr_reader :host
9
+ attr_reader :port
10
+ attr_reader :timeout
11
+
12
+ # Matches Strings like "my-host.cache.aws.com:11211"
13
+ ENDPOINT_REGEX = /([-.a-zA-Z0-9]+):(\d+)/
14
+
15
+ STATS_COMMAND = "stats\r\n"
16
+ CONFIG_COMMAND = "config get cluster\r\n"
17
+ # Legacy command for version < 1.4.14
18
+ OLD_CONFIG_COMMAND = "get AmazonElastiCache:cluster\r\n"
19
+
20
+ def initialize(endpoint, timeout)
21
+ ENDPOINT_REGEX.match(endpoint) do |m|
22
+ @host = m[1]
23
+ @port = m[2].to_i
24
+ end
25
+ @timeout = timeout
26
+ end
27
+
28
+ # A cached ElastiCache::StatsResponse
29
+ def stats
30
+ @stats ||= get_stats_from_remote
31
+ end
32
+
33
+ # A cached ElastiCache::ConfigResponse
34
+ def config
35
+ @config ||= get_config_from_remote
36
+ end
37
+
38
+ # The memcached engine version
39
+ def engine_version
40
+ stats.version
41
+ end
42
+
43
+ protected
44
+
45
+ def with_socket(&block)
46
+ TCPSocket.new(config_host, config_port)
47
+ end
48
+
49
+ def get_stats_from_remote
50
+ data = remote_command(STATS_COMMAND)
51
+ StatsResponse.new(data)
52
+ end
53
+
54
+ def get_config_from_remote
55
+ if engine_version < Gem::Version.new("1.4.14")
56
+ data = remote_command(OLD_CONFIG_COMMAND)
57
+ else
58
+ data = remote_command(CONFIG_COMMAND)
59
+ end
60
+ ConfigResponse.new(data)
61
+ end
62
+
63
+ # Send an ASCII command to the endpoint
64
+ #
65
+ # Returns the raw response as a String
66
+ def remote_command(command)
67
+ socket = tcp_socket(@host, @port, @timeout)
68
+ socket.puts command
69
+
70
+ data = ""
71
+ until (line = socket.readline) =~ /END/
72
+ data << line
73
+ end
74
+
75
+ socket.close
76
+ data
77
+ end
78
+
79
+ # Creates and connects a tcp socket with an optional timeout
80
+ #
81
+ # Returns a Socket or TCPSocket instance
82
+ def tcp_socket(host, port, timeout)
83
+ if timeout.nil?
84
+ TCPSocket.new(host, port)
85
+ else
86
+ # Convert the passed host into structures the non-blocking calls
87
+ # can deal with
88
+ addr = Socket.getaddrinfo(host, nil)
89
+ sockaddr = Socket.pack_sockaddr_in(port, addr[0][3])
90
+
91
+ Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0).tap do |socket|
92
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
93
+
94
+ begin
95
+ # Initiate the socket connection in the background. If it doesn't fail
96
+ # immediatelyit will raise an IO::WaitWritable (Errno::EINPROGRESS)
97
+ # indicating the connection is in progress.
98
+ socket.connect_nonblock(sockaddr)
99
+
100
+ rescue IO::WaitWritable
101
+ # IO.select will block until the socket is writable or the timeout
102
+ # is exceeded - whichever comes first.
103
+ if IO.select(nil, [socket], nil, timeout)
104
+ begin
105
+ # Verify there is now a good connection
106
+ socket.connect_nonblock(sockaddr)
107
+ rescue Errno::EISCONN
108
+ return socket
109
+ # Good news everybody, the socket is connected!
110
+ rescue
111
+ # An unexpected exception was raised - the connection is no good.
112
+ socket.close
113
+ raise
114
+ end
115
+ else
116
+ # IO.select returns nil when the socket is not ready before timeout
117
+ # seconds have elapsed
118
+ socket.close
119
+ raise Timeout, "Connection attempt took longer than timeout of #{timeout} seconds"
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,31 @@
1
+ module Dalli
2
+ module Elasticache
3
+ module AutoDiscovery
4
+
5
+ # This class wraps the raw ASCII response from an Auto Discovery endpoint
6
+ # and provides methods for extracting data from that response.
7
+ #
8
+ # http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/AutoDiscovery.AddingToYourClientLibrary.html
9
+
10
+ class StatsResponse
11
+
12
+ # The raw response text
13
+ attr_reader :text
14
+
15
+ # Matches the version line of the response
16
+ VERSION_REGEX = /^STAT version ([0-9.]+)\s*$/
17
+
18
+ def initialize(response_text)
19
+ @text = response_text.to_s
20
+ end
21
+
22
+ # Extract the engine version stat
23
+ #
24
+ # Returns a Gem::Version
25
+ def version
26
+ Gem::Version.new(VERSION_REGEX.match(@text)[1])
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ module Dalli
2
+ class ElastiCache
3
+ VERSION = "0.2.0"
4
+ end
5
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe 'Dalli::Elasticache::AutoDiscovery::ConfigResponse' do
4
+ let :response do
5
+ text = "CONFIG cluster 0 141\r\n12\nmycluster.0001.cache.amazonaws.com|10.112.21.1|11211 mycluster.0002.cache.amazonaws.com|10.112.21.2|11211 mycluster.0003.cache.amazonaws.com|10.112.21.3|11211\n\r\n"
6
+ Dalli::Elasticache::AutoDiscovery::ConfigResponse.new(text)
7
+ end
8
+
9
+ describe '#version' do
10
+ it 'parses version' do
11
+ response.version.should == 12
12
+ end
13
+ end
14
+
15
+ describe '#nodes' do
16
+ it 'parses hosts' do
17
+ response.nodes.map{|s| s[:host]}.should == [
18
+ "mycluster.0001.cache.amazonaws.com",
19
+ "mycluster.0002.cache.amazonaws.com",
20
+ "mycluster.0003.cache.amazonaws.com"
21
+ ]
22
+ end
23
+
24
+ it 'parses ip addresses' do
25
+ response.nodes.map{|s| s[:ip]}.should == ["10.112.21.1", "10.112.21.2", "10.112.21.3"]
26
+ end
27
+
28
+ it 'parses ports' do
29
+ response.nodes.map{|s| s[:port]}.should == [11211, 11211, 11211]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,64 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe 'Dalli::ElastiCache::Endpoint' do
4
+ let(:cache) do
5
+ options = {
6
+ :expires_in => 24*60*60,
7
+ :namespace => "my_app",
8
+ :compress => true,
9
+ :cluster_timeout => 5
10
+ }
11
+ Dalli::ElastiCache.new("my-cluster.cfg.use1.cache.amazonaws.com:11211", options)
12
+ end
13
+
14
+ let(:config_text) { "CONFIG cluster 0 141\r\n12\nmycluster.0001.cache.amazonaws.com|10.112.21.1|11211 mycluster.0002.cache.amazonaws.com|10.112.21.2|11211 mycluster.0003.cache.amazonaws.com|10.112.21.3|11211\n\r\n" }
15
+ let(:response) { Dalli::Elasticache::AutoDiscovery::ConfigResponse.new(config_text) }
16
+
17
+ describe '.new' do
18
+ it 'builds endpoint' do
19
+ cache.endpoint.host.should == "my-cluster.cfg.use1.cache.amazonaws.com"
20
+ cache.endpoint.port.should == 11211
21
+ cache.endpoint.timeout.should == 5
22
+ end
23
+
24
+ it 'stores Dalli options' do
25
+ cache.options[:expires_in].should == 24*60*60
26
+ cache.options[:namespace].should == "my_app"
27
+ cache.options[:compress].should == true
28
+ end
29
+ end
30
+
31
+ describe '#client' do
32
+ it 'builds with node list'
33
+ it 'builds with options'
34
+ end
35
+
36
+ describe '#servers' do
37
+ before { Dalli::Elasticache::AutoDiscovery::Endpoint.any_instance.should_receive(:get_config_from_remote).and_return(response) }
38
+
39
+ it 'lists addresses and ports' do
40
+ cache.servers.should == ["mycluster.0001.cache.amazonaws.com:11211", "mycluster.0002.cache.amazonaws.com:11211", "mycluster.0003.cache.amazonaws.com:11211"]
41
+ end
42
+ end
43
+
44
+ describe '#version' do
45
+ end
46
+
47
+ describe '#engine_version' do
48
+ end
49
+
50
+ describe '#refresh' do
51
+ it 'clears endpoint configuration' do
52
+ stale_endpoint = cache.endpoint
53
+ cache.refresh.endpoint.should_not === stale_endpoint
54
+ end
55
+
56
+ it 'builds endpoint with same configuration' do
57
+ stale_endpoint = cache.endpoint
58
+ cache.refresh
59
+ cache.endpoint.host.should == stale_endpoint.host
60
+ cache.endpoint.port.should == stale_endpoint.port
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe 'Dalli::Elasticache::AutoDiscovery::Endpoint' do
4
+ let(:endpoint) do
5
+ Dalli::Elasticache::AutoDiscovery::Endpoint.new("my-cluster.cfg.use1.cache.amazonaws.com:11211", nil)
6
+ end
7
+
8
+ describe '.new' do
9
+ it 'parses host' do
10
+ endpoint.host.should == "my-cluster.cfg.use1.cache.amazonaws.com"
11
+ end
12
+ it 'parses port' do
13
+ endpoint.port.should == 11211
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ require "bundler/setup"
2
+
3
+ require "dalli/elasticache"
4
+
5
+ RSpec.configure do |config|
6
+ config.expect_with :rspec do |c|
7
+ c.syntax = :should
8
+ end
9
+ config.mock_with :rspec do |c|
10
+ c.syntax = :should
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe 'Dalli::Elasticache::AutoDiscovery::StatsResponse' do
4
+ let :response do
5
+ text = "STAT pid 1\r\nSTAT uptime 68717\r\nSTAT time 1398885375\r\nSTAT version 1.4.14\r\nSTAT libevent 1.4.13-stable\r\nSTAT pointer_size 64\r\nSTAT rusage_user 0.136008\r\nSTAT rusage_system 0.424026\r\nSTAT curr_connections 5\r\nSTAT total_connections 1159\r\nSTAT connection_structures 6\r\nSTAT reserved_fds 5\r\nSTAT cmd_get 0\r\nSTAT cmd_set 0\r\nSTAT cmd_flush 0\r\nSTAT cmd_touch 0\r\nSTAT cmd_config_get 4582\r\nSTAT cmd_config_set 2\r\nSTAT get_hits 0\r\nSTAT get_misses 0\r\nSTAT delete_misses 0\r\nSTAT delete_hits 0\r\nSTAT incr_misses 0\r\nSTAT incr_hits 0\r\nSTAT decr_misses 0\r\nSTAT decr_hits 0\r\nSTAT cas_misses 0\r\nSTAT cas_hits 0\r\nSTAT cas_badval 0\r\nSTAT touch_hits 0\r\nSTAT touch_misses 0\r\nSTAT auth_cmds 0\r\nSTAT auth_errors 0\r\nSTAT bytes_read 189356\r\nSTAT bytes_written 2906615\r\nSTAT limit_maxbytes 209715200\r\nSTAT accepting_conns 1\r\nSTAT listen_disabled_num 0\r\nSTAT threads 1\r\nSTAT conn_yields 0\r\nSTAT curr_config 1\r\nSTAT hash_power_level 16\r\nSTAT hash_bytes 524288\r\nSTAT hash_is_expanding 0\r\nSTAT expired_unfetched 0\r\nSTAT evicted_unfetched 0\r\nSTAT bytes 0\r\nSTAT curr_items 0\r\nSTAT total_items 0\r\nSTAT evictions 0\r\nSTAT reclaimed 0\r\n"
6
+ Dalli::Elasticache::AutoDiscovery::StatsResponse.new(text)
7
+ end
8
+
9
+ describe '#version' do
10
+ it 'parses version' do
11
+ response.version.should == Gem::Version.new("1.4.14")
12
+ end
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dalli-elasticache-with-timeout
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Suggs
8
+ - Zach Millman
9
+ - Misha Conway
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2017-02-21 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rspec
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: dalli
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 1.0.0
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 1.0.0
57
+ description: |2
58
+ This gem provides an interface for fetching cluster information from an AWS
59
+ ElastiCache AutoDiscovery server and configuring a Dalli client to connect
60
+ to all nodes in the cache cluster.
61
+ email:
62
+ - aaron@ktheory.com
63
+ - zach@magoosh.com
64
+ - mishaAconway@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - README.md
70
+ - Rakefile
71
+ - lib/dalli-elasticache.rb
72
+ - lib/dalli/elasticache.rb
73
+ - lib/dalli/elasticache/auto_discovery/config_response.rb
74
+ - lib/dalli/elasticache/auto_discovery/endpoint.rb
75
+ - lib/dalli/elasticache/auto_discovery/stats_response.rb
76
+ - lib/dalli/elasticache/version.rb
77
+ - spec/config_response_spec.rb
78
+ - spec/elasticache_spec.rb
79
+ - spec/endpoint_spec.rb
80
+ - spec/spec_helper.rb
81
+ - spec/stats_response_spec.rb
82
+ homepage: https://github.com/MishaConway/dalli-elasticache
83
+ licenses:
84
+ - MIT
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options:
88
+ - "--charset=UTF-8"
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: 1.9.2
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 1.3.5
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.6.7
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Configure Dalli clients with ElastiCache's AutoDiscovery
107
+ test_files:
108
+ - spec/config_response_spec.rb
109
+ - spec/elasticache_spec.rb
110
+ - spec/endpoint_spec.rb
111
+ - spec/spec_helper.rb
112
+ - spec/stats_response_spec.rb