readthis 0.1.0 → 0.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/.travis.yml +6 -0
- data/CHANGELOG.md +7 -0
- data/README.md +3 -0
- data/lib/readthis/cache.rb +80 -36
- data/lib/readthis/expanders.rb +15 -0
- data/lib/readthis/notifications.rb +7 -0
- data/lib/readthis/version.rb +1 -1
- data/readthis.gemspec +3 -3
- data/spec/readthis/cache_spec.rb +8 -0
- data/spec/readthis/expanders_spec.rb +26 -0
- data/spec/readthis/notifications_spec.rb +15 -0
- metadata +17 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 513263f9ac89cdc3d8bfc354404778e49902460b
|
4
|
+
data.tar.gz: 525ab985b197507e19c000bcb6dc21683ba068d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9207fe0c1d9746337d17ac05a23acd4bfde8c9d943d1814daa7426160a39fb8d932ea2fd7c69e898097afdf0427eab59cfad320362053547d4e40b3f2a4d4ee
|
7
|
+
data.tar.gz: 14ae7680da85fe6591cc6b623c9f13e2c11dd7905add114288d6ed4138490b4a63a67d0832d0069706246cac73f5fe9de14774f0316e4a4db933ed418e6c60aa
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## v0.2.0 2014-11-24
|
2
|
+
|
3
|
+
- Instrument all caching methods. Will use `ActiveSupport::Notifications`
|
4
|
+
if available, otherwise falls back to a polyfill.
|
5
|
+
- Expand objects with a `cache_key` method and arrays of strings or objects into
|
6
|
+
consistent naespaced keys.
|
7
|
+
|
1
8
|
## v0.1.0 2014-11-22
|
2
9
|
|
3
10
|
- Initial release! Working as a drop in replacement for `redis_store`.
|
data/README.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
[](http://badge.fury.io/rb/readthis)
|
2
|
+
[](https://travis-ci.org/sorentwo/readthis)
|
3
|
+
|
1
4
|
# Readthis
|
2
5
|
|
3
6
|
An ActiveSupport::Cache compatible redis based cache focused on speed,
|
data/lib/readthis/cache.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'readthis/expanders'
|
2
|
+
require 'readthis/notifications'
|
1
3
|
require 'redis'
|
2
4
|
require 'connection_pool'
|
3
5
|
|
@@ -5,8 +7,22 @@ module Readthis
|
|
5
7
|
class Cache
|
6
8
|
attr_reader :expires_in, :namespace, :pool
|
7
9
|
|
10
|
+
# Provide a class level lookup of the proper notifications module.
|
11
|
+
# Instrumention is expected to occur within applications that have
|
12
|
+
# ActiveSupport::Notifications available, but needs to work even when it
|
13
|
+
# isn't.
|
14
|
+
def self.notifications
|
15
|
+
if Object.const_defined?('ActiveSupport::Notifications')
|
16
|
+
ActiveSupport::Notifications
|
17
|
+
else
|
18
|
+
Readthis::Notifications
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
8
22
|
# Creates a new Readthis::Cache object with the given redis URL. The URL
|
9
23
|
# is parsed by the redis client directly.
|
24
|
+
#
|
25
|
+
# Readthis::Cache.new('redis://localhost:6379/0', namespace: 'cache')
|
10
26
|
def initialize(url, options = {})
|
11
27
|
@expires_in = options.fetch(:expires_in, nil)
|
12
28
|
@namespace = options.fetch(:namespace, nil)
|
@@ -17,8 +33,10 @@ module Readthis
|
|
17
33
|
end
|
18
34
|
|
19
35
|
def read(key, options = {})
|
20
|
-
|
21
|
-
store
|
36
|
+
instrument(:read, key) do
|
37
|
+
with do |store|
|
38
|
+
store.get(namespaced_key(key, merged_options(options)))
|
39
|
+
end
|
22
40
|
end
|
23
41
|
end
|
24
42
|
|
@@ -26,18 +44,22 @@ module Readthis
|
|
26
44
|
options = merged_options(options)
|
27
45
|
namespaced = namespaced_key(key, options)
|
28
46
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
47
|
+
instrument(:write, key) do
|
48
|
+
with do |store|
|
49
|
+
if expiration = options[:expires_in]
|
50
|
+
store.setex(namespaced, expiration, value)
|
51
|
+
else
|
52
|
+
store.set(namespaced, value)
|
53
|
+
end
|
34
54
|
end
|
35
55
|
end
|
36
56
|
end
|
37
57
|
|
38
58
|
def delete(key, options = {})
|
39
|
-
|
40
|
-
store
|
59
|
+
instrument(:delete, key) do
|
60
|
+
with do |store|
|
61
|
+
store.del(namespaced_key(key, merged_options(options)))
|
62
|
+
end
|
41
63
|
end
|
42
64
|
end
|
43
65
|
|
@@ -53,14 +75,18 @@ module Readthis
|
|
53
75
|
end
|
54
76
|
|
55
77
|
def increment(key, options = {})
|
56
|
-
|
57
|
-
store
|
78
|
+
instrument(:incremenet, key) do
|
79
|
+
with do |store|
|
80
|
+
store.incr(namespaced_key(key, merged_options(options)))
|
81
|
+
end
|
58
82
|
end
|
59
83
|
end
|
60
84
|
|
61
85
|
def decrement(key, options = {})
|
62
|
-
|
63
|
-
store
|
86
|
+
instrument(:decrement, key) do
|
87
|
+
with do |store|
|
88
|
+
store.decr(namespaced_key(key, merged_options(options)))
|
89
|
+
end
|
64
90
|
end
|
65
91
|
end
|
66
92
|
|
@@ -68,50 +94,70 @@ module Readthis
|
|
68
94
|
options = merged_options(extract_options!(keys))
|
69
95
|
results = []
|
70
96
|
|
71
|
-
|
72
|
-
|
73
|
-
|
97
|
+
instrument(:read_multi, keys) do
|
98
|
+
with do |store|
|
99
|
+
results = store.pipelined do
|
100
|
+
keys.each { |key| store.get(namespaced_key(key, options)) }
|
101
|
+
end
|
74
102
|
end
|
75
|
-
end
|
76
103
|
|
77
|
-
|
104
|
+
keys.zip(results).to_h
|
105
|
+
end
|
78
106
|
end
|
79
107
|
|
80
|
-
#
|
81
|
-
#
|
108
|
+
# Fetches multiple keys from the cache using a single call to the server
|
109
|
+
# and filling in any cache misses. All read and write operations are
|
110
|
+
# executed atomically.
|
111
|
+
#
|
112
|
+
# cache.fetch_multi('alpha', 'beta') do |key|
|
113
|
+
# "#{key}-was-missing"
|
114
|
+
# end
|
82
115
|
def fetch_multi(*keys)
|
83
116
|
results = read_multi(*keys)
|
84
117
|
options = merged_options(extract_options!(keys))
|
85
118
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
value
|
91
|
-
|
92
|
-
|
119
|
+
instrument(:fetch_multi, keys) do
|
120
|
+
with do |store|
|
121
|
+
store.pipelined do
|
122
|
+
results.each do |key, value|
|
123
|
+
if value.nil?
|
124
|
+
value = yield key
|
125
|
+
write(key, value, options)
|
126
|
+
results[key] = value
|
127
|
+
end
|
93
128
|
end
|
94
129
|
end
|
95
130
|
end
|
96
|
-
end
|
97
131
|
|
98
|
-
|
132
|
+
results
|
133
|
+
end
|
99
134
|
end
|
100
135
|
|
101
136
|
def exist?(key, options = {})
|
102
|
-
|
103
|
-
store
|
137
|
+
instrument(:exist?, key) do
|
138
|
+
with do |store|
|
139
|
+
store.exists(namespaced_key(key, merged_options(options)))
|
140
|
+
end
|
104
141
|
end
|
105
142
|
end
|
106
143
|
|
107
144
|
def clear
|
108
|
-
|
109
|
-
store
|
145
|
+
instrument(:clear, '*') do
|
146
|
+
with do |store|
|
147
|
+
store.flushdb
|
148
|
+
end
|
110
149
|
end
|
111
150
|
end
|
112
151
|
|
113
152
|
private
|
114
153
|
|
154
|
+
def instrument(operation, key)
|
155
|
+
name = "cache_#{operation}.active_support"
|
156
|
+
payload = { key: key }
|
157
|
+
|
158
|
+
self.class.notifications.instrument(name, key) { yield(payload) }
|
159
|
+
end
|
160
|
+
|
115
161
|
def with(&block)
|
116
162
|
pool.with(&block)
|
117
163
|
end
|
@@ -132,9 +178,7 @@ module Readthis
|
|
132
178
|
end
|
133
179
|
|
134
180
|
def namespaced_key(key, options)
|
135
|
-
|
136
|
-
|
137
|
-
[namespace, key].compact.join(':')
|
181
|
+
Readthis::Expanders.expand(key, options[:namespace])
|
138
182
|
end
|
139
183
|
end
|
140
184
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Readthis
|
2
|
+
module Expanders
|
3
|
+
def self.expand(key, namespace = nil)
|
4
|
+
expanded = if key.respond_to?(:cache_key)
|
5
|
+
key.cache_key
|
6
|
+
elsif key.is_a?(Array)
|
7
|
+
key.flat_map { |elem| expand(elem) }.join(':')
|
8
|
+
else
|
9
|
+
key
|
10
|
+
end
|
11
|
+
|
12
|
+
namespace ? "#{namespace}:#{expanded}" : expanded
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/readthis/version.rb
CHANGED
data/readthis.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.add_dependency 'redis', '~> 3.0'
|
21
21
|
spec.add_dependency 'connection_pool', '~> 2.1'
|
22
22
|
|
23
|
-
spec.add_development_dependency 'bundler'
|
24
|
-
spec.add_development_dependency 'rake'
|
25
|
-
spec.add_development_dependency 'rspec',
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.1'
|
26
26
|
end
|
data/spec/readthis/cache_spec.rb
CHANGED
@@ -43,6 +43,14 @@ RSpec.describe Readthis::Cache do
|
|
43
43
|
sleep 1.01
|
44
44
|
expect(cache.read('some-key')).to be_nil
|
45
45
|
end
|
46
|
+
|
47
|
+
it 'expands non-string keys' do
|
48
|
+
key_obj = double(cache_key: 'custom-key')
|
49
|
+
|
50
|
+
cache.write(key_obj, 'some-value')
|
51
|
+
|
52
|
+
expect(cache.read('custom-key')).to eq('some-value')
|
53
|
+
end
|
46
54
|
end
|
47
55
|
|
48
56
|
describe '#fetch' do
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'readthis/expanders'
|
2
|
+
|
3
|
+
RSpec.describe Readthis::Expanders do
|
4
|
+
def expand(key, namespace = nil)
|
5
|
+
Readthis::Expanders.expand(key, namespace)
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#expand' do
|
9
|
+
it 'namespaces a plain string' do
|
10
|
+
expect(expand('thing', 'space')).to eq('space:thing')
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'expands an object that has a cache_key method' do
|
14
|
+
object = double(cache_key: 'custom-key')
|
15
|
+
|
16
|
+
expect(expand(object)).to eq('custom-key')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'expands an array of objects' do
|
20
|
+
object = double(cache_key: 'gamma')
|
21
|
+
|
22
|
+
expect(expand(['alpha', 'beta'])).to eq('alpha:beta')
|
23
|
+
expect(expand([object, object])).to eq('gamma:gamma')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'readthis/notifications'
|
2
|
+
|
3
|
+
RSpec.describe Readthis::Notifications do
|
4
|
+
describe '#instrument' do
|
5
|
+
it 'yields the provided block' do
|
6
|
+
inner = double(:inner)
|
7
|
+
|
8
|
+
expect(inner).to receive(:call)
|
9
|
+
|
10
|
+
Readthis::Notifications.instrument('operation', key: 'key') do
|
11
|
+
inner.call
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: readthis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Parker Selbert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -42,30 +42,30 @@ dependencies:
|
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -89,6 +89,7 @@ extra_rdoc_files: []
|
|
89
89
|
files:
|
90
90
|
- ".gitignore"
|
91
91
|
- ".rspec"
|
92
|
+
- ".travis.yml"
|
92
93
|
- CHANGELOG.md
|
93
94
|
- Gemfile
|
94
95
|
- LICENSE.txt
|
@@ -98,9 +99,13 @@ files:
|
|
98
99
|
- lib/active_support/cache/readthis_store.rb
|
99
100
|
- lib/readthis.rb
|
100
101
|
- lib/readthis/cache.rb
|
102
|
+
- lib/readthis/expanders.rb
|
103
|
+
- lib/readthis/notifications.rb
|
101
104
|
- lib/readthis/version.rb
|
102
105
|
- readthis.gemspec
|
103
106
|
- spec/readthis/cache_spec.rb
|
107
|
+
- spec/readthis/expanders_spec.rb
|
108
|
+
- spec/readthis/notifications_spec.rb
|
104
109
|
- spec/spec_helper.rb
|
105
110
|
homepage: https://github.com/sorentwo/readthis
|
106
111
|
licenses:
|
@@ -128,4 +133,6 @@ specification_version: 4
|
|
128
133
|
summary: Pooled active support compliant caching with redis
|
129
134
|
test_files:
|
130
135
|
- spec/readthis/cache_spec.rb
|
136
|
+
- spec/readthis/expanders_spec.rb
|
137
|
+
- spec/readthis/notifications_spec.rb
|
131
138
|
- spec/spec_helper.rb
|