legion-cache 0.2.0 → 1.2.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 +4 -4
- data/.github/workflows/rubocop-analysis.yml +28 -0
- data/.github/workflows/sourcehawk-scan.yml +20 -0
- data/.gitignore +5 -1
- data/.rubocop.yml +13 -10
- data/CHANGELOG.md +4 -0
- data/CODE_OF_CONDUCT.md +75 -0
- data/CONTRIBUTING.md +55 -0
- data/Gemfile +7 -5
- data/INDIVIDUAL_CONTRIBUTOR_LICENSE.md +30 -0
- data/LICENSE +201 -0
- data/NOTICE.txt +9 -0
- data/README.md +45 -24
- data/SECURITY.md +9 -0
- data/attribution.txt +1 -0
- data/legion-cache.gemspec +23 -31
- data/lib/legion/cache.rb +16 -10
- data/lib/legion/cache/memcached.rb +20 -22
- data/lib/legion/cache/pool.rb +43 -0
- data/lib/legion/cache/redis.rb +21 -14
- data/lib/legion/cache/settings.rb +22 -13
- data/lib/legion/cache/version.rb +1 -1
- data/sonar-project.properties +13 -0
- data/sourcehawk.yml +4 -0
- metadata +50 -120
- data/.circleci/config.yml +0 -61
- data/.rspec +0 -3
- data/LICENSE.txt +0 -21
- data/Rakefile +0 -8
- data/bin/console +0 -15
- data/bin/setup +0 -8
data/NOTICE.txt
ADDED
data/README.md
CHANGED
@@ -1,38 +1,59 @@
|
|
1
|
-
|
1
|
+
Legion::Cache
|
2
|
+
=====
|
2
3
|
|
3
|
-
|
4
|
+
Legion::Cache is a wrapper class to handle requests to the caching tier. It supports both memcached and redis
|
4
5
|
|
5
|
-
|
6
|
+
Supported Ruby versions and implementations
|
7
|
+
------------------------------------------------
|
6
8
|
|
7
|
-
|
9
|
+
Legion::Json should work identically on:
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
```
|
12
|
-
|
13
|
-
And then execute:
|
14
|
-
|
15
|
-
$ bundle install
|
16
|
-
|
17
|
-
Or install it yourself as:
|
18
|
-
|
19
|
-
$ gem install legion-cache
|
11
|
+
* JRuby 9.2+
|
12
|
+
* Ruby 2.4+
|
20
13
|
|
21
|
-
## Usage
|
22
14
|
|
15
|
+
Installation and Usage
|
16
|
+
------------------------
|
23
17
|
|
18
|
+
You can verify your installation using this piece of code:
|
24
19
|
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
```bash
|
21
|
+
gem install legion-cache
|
22
|
+
```
|
28
23
|
|
29
|
-
|
24
|
+
```ruby
|
25
|
+
require 'legion/cache'
|
30
26
|
|
31
|
-
|
27
|
+
Legion::Cache.setup
|
28
|
+
Legion::Cache.connected? # => true
|
29
|
+
Legion::Cache.set('foobar', 'testing', ttl: 10)
|
30
|
+
Legion::Cache.get('foobar') # => 'testing'
|
31
|
+
sleep(11)
|
32
|
+
Legion::Cache.get('foobar') # => nil
|
32
33
|
|
33
|
-
|
34
|
+
```
|
34
35
|
|
36
|
+
Settings
|
37
|
+
----------
|
38
|
+
|
39
|
+
```json
|
40
|
+
{
|
41
|
+
"driver": "dalli",
|
42
|
+
"servers": [
|
43
|
+
"127.0.0.1:11211"
|
44
|
+
],
|
45
|
+
"connected": false,
|
46
|
+
"enabled": true,
|
47
|
+
"namespace": "legion",
|
48
|
+
"compress": false,
|
49
|
+
"cache_nils": false,
|
50
|
+
"pool_size": 10,
|
51
|
+
"timeout": 10,
|
52
|
+
"expires_in": 0
|
53
|
+
}
|
54
|
+
```
|
35
55
|
|
36
|
-
|
56
|
+
Authors
|
57
|
+
----------
|
37
58
|
|
38
|
-
|
59
|
+
* [Matthew Iverson](https://github.com/Esity) - current maintainer
|
data/SECURITY.md
ADDED
data/attribution.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Add attributions here.
|
data/legion-cache.gemspec
CHANGED
@@ -3,40 +3,32 @@
|
|
3
3
|
require_relative 'lib/legion/cache/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name
|
6
|
+
spec.name = 'legion-cache'
|
7
7
|
spec.version = Legion::Cache::VERSION
|
8
8
|
spec.authors = ['Esity']
|
9
|
-
spec.email = [
|
9
|
+
spec.email = %w[matthewdiverson@gmail.com ruby@optum.com]
|
10
10
|
|
11
|
-
spec.summary = '
|
12
|
-
spec.description = '
|
13
|
-
spec.homepage = 'https://
|
14
|
-
spec.license = '
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
|
16
|
-
|
17
|
-
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
-
spec.metadata['source_code_uri'] = 'https://bitbucket.org/legion-io/legion-cache/src'
|
19
|
-
spec.metadata['changelog_uri'] = 'https://bitbucket.org/legion-io/legion-cache/src/master/CHANGELOG.md'
|
20
|
-
spec.metadata['wiki_uri'] = 'https://bitbucket.org/legion-io/legion-cache/wiki'
|
21
|
-
spec.metadata['bug_tracker_uri'] = 'https://bitbucket.org/legion-io/legion-cache/issues'
|
22
|
-
|
23
|
-
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
-
end
|
26
|
-
spec.bindir = 'exe'
|
27
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
11
|
+
spec.summary = 'Wraps both the redis and dalli gems to make a consistent interface for accessing cached objects'
|
12
|
+
spec.description = 'A Wrapper class for the LegionIO framework to interface with both Memcached and Redis for caching purposes'
|
13
|
+
spec.homepage = 'https://github.com/Optum/legion-cache'
|
14
|
+
spec.license = 'Apache-2.0'
|
28
15
|
spec.require_paths = ['lib']
|
16
|
+
spec.required_ruby_version = '>= 2.4'
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.test_files = spec.files.select { |p| p =~ %r{^test/.*_test.rb} }
|
19
|
+
spec.extra_rdoc_files = %w[README.md LICENSE CHANGELOG.md]
|
20
|
+
spec.metadata = {
|
21
|
+
'bug_tracker_uri' => 'https://github.com/Optum/legion-cache/issues',
|
22
|
+
'changelog_uri' => 'https://github.com/Optum/legion-cache/src/main/CHANGELOG.md',
|
23
|
+
'documentation_uri' => 'https://github.com/Optum/legion-cache',
|
24
|
+
'homepage_uri' => 'https://github.com/Optum/LegionIO',
|
25
|
+
'source_code_uri' => 'https://github.com/Optum/legion-cache',
|
26
|
+
'wiki_uri' => 'https://github.com/Optum/legion-cache/wiki'
|
27
|
+
}
|
29
28
|
|
30
|
-
spec.
|
31
|
-
spec.
|
32
|
-
spec.
|
33
|
-
spec.
|
34
|
-
spec.
|
35
|
-
spec.add_development_dependency 'rspec_junit_formatter'
|
36
|
-
spec.add_development_dependency 'rubocop'
|
37
|
-
spec.add_development_dependency 'simplecov'
|
38
|
-
|
39
|
-
spec.add_dependency 'connection_pool'
|
40
|
-
spec.add_dependency 'dalli'
|
41
|
-
spec.add_dependency 'redis'
|
29
|
+
spec.add_dependency 'connection_pool', '>= 2.2.3'
|
30
|
+
spec.add_dependency 'dalli', '>= 2.7'
|
31
|
+
spec.add_dependency 'legion-logging'
|
32
|
+
spec.add_dependency 'legion-settings'
|
33
|
+
spec.add_dependency 'redis', '>= 4.2'
|
42
34
|
end
|
data/lib/legion/cache.rb
CHANGED
@@ -1,19 +1,25 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'legion/cache/version'
|
2
|
+
require 'legion/cache/settings'
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
require 'legion/cache/memcached'
|
5
|
+
require 'legion/cache/redis'
|
6
6
|
|
7
7
|
module Legion
|
8
8
|
module Cache
|
9
9
|
class << self
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
if Legion::Settings[:cache][:driver] == 'redis'
|
11
|
+
include Legion::Cache::Redis
|
12
|
+
else
|
13
|
+
include Legion::Cache::Memcached
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup(**opts)
|
17
|
+
return Legion::Settings[:cache][:connected] = true if connected?
|
18
|
+
|
19
|
+
return unless client(**Legion::Settings[:cache], **opts)
|
13
20
|
|
14
|
-
|
15
|
-
|
16
|
-
Legion::Logging.info 'Legion::Cache connected and enabled'
|
21
|
+
@connected = true
|
22
|
+
Legion::Settings[:cache][:connected] = true
|
17
23
|
end
|
18
24
|
|
19
25
|
def shutdown
|
@@ -1,47 +1,45 @@
|
|
1
1
|
require 'dalli'
|
2
|
+
require 'legion/cache/pool'
|
2
3
|
|
3
4
|
module Legion
|
4
5
|
module Cache
|
5
6
|
module Memcached
|
6
|
-
|
7
|
-
|
8
|
-
options = { compress: true,
|
9
|
-
serializer: Legion::JSON,
|
10
|
-
failover: Legion::Settings[:cache][:failover],
|
11
|
-
namespace: Legion::Settings[:cache][:namespace], foo: 'test' }
|
12
|
-
Dalli.logger = Legion::Logging
|
13
|
-
@client = Dalli::Client.new(Legion::Settings[:cache][:servers], options)
|
14
|
-
Legion::Logging.debug "Legion::Cache successfully connected to #{Legion::Settings[:cache][:servers]}"
|
15
|
-
Legion::Settings[:cache][:connected] = true
|
16
|
-
end
|
7
|
+
include Legion::Cache::Pool
|
8
|
+
extend self
|
17
9
|
|
18
|
-
def
|
19
|
-
@client.
|
20
|
-
|
10
|
+
def client(servers: Legion::Settings[:cache][:servers], **opts)
|
11
|
+
return @client unless @client.nil?
|
12
|
+
|
13
|
+
@pool_size = opts.key?(:pool_size) ? opts[:pool_size] : Legion::Settings[:cache][:pool_size] || 10
|
14
|
+
@timeout = opts.key?(:timeout) ? opts[:timeout] : Legion::Settings[:cache][:timeout] || 5
|
15
|
+
|
16
|
+
Dalli.logger = Legion::Logging
|
17
|
+
@client = ConnectionPool.new(size: pool_size, timeout: timeout) do
|
18
|
+
Dalli::Client.new(servers, Legion::Settings[:cache].merge(opts))
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
connect
|
21
|
+
@connected = true
|
22
|
+
@client
|
25
23
|
end
|
26
24
|
|
27
25
|
def get(key)
|
28
|
-
|
26
|
+
client.with { |conn| conn.get(key) }
|
29
27
|
end
|
30
28
|
|
31
29
|
def fetch(key, ttl = nil)
|
32
|
-
|
30
|
+
client.with { |conn| conn.fetch(key, ttl) }
|
33
31
|
end
|
34
32
|
|
35
33
|
def set(key, value, ttl = 180)
|
36
|
-
|
34
|
+
client.with { |conn| conn.set(key, value, ttl).positive? }
|
37
35
|
end
|
38
36
|
|
39
37
|
def delete(key)
|
40
|
-
|
38
|
+
client.with { |conn| conn.delete(key) == true }
|
41
39
|
end
|
42
40
|
|
43
41
|
def flush(delay = 0)
|
44
|
-
|
42
|
+
client.with { |conn| conn.flush(delay).first }
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'connection_pool'
|
2
|
+
|
3
|
+
module Legion
|
4
|
+
module Cache
|
5
|
+
module Pool
|
6
|
+
def connected?
|
7
|
+
@connected ||= false
|
8
|
+
end
|
9
|
+
|
10
|
+
def size
|
11
|
+
client.size
|
12
|
+
end
|
13
|
+
|
14
|
+
def timeout
|
15
|
+
@timeout ||= Legion::Settings[:cache][:timeout] || 5
|
16
|
+
end
|
17
|
+
|
18
|
+
def pool_size
|
19
|
+
@pool_size ||= Legion::Settings[:cache][:pool_size] || 10
|
20
|
+
end
|
21
|
+
|
22
|
+
def available
|
23
|
+
client.available
|
24
|
+
end
|
25
|
+
|
26
|
+
def close
|
27
|
+
client.shutdown(&:close)
|
28
|
+
@client = nil
|
29
|
+
@connected = false
|
30
|
+
end
|
31
|
+
|
32
|
+
def restart(**opts)
|
33
|
+
close
|
34
|
+
@client = nil
|
35
|
+
client_hash = opts
|
36
|
+
client_hash[:pool_size] = opts[:pool_size] if opts.key? :pool_size
|
37
|
+
client_hash[:timeout] = opts[:timeout] if opts.key? :timeout
|
38
|
+
client(**client_hash)
|
39
|
+
@connected = true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/legion/cache/redis.rb
CHANGED
@@ -1,35 +1,42 @@
|
|
1
1
|
require 'redis'
|
2
|
+
require 'legion/cache/pool'
|
2
3
|
|
3
4
|
module Legion
|
4
5
|
module Cache
|
5
6
|
module Redis
|
6
|
-
|
7
|
-
|
8
|
-
end
|
7
|
+
include Legion::Cache::Pool
|
8
|
+
extend self
|
9
9
|
|
10
|
-
def
|
11
|
-
@client.
|
12
|
-
|
10
|
+
def client(pool_size: 20, timeout: 5, **)
|
11
|
+
return @client unless @client.nil?
|
12
|
+
|
13
|
+
@pool_size = pool_size
|
14
|
+
@timeout = timeout
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
@client = ConnectionPool.new(size: pool_size, timeout: timeout) do
|
17
|
+
::Redis.new
|
18
|
+
end
|
19
|
+
@connected = true
|
20
|
+
@client
|
17
21
|
end
|
18
22
|
|
19
23
|
def get(key)
|
20
|
-
|
24
|
+
client.with { |conn| conn.get(key) }
|
21
25
|
end
|
26
|
+
alias fetch get
|
22
27
|
|
23
|
-
def set(key, value)
|
24
|
-
|
28
|
+
def set(key, value, ttl: nil)
|
29
|
+
args = {}
|
30
|
+
args[:ex] = ttl unless ttl.nil?
|
31
|
+
client.with { |conn| conn.set(key, value, **args) == 'OK' }
|
25
32
|
end
|
26
33
|
|
27
34
|
def delete(key)
|
28
|
-
|
35
|
+
client.with { |conn| conn.del(key) == 1 }
|
29
36
|
end
|
30
37
|
|
31
38
|
def flush
|
32
|
-
|
39
|
+
client.with { |conn| conn.flushdb == 'OK' }
|
33
40
|
end
|
34
41
|
end
|
35
42
|
end
|
@@ -1,28 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'legion/settings'
|
3
|
+
rescue StandardError
|
4
|
+
# empty block
|
5
|
+
end
|
6
|
+
|
1
7
|
module Legion
|
2
8
|
module Cache
|
3
9
|
module Settings
|
10
|
+
Legion::Settings.merge_settings(:cache, default) if Legion::Settings.method_defined? :merge_settings
|
4
11
|
def self.default
|
5
12
|
{
|
6
|
-
driver:
|
7
|
-
servers:
|
8
|
-
connected:
|
9
|
-
enabled:
|
10
|
-
namespace:
|
11
|
-
compress:
|
12
|
-
failover:
|
13
|
+
driver: driver,
|
14
|
+
servers: ['127.0.0.1:11211'],
|
15
|
+
connected: false,
|
16
|
+
enabled: true,
|
17
|
+
namespace: 'legion',
|
18
|
+
compress: false,
|
19
|
+
failover: true,
|
13
20
|
threadsafe: true,
|
14
21
|
expires_in: 0,
|
15
22
|
cache_nils: false,
|
16
|
-
pool_size:
|
23
|
+
pool_size: 10,
|
24
|
+
timeout: 5,
|
17
25
|
serializer: Legion::JSON
|
18
26
|
}
|
19
27
|
end
|
20
28
|
|
21
|
-
def self.driver
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
29
|
+
def self.driver(prefer = 'dalli')
|
30
|
+
secondary = prefer == 'dalli' ? 'redis' : 'dalli'
|
31
|
+
if Gem::Specification.find_all_by_name(prefer).count.positive?
|
32
|
+
prefer
|
33
|
+
elsif Gem::Specification.find_all_by_name(secondary).count.positive?
|
34
|
+
secondary
|
26
35
|
else
|
27
36
|
raise NameError('Legion::Cache.driver is nil')
|
28
37
|
end
|
data/lib/legion/cache/version.rb
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
sonar.projectKey=legion-io_legion-cache
|
2
|
+
sonar.organization=legion-io
|
3
|
+
sonar.projectName=Legion::Cache
|
4
|
+
sonar.sources=.
|
5
|
+
sonar.exclusions=vendor/**
|
6
|
+
sonar.coverage.exclusions=spec/**
|
7
|
+
sonar.cpd.exclusions=spec/**
|
8
|
+
sonar.ruby.coverage.reportPath=coverage/.resultset.json
|
9
|
+
sonar.ruby.file.suffixes=rb,ruby
|
10
|
+
sonar.ruby.coverage.framework=RSpec
|
11
|
+
sonar.ruby.rubocopConfig=.rubocop.yml
|
12
|
+
sonar.ruby.rubocop.reportPath=rubocop-result.json
|
13
|
+
sonar.ruby.rubocop.filePath=.
|