redcache 0.0.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 +14 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +96 -0
- data/Rakefile +2 -0
- data/lib/redcache/configuration.rb +22 -0
- data/lib/redcache/version.rb +3 -0
- data/lib/redcache.rb +125 -0
- data/redcache.gemspec +30 -0
- data/spec/redcache_spec.rb +63 -0
- data/spec/spec_helper.rb +17 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 42b0aaf4e3410df46698c1dc6c4266a7ab085a82
|
4
|
+
data.tar.gz: 6168ec9abcac4a6331b313f50325d162a0cd760a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6d1aa979354e1fcaae9126555b8a2ce34bd5529e0770958a5f3df439865f0701fb15b879b99652d79a3b1f4753acb140d986827385352e66d23b31fd44280a11
|
7
|
+
data.tar.gz: 00d1ba914e1c8e0facb68c26b993c0c83d2ca9c5549dd4aaea68bfe0b3fe48a4125f3023427e088dca7a722920d8fa75144665b86958a6551ba40d692d0002af
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Neil Middleton
|
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,96 @@
|
|
1
|
+
# Redcache
|
2
|
+
|
3
|
+
A gem for caching data in Redis.
|
4
|
+
|
5
|
+
This gem caches data from slow services in Redis, but ensures that the cache is
|
6
|
+
up to date.
|
7
|
+
|
8
|
+
Should the cache be cold, the result is cached. Should the cache be warm but
|
9
|
+
considered stale, the cache is still used, but updated subsequently via a
|
10
|
+
threaded request, thus not blocking the original request.
|
11
|
+
|
12
|
+
This gem is also able to encrypt the cached results with Fernet if required.
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Add this line to your application's Gemfile:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
gem 'redcache'
|
20
|
+
```
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
$ bundle
|
25
|
+
|
26
|
+
Or install it yourself as:
|
27
|
+
|
28
|
+
$ gem install redcache
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
|
34
|
+
Redcache.configure do |c|
|
35
|
+
c.redis = $redis
|
36
|
+
c.secret = <some_long_hash>
|
37
|
+
c.encrypt = true
|
38
|
+
end
|
39
|
+
|
40
|
+
value = Redcache.cache "unique_cache_key" do
|
41
|
+
call_to_slow_service
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
### Configuration
|
46
|
+
|
47
|
+
Several configuration options are available to use that defined the behaviour of
|
48
|
+
redcache.
|
49
|
+
|
50
|
+
<table>
|
51
|
+
<tr>
|
52
|
+
<td>:redis</td>
|
53
|
+
<td>Connection to redis</td>
|
54
|
+
</tr>
|
55
|
+
<tr>
|
56
|
+
<td>:secret</td>
|
57
|
+
<td>If encrypting, what secret should be used. See [Fernet](https://github.com/fernet/fernet-rb) README for more
|
58
|
+
information</td>
|
59
|
+
</tr>
|
60
|
+
<tr>
|
61
|
+
<td>:encrypt</td>
|
62
|
+
<td>Should cached data be encrypted (boolean)</td>
|
63
|
+
</tr>
|
64
|
+
<tr>
|
65
|
+
<td>:skip_cache</td>
|
66
|
+
<td>Should the cache be skipped. Useful in test environments (boolean)</td>
|
67
|
+
</tr>
|
68
|
+
<tr>
|
69
|
+
<td>:logged</td>
|
70
|
+
<td>Standard logger object to use for logging</td>
|
71
|
+
</tr>
|
72
|
+
<tr>
|
73
|
+
<td>:log_prefix</td>
|
74
|
+
<td>String to prefix to l2met compatible log lines</td>
|
75
|
+
</tr>
|
76
|
+
<tr>
|
77
|
+
<td>:cache_time</td>
|
78
|
+
<td>Time (in seconds) to cache data for before expiring</td>
|
79
|
+
</tr>
|
80
|
+
<tr>
|
81
|
+
<td>:stale_time</td>
|
82
|
+
<td>Time (in seconds) before cached data should be considered stale</td>
|
83
|
+
</tr>
|
84
|
+
</table>
|
85
|
+
|
86
|
+
## Testing
|
87
|
+
|
88
|
+
Specs to come ;)
|
89
|
+
|
90
|
+
## Contributing
|
91
|
+
|
92
|
+
1. Fork it ( https://github.com/[my-github-username]/redcache/fork )
|
93
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
94
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
95
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
96
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Redcache
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :redis
|
4
|
+
attr_accessor :secret
|
5
|
+
attr_accessor :cache_time
|
6
|
+
attr_accessor :stale_time
|
7
|
+
attr_accessor :encrypt
|
8
|
+
attr_accessor :skip_cache
|
9
|
+
attr_accessor :logger
|
10
|
+
attr_accessor :log_prefix
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@cache_time = 86400
|
14
|
+
@stale_time = 900
|
15
|
+
@encrypt = false
|
16
|
+
@secret = nil
|
17
|
+
@skip_cache = false
|
18
|
+
@logger = nil
|
19
|
+
@log_prefix = "redcache"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/redcache.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
require "redcache/version"
|
2
|
+
require "redcache/configuration"
|
3
|
+
|
4
|
+
module Redcache
|
5
|
+
class << self
|
6
|
+
attr_writer :configuration
|
7
|
+
|
8
|
+
def configure
|
9
|
+
yield(configuration)
|
10
|
+
end
|
11
|
+
|
12
|
+
def cache(redis_key, &block)
|
13
|
+
return block.call if skip_cache?
|
14
|
+
if redis_up?
|
15
|
+
value = read_from_cache(redis_key, block) || write_into_cache(redis_key, block)
|
16
|
+
return value unless value.nil?
|
17
|
+
else
|
18
|
+
block.call
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def configuration
|
23
|
+
@configuration ||= Configuration.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def redis
|
27
|
+
configuration.redis
|
28
|
+
end
|
29
|
+
|
30
|
+
def redis_up?
|
31
|
+
begin
|
32
|
+
redis.ping
|
33
|
+
rescue Redis::CannotConnectError
|
34
|
+
puts "Redis is DOWN! :shitsonfire:"
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
return true
|
38
|
+
end
|
39
|
+
|
40
|
+
def with_redis(&block)
|
41
|
+
block.call if redis_up?
|
42
|
+
end
|
43
|
+
|
44
|
+
def cache_time
|
45
|
+
configuration.cache_time
|
46
|
+
end
|
47
|
+
|
48
|
+
def stale_time
|
49
|
+
configuration.stale_time
|
50
|
+
end
|
51
|
+
|
52
|
+
def skip_cache?
|
53
|
+
configuration.skip_cache
|
54
|
+
end
|
55
|
+
|
56
|
+
def read_from_cache(redis_key, block)
|
57
|
+
value = get_value(redis_key)
|
58
|
+
value.nil? ? log("cache.miss") : log("cache.hit")
|
59
|
+
refresh_cache(redis_key, block) if key_stale?(redis_key) && !value.nil?
|
60
|
+
return value
|
61
|
+
end
|
62
|
+
|
63
|
+
def test?
|
64
|
+
ENV["RACK_ENV"] == 'test'
|
65
|
+
end
|
66
|
+
|
67
|
+
def refresh_cache(redis_key, block)
|
68
|
+
log("cache.stale_refresh")
|
69
|
+
Thread.new do
|
70
|
+
write_into_cache(redis_key, block)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def write_into_cache(redis_key, block)
|
75
|
+
json = block.call
|
76
|
+
with_redis do
|
77
|
+
log("cache.write")
|
78
|
+
set_value(redis_key, json)
|
79
|
+
end
|
80
|
+
json
|
81
|
+
end
|
82
|
+
|
83
|
+
def key_stale?(redis_key)
|
84
|
+
ttl = redis.ttl(redis_key)
|
85
|
+
return ttl < (configuration.cache_time - configuration.stale_time)
|
86
|
+
end
|
87
|
+
|
88
|
+
def get_value(key)
|
89
|
+
decrypt redis.get(key)
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_value(key, value)
|
93
|
+
redis.setex key, configuration.cache_time, encrypt(value)
|
94
|
+
end
|
95
|
+
|
96
|
+
def encrypt(value)
|
97
|
+
return value unless encrypt?
|
98
|
+
Fernet.generate(secret, MultiJson.encode(value))
|
99
|
+
end
|
100
|
+
|
101
|
+
def encrypt?
|
102
|
+
configuration.encrypt
|
103
|
+
end
|
104
|
+
|
105
|
+
def decrypt(value)
|
106
|
+
return nil if value.nil?
|
107
|
+
return value unless encrypt?
|
108
|
+
verifier = Fernet.verifier(secret, value)
|
109
|
+
return MultiJson.load(verifier.message) if verifier.valid?
|
110
|
+
return nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def secret
|
114
|
+
configuration.secret
|
115
|
+
end
|
116
|
+
|
117
|
+
def log(str)
|
118
|
+
configuration.logger.log(log_prefix(str) => 1)
|
119
|
+
end
|
120
|
+
|
121
|
+
def log_prefix(str)
|
122
|
+
[configuration.log_prefix, str].join(".")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
data/redcache.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'redcache/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "redcache"
|
8
|
+
spec.version = Redcache::VERSION
|
9
|
+
spec.authors = ["Neil Middleton"]
|
10
|
+
spec.email = ["neil@neilmiddleton.com"]
|
11
|
+
spec.summary = %q{A gem for caching values in redis and encrypting them}
|
12
|
+
spec.description = %q{A wrapper for Redis, for caching and encryption with Fernet}
|
13
|
+
spec.homepage = "http://www.neilmiddleton.com"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
24
|
+
spec.add_development_dependency "fakeredis", "~> 0.5"
|
25
|
+
spec.add_development_dependency "pliny", "~> 0.0"
|
26
|
+
|
27
|
+
spec.add_dependency "fernet", "~> 2.1"
|
28
|
+
spec.add_dependency "redis", "~> 3.1"
|
29
|
+
spec.add_dependency "multi_json", "~> 1.10"
|
30
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
Redcache.configure do |c|
|
4
|
+
c.redis = Redis.new
|
5
|
+
c.logger = Pliny
|
6
|
+
end
|
7
|
+
|
8
|
+
class Dummy
|
9
|
+
def self.run
|
10
|
+
Redcache.cache "foo" do
|
11
|
+
get_value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.get_value
|
16
|
+
"bar"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Redcache do
|
21
|
+
|
22
|
+
context 'when skipping caching' do
|
23
|
+
before do
|
24
|
+
allow(Redcache.configuration).to receive(:skip_cache){true}
|
25
|
+
end
|
26
|
+
it 'does not use the cache' do
|
27
|
+
expect(Redcache).to_not receive(:read_from_cache)
|
28
|
+
Dummy.run
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when caching' do
|
33
|
+
before do
|
34
|
+
allow(Redcache.configuration).to receive(:skip_cache){false}
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'uses the cached' do
|
38
|
+
expect(Redcache).to receive(:read_from_cache){ {} }
|
39
|
+
Dummy.run
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'triggers a cache write if the cache is cold' do
|
43
|
+
allow(Redcache).to receive(:read_from_cache){ nil }
|
44
|
+
expect(Redcache).to receive(:write_into_cache) { "" }
|
45
|
+
Dummy.run
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'skips cache when redis is down' do
|
49
|
+
allow(Redcache).to receive(:redis_up?){ false }
|
50
|
+
expect(Redcache).to_not receive(:read_from_cache)
|
51
|
+
expect(Dummy).to receive(:get_value)
|
52
|
+
Dummy.run
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'triggers a cache refresh with a stale warm cache' do
|
56
|
+
allow(Redcache).to receive(:key_stale?){ true }
|
57
|
+
allow(Redcache).to receive(:get_value){ "" }
|
58
|
+
expect(Redcache).to receive(:refresh_cache).once
|
59
|
+
Dummy.run
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler.require
|
3
|
+
|
4
|
+
require 'redcache'
|
5
|
+
require 'redis'
|
6
|
+
require 'fakeredis'
|
7
|
+
require 'pliny'
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.expect_with :rspec do |expectations|
|
11
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
12
|
+
end
|
13
|
+
|
14
|
+
config.mock_with :rspec do |mocks|
|
15
|
+
mocks.verify_partial_doubles = true
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redcache
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Neil Middleton
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-05 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.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: fakeredis
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.5'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pliny
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.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.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: fernet
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.1'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: redis
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.1'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: multi_json
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.10'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.10'
|
125
|
+
description: A wrapper for Redis, for caching and encryption with Fernet
|
126
|
+
email:
|
127
|
+
- neil@neilmiddleton.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rspec"
|
134
|
+
- Gemfile
|
135
|
+
- LICENSE.txt
|
136
|
+
- README.md
|
137
|
+
- Rakefile
|
138
|
+
- lib/redcache.rb
|
139
|
+
- lib/redcache/configuration.rb
|
140
|
+
- lib/redcache/version.rb
|
141
|
+
- redcache.gemspec
|
142
|
+
- spec/redcache_spec.rb
|
143
|
+
- spec/spec_helper.rb
|
144
|
+
homepage: http://www.neilmiddleton.com
|
145
|
+
licenses:
|
146
|
+
- MIT
|
147
|
+
metadata: {}
|
148
|
+
post_install_message:
|
149
|
+
rdoc_options: []
|
150
|
+
require_paths:
|
151
|
+
- lib
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
requirements: []
|
163
|
+
rubyforge_project:
|
164
|
+
rubygems_version: 2.2.2
|
165
|
+
signing_key:
|
166
|
+
specification_version: 4
|
167
|
+
summary: A gem for caching values in redis and encrypting them
|
168
|
+
test_files:
|
169
|
+
- spec/redcache_spec.rb
|
170
|
+
- spec/spec_helper.rb
|
171
|
+
has_rdoc:
|