readthis 0.8.1 → 1.0.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/README.md +31 -9
- data/lib/active_support/cache/readthis_store.rb +1 -1
- data/lib/readthis/cache.rb +24 -29
- data/lib/readthis/entity.rb +120 -28
- data/lib/readthis/expanders.rb +1 -1
- data/lib/readthis/serializers.rb +111 -0
- data/lib/readthis/version.rb +1 -1
- data/lib/readthis.rb +6 -0
- data/spec/readthis/cache_spec.rb +68 -20
- data/spec/readthis/entity_spec.rb +69 -12
- data/spec/readthis/expanders_spec.rb +1 -1
- data/spec/readthis/serializers_spec.rb +87 -0
- data/spec/readthis_spec.rb +9 -0
- data/spec/spec_helper.rb +1 -3
- metadata +23 -24
- data/.gitignore +0 -15
- data/.rspec +0 -2
- data/.travis.yml +0 -15
- data/CHANGELOG.md +0 -114
- data/CONTRIBUTING.md +0 -14
- data/Gemfile +0 -14
- data/LICENSE.txt +0 -22
- data/PERFORMANCE.md +0 -73
- data/Rakefile +0 -2
- data/benchmarks/compressed.rb +0 -74
- data/benchmarks/driver.rb +0 -18
- data/benchmarks/marshalling.rb +0 -40
- data/benchmarks/memory.rb +0 -11
- data/benchmarks/multi.rb +0 -64
- data/benchmarks/profile.rb +0 -20
- data/bin/rspec +0 -16
- data/lib/readthis/notifications.rb +0 -7
- data/readthis.gemspec +0 -27
- data/spec/readthis/notifications_spec.rb +0 -15
data/benchmarks/compressed.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
|
3
|
-
Bundler.setup
|
4
|
-
|
5
|
-
require 'benchmark/ips'
|
6
|
-
require 'dalli'
|
7
|
-
require 'active_support'
|
8
|
-
require 'active_support/cache/dalli_store'
|
9
|
-
require 'readthis'
|
10
|
-
|
11
|
-
dalli = ActiveSupport::Cache::DalliStore.new(
|
12
|
-
'localhost',
|
13
|
-
pool_size: 5,
|
14
|
-
compressed: true,
|
15
|
-
compression_threshold: 8
|
16
|
-
)
|
17
|
-
|
18
|
-
readthis = Readthis::Cache.new(
|
19
|
-
pool_size: 5,
|
20
|
-
compressed: true,
|
21
|
-
compression_threshold: 128
|
22
|
-
)
|
23
|
-
|
24
|
-
KEY = 'key'
|
25
|
-
TEXT = <<-TEXT
|
26
|
-
An abstract cache store class. There are multiple cache store implementations, each having its own additional features. See the classes under the ActiveSupport::Cache module, e.g. ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most popular cache store for large production websites.
|
27
|
-
Some implementations may not support all methods beyond the basic cache methods of fetch, write, read, exist?, and delete.
|
28
|
-
ActiveSupport::Cache::Store can store any serializable Ruby object.
|
29
|
-
cache = ActiveSupport::Cache::MemoryStore.new
|
30
|
-
cache.read('city') # => nil
|
31
|
-
cache.write('city', "Duckburgh")
|
32
|
-
cache.read('city') # => "Duckburgh"
|
33
|
-
Keys are always translated into Strings and are case sensitive. When an object is specified as a key and has a cache_key method defined, this method will be called to define the key. Otherwise, the to_param method will be called. Hashes and Arrays can also be used as keys. The elements will be delimited by slashes, and the elements within a Hash will be sorted by key so they are consistent.
|
34
|
-
cache.read('city') == cache.read(:city) # => true
|
35
|
-
Nil values can be cached.
|
36
|
-
If your cache is on a shared infrastructure, you can define a namespace for your cache entries. If a namespace is defined, it will be prefixed on to every key. The namespace can be either a static value or a Proc. If it is a Proc, it will be invoked when each key is evaluated so that you can use application logic to invalidate keys.
|
37
|
-
cache.namespace = -> { @last_mod_time } # Set the namespace to a variable
|
38
|
-
@last_mod_time = Time.now # Invalidate the entire cache by changing namespace
|
39
|
-
Caches can also store values in a compressed format to save space and reduce time spent sending data. Since there is overhead, values must be large enough to warrant compression. To turn on compression either pass compress: true in the initializer or as an option to fetch or write. To specify the threshold at which to compress values, set the :compress_threshold option. The default threshold is 16K.
|
40
|
-
TEXT
|
41
|
-
|
42
|
-
puts 'Compressed Write/Read:'
|
43
|
-
Benchmark.ips do |x|
|
44
|
-
x.report 'readthis:write/read' do
|
45
|
-
readthis.write(KEY, TEXT)
|
46
|
-
readthis.read(KEY)
|
47
|
-
end
|
48
|
-
|
49
|
-
x.report 'dalli:write/read' do
|
50
|
-
dalli.write(KEY, TEXT)
|
51
|
-
dalli.read(KEY)
|
52
|
-
end
|
53
|
-
|
54
|
-
x.compare!
|
55
|
-
end
|
56
|
-
|
57
|
-
puts 'Compressed Read Multi:'
|
58
|
-
MULTI_KEY = (1..30).to_a
|
59
|
-
MULTI_KEY.each do |key|
|
60
|
-
readthis.write(key, TEXT)
|
61
|
-
dalli.write(key, TEXT)
|
62
|
-
end
|
63
|
-
|
64
|
-
Benchmark.ips do |x|
|
65
|
-
x.report 'readthis:read_multi' do
|
66
|
-
readthis.read_multi(*MULTI_KEY)
|
67
|
-
end
|
68
|
-
|
69
|
-
x.report 'dalli:read_multi' do
|
70
|
-
dalli.read_multi(*MULTI_KEY)
|
71
|
-
end
|
72
|
-
|
73
|
-
x.compare!
|
74
|
-
end
|
data/benchmarks/driver.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
|
3
|
-
Bundler.setup
|
4
|
-
|
5
|
-
require 'benchmark/ips'
|
6
|
-
require 'readthis'
|
7
|
-
|
8
|
-
native = Readthis::Cache.new(redis: { driver: :ruby }, expires_in: 60)
|
9
|
-
hiredis = Readthis::Cache.new(redis: { driver: :hiredis }, expires_in: 60)
|
10
|
-
|
11
|
-
('a'..'z').each { |key| native.write(key, key * 1024) }
|
12
|
-
|
13
|
-
Benchmark.ips do |x|
|
14
|
-
x.report('native:read-multi') { native.read_multi(*('a'..'z')) }
|
15
|
-
x.report('hiredis:read-multi') { hiredis.read_multi(*('a'..'z')) }
|
16
|
-
|
17
|
-
x.compare!
|
18
|
-
end
|
data/benchmarks/marshalling.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
|
3
|
-
Bundler.setup
|
4
|
-
|
5
|
-
require 'benchmark/ips'
|
6
|
-
require 'json'
|
7
|
-
require 'oj'
|
8
|
-
require 'msgpack'
|
9
|
-
require 'readthis'
|
10
|
-
require 'readthis/passthrough'
|
11
|
-
|
12
|
-
OPTIONS = { compressed: false }
|
13
|
-
|
14
|
-
readthis_pass = Readthis::Cache.new(OPTIONS.merge(marshal: Readthis::Passthrough))
|
15
|
-
readthis_oj = Readthis::Cache.new(OPTIONS.merge(marshal: Oj))
|
16
|
-
readthis_msgpack = Readthis::Cache.new(OPTIONS.merge(marshal: MessagePack))
|
17
|
-
readthis_json = Readthis::Cache.new(OPTIONS.merge(marshal: JSON))
|
18
|
-
readthis_ruby = Readthis::Cache.new(OPTIONS.merge(marshal: Marshal))
|
19
|
-
|
20
|
-
HASH = ('a'..'z').each_with_object({}) { |key, memo| memo[key] = key }
|
21
|
-
|
22
|
-
Benchmark.ips do |x|
|
23
|
-
x.report('pass:hash:dump') { readthis_pass.write('pass', HASH) }
|
24
|
-
x.report('oj:hash:dump') { readthis_oj.write('oj', HASH) }
|
25
|
-
x.report('json:hash:dump') { readthis_json.write('json', HASH) }
|
26
|
-
x.report('msgpack:hash:dump') { readthis_msgpack.write('msgpack', HASH) }
|
27
|
-
x.report('ruby:hash:dump') { readthis_ruby.write('ruby', HASH) }
|
28
|
-
|
29
|
-
x.compare!
|
30
|
-
end
|
31
|
-
|
32
|
-
Benchmark.ips do |x|
|
33
|
-
x.report('pass:hash:load') { readthis_pass.read('pass') }
|
34
|
-
x.report('oj:hash:load') { readthis_oj.read('oj') }
|
35
|
-
x.report('json:hash:load') { readthis_json.read('json') }
|
36
|
-
x.report('msgpack:hash:load') { readthis_msgpack.read('msgpack') }
|
37
|
-
x.report('ruby:hash:load') { readthis_ruby.read('ruby') }
|
38
|
-
|
39
|
-
x.compare!
|
40
|
-
end
|
data/benchmarks/memory.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'bundler'; Bundler.setup
|
2
|
-
a = GC.stat(:total_allocated_objects)
|
3
|
-
|
4
|
-
require 'readthis'
|
5
|
-
b = GC.stat(:total_allocated_objects)
|
6
|
-
|
7
|
-
require 'redis-activesupport'
|
8
|
-
c = GC.stat(:total_allocated_objects)
|
9
|
-
|
10
|
-
puts "readthis: #{b - a}"
|
11
|
-
puts "redis-activesupport: #{c - b}"
|
data/benchmarks/multi.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
|
3
|
-
Bundler.setup
|
4
|
-
|
5
|
-
require 'benchmark/ips'
|
6
|
-
require 'dalli'
|
7
|
-
require 'redis-activesupport'
|
8
|
-
require 'active_support/cache/memory_store'
|
9
|
-
require 'active_support/cache/dalli_store'
|
10
|
-
require 'readthis'
|
11
|
-
|
12
|
-
memory = ActiveSupport::Cache::MemoryStore.new(expires_in: 60, namespace: 'mm')
|
13
|
-
dalli = ActiveSupport::Cache::DalliStore.new('localhost', namespace: 'da', pool_size: 5, expires_in: 60)
|
14
|
-
redisas = ActiveSupport::Cache::RedisStore.new('redis://localhost:6379/11/ra', expires_in: 60)
|
15
|
-
readthis = Readthis::Cache.new(namespace: 'rd', expires_in: 60)
|
16
|
-
|
17
|
-
('a'..'z').each do |key|
|
18
|
-
value = key * 1024
|
19
|
-
|
20
|
-
memory.write(key, value)
|
21
|
-
dalli.write(key, value)
|
22
|
-
readthis.write(key, value)
|
23
|
-
redisas.write(key, value)
|
24
|
-
end
|
25
|
-
|
26
|
-
Benchmark.ips do |x|
|
27
|
-
x.report 'memory:read-multi' do
|
28
|
-
memory.read_multi(*('a'..'z'))
|
29
|
-
end
|
30
|
-
|
31
|
-
x.report 'readthis:read-multi' do
|
32
|
-
readthis.read_multi(*('a'..'z'))
|
33
|
-
end
|
34
|
-
|
35
|
-
x.report 'redisas:read-multi' do
|
36
|
-
redisas.read_multi(*('a'..'z'))
|
37
|
-
end
|
38
|
-
|
39
|
-
x.report 'dalli:read-multi' do
|
40
|
-
dalli.read_multi(*('a'..'z'))
|
41
|
-
end
|
42
|
-
|
43
|
-
x.compare!
|
44
|
-
end
|
45
|
-
|
46
|
-
Benchmark.ips do |x|
|
47
|
-
x.report 'memory:fetch-multi' do
|
48
|
-
memory.fetch_multi(*('a'..'z')) { |_| 'missing' }
|
49
|
-
end
|
50
|
-
|
51
|
-
x.report 'readthis:fetch-multi' do
|
52
|
-
readthis.fetch_multi(*('a'..'z')) { |_| 'missing' }
|
53
|
-
end
|
54
|
-
|
55
|
-
x.report 'redisas:fetch-multi' do
|
56
|
-
redisas.fetch_multi(*('a'..'z')) { |_| 'missing' }
|
57
|
-
end
|
58
|
-
|
59
|
-
x.report 'dalli:fetch-multi' do
|
60
|
-
dalli.fetch_multi(*('a'..'z')) { |_| 'missing' }
|
61
|
-
end
|
62
|
-
|
63
|
-
x.compare!
|
64
|
-
end
|
data/benchmarks/profile.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
|
3
|
-
Bundler.setup
|
4
|
-
|
5
|
-
require 'fileutils'
|
6
|
-
require 'stackprof'
|
7
|
-
require 'readthis'
|
8
|
-
|
9
|
-
readthis = Readthis::Cache.new('redis://localhost:6379/11')
|
10
|
-
|
11
|
-
FileUtils.mkdir_p('tmp')
|
12
|
-
readthis.clear
|
13
|
-
|
14
|
-
('a'..'z').each { |key| readthis.write(key, key * 1024) }
|
15
|
-
|
16
|
-
StackProf.run(mode: :object, interval: 500, out: "tmp/stackprof-object.dump") do
|
17
|
-
1000.times do
|
18
|
-
readthis.read_multi(*('a'..'z'))
|
19
|
-
end
|
20
|
-
end
|
data/bin/rspec
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# This file was generated by Bundler.
|
4
|
-
#
|
5
|
-
# The application 'rspec' is installed as part of a gem, and
|
6
|
-
# this file is here to facilitate running it.
|
7
|
-
#
|
8
|
-
|
9
|
-
require 'pathname'
|
10
|
-
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
-
Pathname.new(__FILE__).realpath)
|
12
|
-
|
13
|
-
require 'rubygems'
|
14
|
-
require 'bundler/setup'
|
15
|
-
|
16
|
-
load Gem.bin_path('rspec-core', 'rspec')
|
data/readthis.gemspec
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'readthis/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = 'readthis'
|
8
|
-
spec.version = Readthis::VERSION
|
9
|
-
spec.authors = ['Parker Selbert']
|
10
|
-
spec.email = ['parker@sorentwo.com']
|
11
|
-
spec.summary = 'Pooled active support compliant caching with redis'
|
12
|
-
spec.description = 'Pooled active support compliant caching with redis'
|
13
|
-
spec.homepage = 'https://github.com/sorentwo/readthis'
|
14
|
-
spec.license = 'MIT'
|
15
|
-
|
16
|
-
spec.files = `git ls-files -z`.split("\x0")
|
17
|
-
spec.test_files = spec.files.grep(%r{^(spec)/})
|
18
|
-
spec.require_paths = ['lib']
|
19
|
-
|
20
|
-
spec.add_dependency 'redis', '~> 3.0'
|
21
|
-
spec.add_dependency 'connection_pool', '~> 2.1'
|
22
|
-
|
23
|
-
spec.add_development_dependency 'bundler'
|
24
|
-
spec.add_development_dependency 'hiredis', '~> 0.5'
|
25
|
-
spec.add_development_dependency 'rake'
|
26
|
-
spec.add_development_dependency 'rspec', '~> 3.1'
|
27
|
-
end
|
@@ -1,15 +0,0 @@
|
|
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
|