dalli-elasticache 0.1.1 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/README.md +36 -21
- data/Rakefile +7 -4
- data/lib/dalli/elasticache/auto_discovery/base_command.rb +42 -0
- data/lib/dalli/elasticache/auto_discovery/config_command.rb +45 -0
- data/lib/dalli/elasticache/auto_discovery/config_response.rb +15 -18
- data/lib/dalli/elasticache/auto_discovery/endpoint.rb +28 -59
- data/lib/dalli/elasticache/auto_discovery/node.rb +39 -0
- data/lib/dalli/elasticache/auto_discovery/stats_command.rb +23 -0
- data/lib/dalli/elasticache/auto_discovery/stats_response.rb +15 -12
- data/lib/dalli/elasticache/version.rb +3 -1
- data/lib/dalli/elasticache.rb +42 -14
- data/lib/dalli-elasticache.rb +3 -1
- data/spec/config_command_spec.rb +101 -0
- data/spec/config_response_spec.rb +15 -11
- data/spec/elasticache_spec.rb +106 -23
- data/spec/endpoint_spec.rb +77 -6
- data/spec/node_spec.rb +82 -0
- data/spec/spec_helper.rb +7 -10
- data/spec/stats_command_spec.rb +90 -0
- data/spec/stats_response_spec.rb +111 -8
- metadata +115 -29
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YzM4Y2E3ZjlhMzA3M2NjYTc0NjZjZTU1MzA4Y2UwODM1YmZjMjNmYw==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 050e21a65939176f89e224e1cd7240051fcfec434fb8f048b8a00d17e70a175f
|
4
|
+
data.tar.gz: 77f1c0ff3f43bb6eff10de21005c56a36f161524408567313e40c56f94e09d85
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
N2E5ZWJhZmRkYTBmYTg1Zjg3NmQ2N2Q1YjUyZTBlN2E1ZWYxMDFmMmI4MTM1
|
11
|
-
ZWM5ZmY0OTkzMDU2MmI4NGZiODFmY2QzNmZhMWEzY2MxZWIzZjk=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZjVlMmMyMzI3ODhlMDFiMTc4NTQzMjc5ZDkyYjFlMGRmOGIwNGYxYTc5OTUw
|
14
|
-
YTk2YWE1MmFmMmViODZkM2UwMTliMTdhYWM2ZDRhMjljOGJkZmQ5OTc3NzAy
|
15
|
-
NzIyMzI5NWY1YWFmY2M5ODMwYzIzN2UzNmFhMjRiMTkwYjUwMDQ=
|
6
|
+
metadata.gz: 1ced0146220de8f94e8b97cbb6fcde53a5ddd3335716482b9b84feadae020d8054f4e18c63bed9dcac60b41fcca6e68e8b8ea007a2192f6985714136324c5e49
|
7
|
+
data.tar.gz: 0d9aced1a50c272e9974d8b1d9e4da6628409235317d46f0af5fd7db9e1b86ce3a7c07ebcbe389a80c646bf6d557dd896257af70d269ac807445f6c370b93379
|
data/README.md
CHANGED
@@ -1,46 +1,63 @@
|
|
1
|
-
Dalli ElastiCache [![Gem Version](https://badge.fury.io/rb/dalli-elasticache.svg)](http://badge.fury.io/rb/dalli-elasticache) [![Build Status](https://
|
1
|
+
Dalli ElastiCache [![Gem Version](https://badge.fury.io/rb/dalli-elasticache.svg)](http://badge.fury.io/rb/dalli-elasticache) [![Build Status](https://github.com/ktheory/dalli-elasticache/actions/workflows/tests.yml/badge.svg)](https://github.com/ktheory/dalli-elasticache/actions/workflows/tests.yml) [![Code Climate](https://codeclimate.com/github/ktheory/dalli-elasticache.png)](https://codeclimate.com/github/ktheory/dalli-elasticache)
|
2
2
|
=================
|
3
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/
|
4
|
+
Use [AWS ElastiCache AutoDiscovery](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/AutoDiscovery.html) or [Google Cloud MemoryStore Auto Discovery](https://cloud.google.com/memorystore/docs/memcached/using-auto-discovery) to automatically configure your [Dalli memcached client](https://github.com/petergoldstein/dalli) with all the nodes in your cluster.
|
5
5
|
|
6
6
|
Installation
|
7
7
|
------------
|
8
8
|
|
9
|
-
Install the [
|
9
|
+
Install the [gem](https://rubygems.org/gems/dalli-elasticache):
|
10
10
|
|
11
11
|
```ruby
|
12
12
|
# in your Gemfile
|
13
13
|
gem 'dalli-elasticache'
|
14
14
|
```
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
Using Dalli Elasticache in Rails
|
17
|
+
---------------------------------
|
18
18
|
|
19
|
-
|
19
|
+
Note that the list of memcached servers used by Rails will be refreshed each time an app server process starts. If the list of nodes in your cluster changes, this configuration will not be reflected in the Rails configuraiton without such a server process restart.
|
20
|
+
|
21
|
+
### Configuring a Cache Store
|
22
|
+
|
23
|
+
The most common use of Dalli in Rails is to support a cache store. To set up your cache store with a cluster, you'll need to generate the list of servers with Dalli ElastiCache and pass them to the `cache_store` configuration. This needs to be done in your `config/environments/RAILS_ENV.rb` file for each Rails environment where you want to use a cluster.
|
20
24
|
|
21
25
|
```ruby
|
22
26
|
# in config/environments/production.rb
|
23
|
-
|
24
|
-
elasticache
|
27
|
+
endpoint = "my-cluster-name.abc123.cfg.use1.cache.amazonaws.com:11211"
|
28
|
+
elasticache = Dalli::ElastiCache.new(endpoint)
|
25
29
|
|
26
|
-
config.cache_store = :
|
30
|
+
config.cache_store = :mem_cache_store, elasticache.servers, { expires_in: 1.day }
|
27
31
|
```
|
32
|
+
### Configuring a Session Store
|
33
|
+
|
34
|
+
Another use of Dalli in Rails is to support a Rails session store. Dalli ElastiCache can also be used in this case. The usage is very similar - first use Dalli ElastiCache to generate the list of servers, and then pass that result to the Rails configuration. In `config/application.rb` you would write:
|
28
35
|
|
29
|
-
|
36
|
+
```ruby
|
37
|
+
# in config/environments/production.rb
|
38
|
+
endpoint = "my-cluster-name.abc123.cfg.use1.cache.amazonaws.com:11211"
|
39
|
+
elasticache = Dalli::ElastiCache.new(endpoint)
|
30
40
|
|
31
|
-
|
41
|
+
config.session_store = :mem_cache_store, memcache_server: elasticache.servers, pool_size: 10, pool_timeout: 5, expire_after: 1.day
|
42
|
+
```
|
43
|
+
|
44
|
+
### Dalli Considerations
|
45
|
+
|
46
|
+
Please see [here](https://github.com/petergoldstein/dalli/wiki/Using-Dalli-with-Rails) for more information on configuring Dalli and Rails.
|
47
|
+
|
48
|
+
|
49
|
+
Using Dalli ElastiCache with a Dalli Client
|
32
50
|
------------
|
33
51
|
|
34
|
-
|
52
|
+
To initialize a Dalli Client the is configured for all the nodes of a cluster, one simply needs to pass the configuration endpoint and any options for the Dalli Client into the `Dalli::ElastiCache` initializer. Then one can use the methods on the `Dalli::ElastiCache` object to generate an appropriately configured `Dalli::Client`or to get information about the cluster.
|
35
53
|
|
36
54
|
```ruby
|
37
55
|
config_endpoint = "aaron-scratch.vfdnac.cfg.use1.cache.amazonaws.com:11211"
|
38
56
|
|
39
57
|
# Options for configuring the Dalli::Client
|
40
58
|
dalli_options = {
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:compress => true
|
59
|
+
expires_in: 24 * 60 * 60,
|
60
|
+
namespace: "my_app"
|
44
61
|
}
|
45
62
|
|
46
63
|
elasticache = Dalli::ElastiCache.new(config_endpoint, dalli_options)
|
@@ -51,11 +68,11 @@ Fetch information about the Memcached nodes:
|
|
51
68
|
```ruby
|
52
69
|
# Dalli::Client with configuration from the AutoDiscovery endpoint
|
53
70
|
elasticache.client
|
54
|
-
# => #<Dalli::Client ... @servers=["
|
71
|
+
# => #<Dalli::Client ... @servers=["aaron-scratch.vfdnac.0001.use1.cache.amazonaws.com:11211", ...]>
|
55
72
|
|
56
|
-
# Node
|
73
|
+
# Node addresses
|
57
74
|
elasticache.servers
|
58
|
-
# => ["
|
75
|
+
# => ["aaron-scratch.vfdnac.0001.use1.cache.amazonaws.com:11211", "aaron-scratch.vfdnac.0002.use1.cache.amazonaws.com:11211"]
|
59
76
|
|
60
77
|
# Number of times the cluster configuration has changed
|
61
78
|
elasticache.version
|
@@ -75,6 +92,4 @@ elasticache.refresh.client
|
|
75
92
|
License
|
76
93
|
-------
|
77
94
|
|
78
|
-
Copyright
|
79
|
-
|
80
|
-
Released under an [MIT License](http://opensource.org/licenses/MIT)
|
95
|
+
Copyright (2017-2022) Aaron Suggs, Peter M. Goldstein. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'bundler/gem_tasks'
|
6
|
+
require 'rspec/core/rake_task'
|
4
7
|
|
5
8
|
RSpec::Core::RakeTask.new(:test)
|
6
9
|
|
7
|
-
task :
|
10
|
+
task default: :test
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dalli
|
4
|
+
module Elasticache
|
5
|
+
module AutoDiscovery
|
6
|
+
##
|
7
|
+
# Base command class for configuration endpoint
|
8
|
+
# command. Contains the network logic.
|
9
|
+
##
|
10
|
+
class BaseCommand
|
11
|
+
attr_reader :host, :port
|
12
|
+
|
13
|
+
def initialize(host, port)
|
14
|
+
@host = host
|
15
|
+
@port = port
|
16
|
+
end
|
17
|
+
|
18
|
+
# Send an ASCII command to the endpoint
|
19
|
+
#
|
20
|
+
# Returns the raw response as a String
|
21
|
+
def send_command
|
22
|
+
socket = TCPSocket.new(@host, @port)
|
23
|
+
begin
|
24
|
+
socket.puts command
|
25
|
+
response_from_socket(socket)
|
26
|
+
ensure
|
27
|
+
socket.close
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def response_from_socket(socket)
|
32
|
+
data = +''
|
33
|
+
until (line = socket.readline).include?('END')
|
34
|
+
data << line
|
35
|
+
end
|
36
|
+
|
37
|
+
data
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dalli
|
4
|
+
module Elasticache
|
5
|
+
module AutoDiscovery
|
6
|
+
##
|
7
|
+
# Encapsulates execution of the 'config' command, which is used to
|
8
|
+
# extract the list of nodes and determine if that list of nodes has changed.
|
9
|
+
##
|
10
|
+
class ConfigCommand < BaseCommand
|
11
|
+
attr_reader :engine_version
|
12
|
+
|
13
|
+
CONFIG_COMMAND = "config get cluster\r\n"
|
14
|
+
|
15
|
+
# Legacy command for version < 1.4.14
|
16
|
+
LEGACY_CONFIG_COMMAND = "get AmazonElastiCache:cluster\r\n"
|
17
|
+
|
18
|
+
def initialize(host, port, engine_version)
|
19
|
+
super(host, port)
|
20
|
+
@engine_version = engine_version
|
21
|
+
end
|
22
|
+
|
23
|
+
def response
|
24
|
+
ConfigResponse.new(send_command)
|
25
|
+
end
|
26
|
+
|
27
|
+
def command
|
28
|
+
return LEGACY_CONFIG_COMMAND if legacy_config?
|
29
|
+
|
30
|
+
CONFIG_COMMAND
|
31
|
+
end
|
32
|
+
|
33
|
+
def legacy_config?
|
34
|
+
return false unless engine_version
|
35
|
+
return false if engine_version.casecmp('unknown').zero?
|
36
|
+
|
37
|
+
Gem::Version.new(engine_version) < Gem::Version.new('1.4.14')
|
38
|
+
rescue ArgumentError
|
39
|
+
# Just assume false if we can't parse the engine_version
|
40
|
+
false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,48 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dalli
|
2
4
|
module Elasticache
|
3
5
|
module AutoDiscovery
|
4
|
-
|
5
6
|
# This class wraps the raw ASCII response from an Auto Discovery endpoint
|
6
7
|
# and provides methods for extracting data from that response.
|
7
8
|
#
|
8
9
|
# http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/AutoDiscovery.AddingToYourClientLibrary.html
|
9
|
-
|
10
10
|
class ConfigResponse
|
11
|
-
|
12
11
|
# The raw response text
|
13
12
|
attr_reader :text
|
14
|
-
|
13
|
+
|
15
14
|
# Matches the version line of the response
|
16
|
-
VERSION_REGEX = /^(\d+)
|
17
|
-
|
15
|
+
VERSION_REGEX = /^(\d+)\r?\n/.freeze
|
16
|
+
|
18
17
|
# 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
|
-
|
18
|
+
NODE_REGEX = /(([-.a-zA-Z0-9]+)\|(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)\|(\d+))/.freeze
|
19
|
+
NODE_LIST_REGEX = /^(#{NODE_REGEX}\s*)+$/.freeze
|
20
|
+
|
22
21
|
def initialize(response_text)
|
23
22
|
@text = response_text.to_s
|
24
23
|
end
|
25
|
-
|
24
|
+
|
26
25
|
# The number of times the configuration has been changed
|
27
26
|
#
|
28
27
|
# Returns an integer
|
29
28
|
def version
|
30
|
-
VERSION_REGEX.match(@text)
|
29
|
+
m = VERSION_REGEX.match(@text)
|
30
|
+
return -1 unless m
|
31
|
+
|
32
|
+
m[1].to_i
|
31
33
|
end
|
32
|
-
|
34
|
+
|
33
35
|
# Node hosts, ip addresses, and ports
|
34
36
|
#
|
35
37
|
# Returns an Array of Hashes with values for :host, :ip and :port
|
36
38
|
def nodes
|
37
39
|
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
|
-
}
|
40
|
+
Node.new(match[1], match[2], match[3].to_i)
|
43
41
|
end
|
44
42
|
end
|
45
|
-
|
46
43
|
end
|
47
44
|
end
|
48
45
|
end
|
@@ -1,76 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dalli
|
2
4
|
module Elasticache
|
3
5
|
module AutoDiscovery
|
6
|
+
##
|
7
|
+
# This is a representation of the configuration endpoint for
|
8
|
+
# a memcached cluster. It encapsulates information returned from
|
9
|
+
# that endpoint.
|
10
|
+
##
|
4
11
|
class Endpoint
|
5
|
-
|
6
12
|
# Endpoint configuration
|
7
|
-
attr_reader :host
|
8
|
-
|
9
|
-
|
13
|
+
attr_reader :host, :port
|
14
|
+
|
10
15
|
# Matches Strings like "my-host.cache.aws.com:11211"
|
11
|
-
ENDPOINT_REGEX =
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
def
|
19
|
-
ENDPOINT_REGEX.match(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
|
16
|
+
ENDPOINT_REGEX = /^([-_.a-zA-Z0-9]+)(?::(\d+))?$/.freeze
|
17
|
+
|
18
|
+
def initialize(addr)
|
19
|
+
@host, @port = parse_endpoint_address(addr)
|
20
|
+
end
|
21
|
+
|
22
|
+
DEFAULT_PORT = 11_211
|
23
|
+
def parse_endpoint_address(addr)
|
24
|
+
m = ENDPOINT_REGEX.match(addr)
|
25
|
+
raise ArgumentError, "Unable to parse configuration endpoint address - #{addr}" unless m
|
26
|
+
|
27
|
+
[m[1], (m[2] || DEFAULT_PORT).to_i]
|
28
|
+
end
|
29
|
+
|
25
30
|
# A cached ElastiCache::StatsResponse
|
26
31
|
def stats
|
27
|
-
@stats ||=
|
32
|
+
@stats ||= StatsCommand.new(@host, @port).response
|
28
33
|
end
|
29
|
-
|
34
|
+
|
30
35
|
# A cached ElastiCache::ConfigResponse
|
31
36
|
def config
|
32
|
-
@config ||=
|
37
|
+
@config ||= ConfigCommand.new(@host, @port, engine_version).response
|
33
38
|
end
|
34
|
-
|
39
|
+
|
35
40
|
# The memcached engine version
|
36
41
|
def engine_version
|
37
|
-
stats.
|
38
|
-
end
|
39
|
-
|
40
|
-
protected
|
41
|
-
|
42
|
-
def with_socket(&block)
|
43
|
-
TCPSocket.new(config_host, config_port)
|
44
|
-
end
|
45
|
-
|
46
|
-
def get_stats_from_remote
|
47
|
-
data = remote_command(STATS_COMMAND)
|
48
|
-
StatsResponse.new(data)
|
49
|
-
end
|
50
|
-
|
51
|
-
def get_config_from_remote
|
52
|
-
if engine_version < Gem::Version.new("1.4.14")
|
53
|
-
data = remote_command(OLD_CONFIG_COMMAND)
|
54
|
-
else
|
55
|
-
data = remote_command(CONFIG_COMMAND)
|
56
|
-
end
|
57
|
-
ConfigResponse.new(data)
|
58
|
-
end
|
59
|
-
|
60
|
-
# Send an ASCII command to the endpoint
|
61
|
-
#
|
62
|
-
# Returns the raw response as a String
|
63
|
-
def remote_command(command)
|
64
|
-
socket = TCPSocket.new(@host, @port)
|
65
|
-
socket.puts command
|
66
|
-
|
67
|
-
data = ""
|
68
|
-
until (line = socket.readline) =~ /END/
|
69
|
-
data << line
|
70
|
-
end
|
71
|
-
|
72
|
-
socket.close
|
73
|
-
data
|
42
|
+
stats.engine_version
|
74
43
|
end
|
75
44
|
end
|
76
45
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dalli
|
4
|
+
module Elasticache
|
5
|
+
module AutoDiscovery
|
6
|
+
##
|
7
|
+
# Represents a single memcached node in the
|
8
|
+
# cluster.
|
9
|
+
##
|
10
|
+
class Node
|
11
|
+
attr_reader :host, :ip, :port
|
12
|
+
|
13
|
+
def initialize(host, ip, port)
|
14
|
+
@host = host
|
15
|
+
@ip = ip
|
16
|
+
@port = port
|
17
|
+
end
|
18
|
+
|
19
|
+
def ==(other)
|
20
|
+
host == other.host &&
|
21
|
+
ip == other.ip &&
|
22
|
+
port == other.port
|
23
|
+
end
|
24
|
+
|
25
|
+
def eql?(other)
|
26
|
+
self == other
|
27
|
+
end
|
28
|
+
|
29
|
+
def hash
|
30
|
+
[host, ip, port].hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
"#{@host}:#{@port}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dalli
|
4
|
+
module Elasticache
|
5
|
+
module AutoDiscovery
|
6
|
+
##
|
7
|
+
# Encapsulates execution of the 'stats' command, which is used to
|
8
|
+
# extract the engine_version
|
9
|
+
##
|
10
|
+
class StatsCommand < BaseCommand
|
11
|
+
STATS_COMMAND = "stats\r\n"
|
12
|
+
|
13
|
+
def response
|
14
|
+
StatsResponse.new(send_command)
|
15
|
+
end
|
16
|
+
|
17
|
+
def command
|
18
|
+
STATS_COMMAND
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,29 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dalli
|
2
4
|
module Elasticache
|
3
5
|
module AutoDiscovery
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
6
|
+
# This class wraps the raw ASCII response from a stats call to an
|
7
|
+
# Auto Discovery endpoint and provides methods for extracting data
|
8
|
+
# from that response.
|
7
9
|
#
|
8
10
|
# http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/AutoDiscovery.AddingToYourClientLibrary.html
|
9
|
-
|
10
11
|
class StatsResponse
|
11
|
-
|
12
12
|
# The raw response text
|
13
13
|
attr_reader :text
|
14
|
-
|
14
|
+
|
15
15
|
# Matches the version line of the response
|
16
|
-
VERSION_REGEX = /^STAT version ([0-9.]
|
17
|
-
|
16
|
+
VERSION_REGEX = /^STAT version ([0-9.]+|unknown)\s*/i.freeze
|
17
|
+
|
18
18
|
def initialize(response_text)
|
19
19
|
@text = response_text.to_s
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
# Extract the engine version stat
|
23
23
|
#
|
24
|
-
# Returns a
|
25
|
-
def
|
26
|
-
|
24
|
+
# Returns a string
|
25
|
+
def engine_version
|
26
|
+
m = VERSION_REGEX.match(@text)
|
27
|
+
return '' unless m && m[1]
|
28
|
+
|
29
|
+
m[1]
|
27
30
|
end
|
28
31
|
end
|
29
32
|
end
|
data/lib/dalli/elasticache.rb
CHANGED
@@ -1,45 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dalli'
|
2
4
|
require 'socket'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
require_relative 'elasticache/version'
|
6
|
+
require_relative 'elasticache/auto_discovery/endpoint'
|
7
|
+
require_relative 'elasticache/auto_discovery/base_command'
|
8
|
+
require_relative 'elasticache/auto_discovery/node'
|
9
|
+
require_relative 'elasticache/auto_discovery/config_response'
|
10
|
+
require_relative 'elasticache/auto_discovery/config_command'
|
11
|
+
require_relative 'elasticache/auto_discovery/stats_response'
|
12
|
+
require_relative 'elasticache/auto_discovery/stats_command'
|
7
13
|
|
8
14
|
module Dalli
|
15
|
+
##
|
16
|
+
# Dalli::Elasticache provides an interface for providing a configuration
|
17
|
+
# endpoint for a memcached cluster on ElasticCache and retrieving the
|
18
|
+
# list of addresses (hostname and port) for the individual nodes of that cluster.
|
19
|
+
#
|
20
|
+
# This allows the caller to pass that server list to Dalli, which then
|
21
|
+
# distributes cached items consistently over the nodes.
|
22
|
+
##
|
9
23
|
class ElastiCache
|
10
24
|
attr_reader :endpoint, :options
|
11
|
-
|
12
|
-
|
25
|
+
|
26
|
+
##
|
27
|
+
# Creates a new Dalli::ElasticCache instance.
|
28
|
+
#
|
29
|
+
# config_endpoint - a String containing the host and (optionally) port of the
|
30
|
+
# configuration endpoint for the cluster. If not specified the port will
|
31
|
+
# default to 11211. The host must be either a DNS name or an IPv4 address. IPv6
|
32
|
+
# addresses are not handled at this time.
|
33
|
+
# dalli_options - a set of options passed to the Dalli::Client that is returned
|
34
|
+
# by the client method. Otherwise unused.
|
35
|
+
##
|
36
|
+
def initialize(config_endpoint, dalli_options = {})
|
13
37
|
@endpoint = Dalli::Elasticache::AutoDiscovery::Endpoint.new(config_endpoint)
|
14
|
-
@options =
|
38
|
+
@options = dalli_options
|
15
39
|
end
|
16
|
-
|
40
|
+
|
17
41
|
# Dalli::Client configured to connect to the cluster's nodes
|
18
42
|
def client
|
19
43
|
Dalli::Client.new(servers, options)
|
20
44
|
end
|
21
|
-
|
45
|
+
|
22
46
|
# The number of times the cluster configuration has been changed
|
23
47
|
#
|
24
48
|
# Returns an integer
|
25
49
|
def version
|
26
50
|
endpoint.config.version
|
27
51
|
end
|
28
|
-
|
52
|
+
|
29
53
|
# The cache engine version of the cluster
|
54
|
+
#
|
55
|
+
# Returns a string
|
30
56
|
def engine_version
|
31
57
|
endpoint.engine_version
|
32
58
|
end
|
33
|
-
|
59
|
+
|
34
60
|
# List of cluster server nodes with ip addresses and ports
|
61
|
+
# Always use host name instead of private elasticache IPs as internal IPs can change after a node is rebooted
|
35
62
|
def servers
|
36
|
-
endpoint.config.nodes.map
|
63
|
+
endpoint.config.nodes.map(&:to_s)
|
37
64
|
end
|
38
|
-
|
65
|
+
|
39
66
|
# Clear all cached data from the cluster endpoint
|
40
67
|
def refresh
|
68
|
+
config_endpoint = "#{endpoint.host}:#{endpoint.port}"
|
41
69
|
@endpoint = Dalli::Elasticache::AutoDiscovery::Endpoint.new(config_endpoint)
|
42
|
-
|
70
|
+
|
43
71
|
self
|
44
72
|
end
|
45
73
|
end
|
data/lib/dalli-elasticache.rb
CHANGED