memcached_store 0.10.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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +37 -0
- data/LICENSE +22 -0
- data/README.md +40 -0
- data/Rakefile +32 -0
- data/lib/active_support/cache/memcached_snappy_store.rb +38 -0
- data/lib/memcached_store.rb +2 -0
- data/lib/memcached_store/memcached_safety.rb +68 -0
- data/lib/memcached_store/version.rb +4 -0
- data/memcached_store.gemspec +27 -0
- data/test/test_helper.rb +8 -0
- data/test/test_memcached_safety.rb +137 -0
- data/test/test_memcached_snappy_store.rb +95 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a42e70078b5eda9cbbaf458f14785c0dacf41ebc
|
4
|
+
data.tar.gz: aae001ea0804778071cb51f155f85b625523ac02
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 77432128fdc4ea38984673d5551f13c2ff2abc886b96989dcd7f6db8a0de9d37d5e5648610feb055560ab5db56811fee02b307c9eea021ce2d0c00e371880819
|
7
|
+
data.tar.gz: fb8da4066ef04dcaea44d7fa746aa26a4b47d3c25e30971c2b8e52a59d693a0bf99e4285aae7c68ecbe42e6c136f4a5076d9e2d13afeabe3d835024dec3ec5fa
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
memcached_store (0.10.0)
|
5
|
+
activesupport (>= 3.2)
|
6
|
+
snappy (= 0.0.4)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (3.2.13)
|
12
|
+
i18n (= 0.6.1)
|
13
|
+
multi_json (~> 1.0)
|
14
|
+
i18n (0.6.1)
|
15
|
+
memcache-client (1.8.5)
|
16
|
+
memcached (1.5.0)
|
17
|
+
metaclass (0.0.1)
|
18
|
+
minitest (4.7.1)
|
19
|
+
mocha (0.13.3)
|
20
|
+
metaclass (~> 0.0.1)
|
21
|
+
multi_json (1.8.3)
|
22
|
+
rake (10.0.4)
|
23
|
+
snappy (0.0.4)
|
24
|
+
timecop (0.6.1)
|
25
|
+
|
26
|
+
PLATFORMS
|
27
|
+
ruby
|
28
|
+
|
29
|
+
DEPENDENCIES
|
30
|
+
i18n
|
31
|
+
memcache-client
|
32
|
+
memcached
|
33
|
+
memcached_store!
|
34
|
+
minitest
|
35
|
+
mocha
|
36
|
+
rake
|
37
|
+
timecop
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Camilo Lopez
|
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,40 @@
|
|
1
|
+
# MemcachedSnappyStore
|
2
|
+
|
3
|
+
ActiveSupport cache store that adds snappy compression at the cost of making the ```incr, decr, add``` operations unavailable.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'memcached_snappy_store'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install memcached_snappy_store
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
In your environment file:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
|
25
|
+
config.cache_store = :memcached_snappy_store,
|
26
|
+
Memcached::Rails.new(:servers => ['memcached1.foo.com', 'memcached2.foo.com'])
|
27
|
+
|
28
|
+
```
|
29
|
+
|
30
|
+
## Code status
|
31
|
+
|
32
|
+
[](https://travis-ci.org/Shopify/rails_cache_adapters)
|
33
|
+
|
34
|
+
## Contributing
|
35
|
+
|
36
|
+
1. Fork it
|
37
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
38
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
39
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
40
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
5
|
+
require "memcached_store/version"
|
6
|
+
|
7
|
+
task :default => 'test'
|
8
|
+
|
9
|
+
desc 'run test suite with default parser'
|
10
|
+
Rake::TestTask.new do |t|
|
11
|
+
t.libs << "test"
|
12
|
+
t.libs << "lib/**/*"
|
13
|
+
t.test_files = FileList['test/test*.rb']
|
14
|
+
t.verbose = true
|
15
|
+
end
|
16
|
+
|
17
|
+
task :gem => :build
|
18
|
+
task :build do
|
19
|
+
system "gem build memcached_store.gemspec"
|
20
|
+
end
|
21
|
+
|
22
|
+
task :install => :build do
|
23
|
+
system "gem install memcached_store-#{MemcachedStore::VERSION}.gem"
|
24
|
+
end
|
25
|
+
|
26
|
+
task :release => :build do
|
27
|
+
system "git commit -m'Released version #{MemcachedStore::VERSION}' --allow-empty"
|
28
|
+
system "git tag -a v#{MemcachedStore::VERSION} -m 'Tagging #{MemcachedStore::VERSION}'"
|
29
|
+
system "git push --tags"
|
30
|
+
system "gem push memcached_store-#{MemcachedStore::VERSION}.gem"
|
31
|
+
system "rm memcached_store-#{MemcachedStore::VERSION}.gem"
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
module Cache
|
3
|
+
class MemcachedSnappyStore < Cache::MemCacheStore
|
4
|
+
class UnsupportedOperation < StandardError; end
|
5
|
+
|
6
|
+
def increment(*args)
|
7
|
+
raise UnsupportedOperation.new("increment is not supported by: #{self.class.name}")
|
8
|
+
end
|
9
|
+
|
10
|
+
def decrement(*args)
|
11
|
+
raise UnsupportedOperation.new("decrement is not supported by: #{self.class.name}")
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def write_entry(key, entry, options)
|
17
|
+
# normally unless_exist would make this method use add, add will not make sense on compressed entries
|
18
|
+
raise UnsupportedOperation.new("unless_exist would try to use the unsupported add method") if options && options[:unless_exist]
|
19
|
+
|
20
|
+
serialized_value = options[:raw] ? entry.value.to_s : Marshal.dump(entry)
|
21
|
+
expires_in = options[:expires_in].to_i
|
22
|
+
if expires_in > 0 && !options[:raw]
|
23
|
+
# Set the memcache expire a few minutes in the future to support race condition ttls on read
|
24
|
+
expires_in += 5.minutes
|
25
|
+
end
|
26
|
+
|
27
|
+
serialized_compressed_value = Snappy.deflate(serialized_value)
|
28
|
+
|
29
|
+
response = @data.set(escape_key(key), serialized_compressed_value, expires_in, true)
|
30
|
+
end
|
31
|
+
|
32
|
+
def deserialize_entry(compressed_value)
|
33
|
+
decompressed_value = compressed_value.nil? ? compressed_value : Snappy.inflate(compressed_value)
|
34
|
+
super(decompressed_value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module MemcachedStore
|
2
|
+
class MemcachedSafety < Memcached::Rails
|
3
|
+
|
4
|
+
FATAL_EXCEPTIONS = [ Memcached::ABadKeyWasProvidedOrCharactersOutOfRange,
|
5
|
+
Memcached::AKeyLengthOfZeroWasProvided,
|
6
|
+
Memcached::ConnectionBindFailure,
|
7
|
+
Memcached::ConnectionDataDoesNotExist,
|
8
|
+
Memcached::ConnectionFailure,
|
9
|
+
Memcached::ConnectionSocketCreateFailure,
|
10
|
+
Memcached::CouldNotOpenUnixSocket,
|
11
|
+
Memcached::NoServersDefined,
|
12
|
+
Memcached::TheHostTransportProtocolDoesNotMatchThatOfTheClient
|
13
|
+
]
|
14
|
+
|
15
|
+
if defined?(::Rails) && ::Rails.env.test?
|
16
|
+
NONFATAL_EXCEPTIONS = []
|
17
|
+
else
|
18
|
+
NONFATAL_EXCEPTIONS = Memcached::EXCEPTIONS - FATAL_EXCEPTIONS
|
19
|
+
end
|
20
|
+
|
21
|
+
SIZE_LIMIT = 2 * 1024 * 1024
|
22
|
+
|
23
|
+
def exist_with_rescue?(*args)
|
24
|
+
exist_without_rescue?(*args)
|
25
|
+
rescue *NONFATAL_EXCEPTIONS
|
26
|
+
end
|
27
|
+
alias_method :exist_without_rescue?, :exist?
|
28
|
+
alias_method :exist?, :exist_with_rescue?
|
29
|
+
|
30
|
+
def cas_with_rescue(*args)
|
31
|
+
cas_without_rescue(*args)
|
32
|
+
rescue *NONFATAL_EXCEPTIONS
|
33
|
+
false
|
34
|
+
end
|
35
|
+
alias_method_chain :cas, :rescue
|
36
|
+
|
37
|
+
def get_multi_with_rescue(*args)
|
38
|
+
get_multi_without_rescue(*args)
|
39
|
+
rescue *NONFATAL_EXCEPTIONS
|
40
|
+
{}
|
41
|
+
end
|
42
|
+
alias_method_chain :get_multi, :rescue
|
43
|
+
|
44
|
+
def set_with_rescue(*args)
|
45
|
+
set_without_rescue(*args)
|
46
|
+
rescue *NONFATAL_EXCEPTIONS
|
47
|
+
false
|
48
|
+
end
|
49
|
+
alias_method_chain :set, :rescue
|
50
|
+
|
51
|
+
def add_with_rescue(*args)
|
52
|
+
add_without_rescue(*args)
|
53
|
+
rescue *NONFATAL_EXCEPTIONS
|
54
|
+
@string_return_types? "NOT STORED\r\n" : true
|
55
|
+
end
|
56
|
+
alias_method_chain :add, :rescue
|
57
|
+
|
58
|
+
%w{get delete incr decr append prepend}.each do |meth|
|
59
|
+
class_eval <<-ENV
|
60
|
+
def #{meth}_with_rescue(*args)
|
61
|
+
#{meth}_without_rescue(*args)
|
62
|
+
rescue *NONFATAL_EXCEPTIONS
|
63
|
+
end
|
64
|
+
alias_method_chain :#{meth}, :rescue
|
65
|
+
ENV
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
require "memcached_store/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.authors = ["Camilo Lopez", "Tom Burns", "Arthur Neves"]
|
8
|
+
gem.email = ["camilo@camilolopez.com", "tom.burns@shopify.com", "arthurnn@gmail.com"]
|
9
|
+
gem.summary = gem.description = %q{Plugin-able Memcached adapters to add features (compression, safety)}
|
10
|
+
gem.homepage = "https://github.com/Shopify/memcached_store/"
|
11
|
+
|
12
|
+
gem.files = `git ls-files`.split($\)
|
13
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
+
gem.name = "memcached_store"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = MemcachedStore::VERSION
|
18
|
+
gem.add_runtime_dependency "activesupport", ">= 3.2"
|
19
|
+
gem.add_runtime_dependency "snappy", "0.0.4"
|
20
|
+
gem.add_development_dependency "i18n"
|
21
|
+
gem.add_development_dependency "rake"
|
22
|
+
gem.add_development_dependency "minitest"
|
23
|
+
gem.add_development_dependency "mocha"
|
24
|
+
gem.add_development_dependency "timecop"
|
25
|
+
gem.add_development_dependency "memcached"
|
26
|
+
gem.add_development_dependency "memcache-client"
|
27
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestMemcachedSafety < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
@cache = MemcachedStore::MemcachedSafety.new(["localhost:21211"])
|
6
|
+
@entry = ActiveSupport::Cache::Entry.new({:omg => "ponies"})
|
7
|
+
end
|
8
|
+
|
9
|
+
test "exist? absorbs non-fatal exceptions" do
|
10
|
+
expect_nonfatal(:exist_without_rescue?)
|
11
|
+
@cache.exist?("a-key")
|
12
|
+
end
|
13
|
+
|
14
|
+
test "exist? raises fatal exceptions" do
|
15
|
+
expect_fatal(:exist_without_rescue?)
|
16
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
17
|
+
@cache.exist?("a-key")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
test "cas absorbs non-fatal exceptions" do
|
22
|
+
expect_nonfatal(:cas_without_rescue)
|
23
|
+
@cache.cas("a-key") { 1 }
|
24
|
+
end
|
25
|
+
|
26
|
+
test "cas raises fatal exceptions" do
|
27
|
+
expect_fatal(:cas_without_rescue)
|
28
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
29
|
+
@cache.cas("a-key") { 1 }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
test "get_multi absorbs non-fatal exceptions" do
|
34
|
+
expect_nonfatal(:get_multi_without_rescue)
|
35
|
+
@cache.get_multi(["a-key"])
|
36
|
+
end
|
37
|
+
|
38
|
+
test "get_multi raises fatal exceptions" do
|
39
|
+
expect_fatal(:get_multi_without_rescue)
|
40
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
41
|
+
@cache.get_multi(["a-key"])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
test "set absorbs non-fatal exceptions" do
|
46
|
+
expect_nonfatal(:set_without_rescue)
|
47
|
+
@cache.set("a-key", @entry)
|
48
|
+
end
|
49
|
+
|
50
|
+
test "set raises fatal exceptions" do
|
51
|
+
expect_fatal(:set_without_rescue)
|
52
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
53
|
+
@cache.set("a-key", @entry)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
test "add absorbs non-fatal exceptions" do
|
58
|
+
expect_nonfatal(:add_without_rescue)
|
59
|
+
@cache.add("a-key", "val")
|
60
|
+
end
|
61
|
+
|
62
|
+
test "add raises fatal exceptions" do
|
63
|
+
expect_fatal(:add_without_rescue)
|
64
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
65
|
+
@cache.add("a-key", "val")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
test "delete absorbs non-fatal exceptions" do
|
70
|
+
expect_nonfatal(:delete_without_rescue)
|
71
|
+
@cache.delete("a-key")
|
72
|
+
end
|
73
|
+
|
74
|
+
test "delete raises fatal exceptions" do
|
75
|
+
expect_fatal(:delete_without_rescue)
|
76
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
77
|
+
@cache.delete("a-key")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
test "incr absorbs non-fatal exceptions" do
|
82
|
+
expect_nonfatal(:incr_without_rescue)
|
83
|
+
@cache.incr("a-key")
|
84
|
+
end
|
85
|
+
|
86
|
+
test "incr raises fatal exceptions" do
|
87
|
+
expect_fatal(:incr_without_rescue)
|
88
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
89
|
+
@cache.incr("a-key")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
test "decr absorbs non-fatal exceptions" do
|
94
|
+
expect_nonfatal(:decr_without_rescue)
|
95
|
+
@cache.decr("a-key")
|
96
|
+
end
|
97
|
+
|
98
|
+
test "decr raises fatal exceptions" do
|
99
|
+
expect_fatal(:decr_without_rescue)
|
100
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
101
|
+
@cache.decr("a-key")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
test "append absorbs non-fatal exceptions" do
|
106
|
+
expect_nonfatal(:append_without_rescue)
|
107
|
+
@cache.append("a-key", "other")
|
108
|
+
end
|
109
|
+
|
110
|
+
test "append raises fatal exceptions" do
|
111
|
+
expect_fatal(:append_without_rescue)
|
112
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
113
|
+
@cache.append("a-key", "other")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
test "prepend absorbs non-fatal exceptions" do
|
118
|
+
expect_nonfatal(:prepend_without_rescue)
|
119
|
+
@cache.prepend("a-key", "other")
|
120
|
+
end
|
121
|
+
|
122
|
+
test "prepend raises fatal exceptions" do
|
123
|
+
expect_fatal(:prepend_without_rescue)
|
124
|
+
assert_raises(Memcached::AKeyLengthOfZeroWasProvided) do
|
125
|
+
@cache.prepend("a-key", "other")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
private
|
129
|
+
|
130
|
+
def expect_nonfatal(sym)
|
131
|
+
MemcachedStore::MemcachedSafety.any_instance.expects(sym).raises(Memcached::ServerIsMarkedDead)
|
132
|
+
end
|
133
|
+
|
134
|
+
def expect_fatal(sym)
|
135
|
+
MemcachedStore::MemcachedSafety.any_instance.expects(sym).raises(Memcached::AKeyLengthOfZeroWasProvided)
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestMemcachedSnappyStore < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
setup do
|
6
|
+
@cache = ActiveSupport::Cache.lookup_store(:memcached_snappy_store, Memcached::Rails.new(["localhost:11211"]))
|
7
|
+
@cache.clear
|
8
|
+
end
|
9
|
+
|
10
|
+
test "test should not allow increment" do
|
11
|
+
assert_raise(ActiveSupport::Cache::MemcachedSnappyStore::UnsupportedOperation) do
|
12
|
+
@cache.increment('foo')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
test "should not allow decrement" do
|
17
|
+
assert_raise(ActiveSupport::Cache::MemcachedSnappyStore::UnsupportedOperation) do
|
18
|
+
@cache.decrement('foo')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
test "write should not allow the implicit add operation when unless_exist is passed to write" do
|
23
|
+
assert_raise(ActiveSupport::Cache::MemcachedSnappyStore::UnsupportedOperation) do
|
24
|
+
@cache.write('foo', 'bar', :unless_exist => true)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
test "should use snappy to write cache entries" do
|
29
|
+
# Freezing time so created_at is the same in entry and the entry created
|
30
|
+
# internally and assert_equal between the raw data in the cache and the
|
31
|
+
# compressed explicitly makes sense
|
32
|
+
Timecop.freeze do
|
33
|
+
entry_value = { :omg => 'data' }
|
34
|
+
entry = ActiveSupport::Cache::Entry.new(entry_value)
|
35
|
+
key = 'moarponies'
|
36
|
+
assert @cache.write(key, entry_value)
|
37
|
+
|
38
|
+
serialized_entry = Marshal.dump(entry)
|
39
|
+
serialized_compressed_entry = Snappy.deflate(serialized_entry)
|
40
|
+
actual_cache_value = @cache.instance_variable_get(:@data).get(key, true)
|
41
|
+
|
42
|
+
assert_equal serialized_compressed_entry, actual_cache_value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
test "should use snappy to read cache entries" do
|
47
|
+
entry_value = { :omg => 'data' }
|
48
|
+
key = 'ponies'
|
49
|
+
|
50
|
+
@cache.write(key, entry_value)
|
51
|
+
cache_entry = ActiveSupport::Cache::Entry.new(entry_value)
|
52
|
+
serialized_cached_entry = Marshal.dump(cache_entry)
|
53
|
+
|
54
|
+
Snappy.expects(:inflate).returns(serialized_cached_entry)
|
55
|
+
assert_equal entry_value, @cache.read(key)
|
56
|
+
end
|
57
|
+
|
58
|
+
test "should skip snappy to reading not found" do
|
59
|
+
key = 'ponies2'
|
60
|
+
Snappy.expects(:inflate).never
|
61
|
+
assert_nil @cache.read(key)
|
62
|
+
end
|
63
|
+
|
64
|
+
test "should use snappy to multi read cache entries but not on missing entries" do
|
65
|
+
keys = %w{ one tow three }
|
66
|
+
values = keys.map{ |k| k * 10 }
|
67
|
+
entries = values.map{ |v| ActiveSupport::Cache::Entry.new(v) }
|
68
|
+
|
69
|
+
keys.each_with_index{ |k, i| @cache.write(k, values[i]) }
|
70
|
+
|
71
|
+
keys_and_missing = keys << 'missing'
|
72
|
+
|
73
|
+
Snappy.expects(:inflate).times(3).returns(*entries)
|
74
|
+
assert_equal values, @cache.read_multi(*keys_and_missing).values
|
75
|
+
end
|
76
|
+
|
77
|
+
test "should use snappy to multi read cache entries" do
|
78
|
+
keys = %w{ one tow three }
|
79
|
+
values = keys.map{ |k| k * 10 }
|
80
|
+
entries = values.map{ |v| ActiveSupport::Cache::Entry.new(v) }
|
81
|
+
|
82
|
+
keys.each_with_index{ |k, i| @cache.write(k, values[i]) }
|
83
|
+
|
84
|
+
Snappy.expects(:inflate).times(3).returns(*entries)
|
85
|
+
assert_equal values, @cache.read_multi(*keys).values
|
86
|
+
end
|
87
|
+
|
88
|
+
test "should support raw writes that don't use marshal format" do
|
89
|
+
key = 'key'
|
90
|
+
@cache.write(key, 'value', :raw => true)
|
91
|
+
|
92
|
+
actual_cache_value = @cache.instance_variable_get(:@data).get(key, true)
|
93
|
+
assert_equal 'value', Snappy.inflate(actual_cache_value)
|
94
|
+
end
|
95
|
+
end
|
metadata
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: memcached_store
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.10.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Camilo Lopez
|
8
|
+
- Tom Burns
|
9
|
+
- Arthur Neves
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2014-01-09 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.2'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '3.2'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: snappy
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - '='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 0.0.4
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - '='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.0.4
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: i18n
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
type: :development
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: rake
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: minitest
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: mocha
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
type: :development
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: timecop
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
type: :development
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: memcached
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
type: :development
|
121
|
+
prerelease: false
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: memcache-client
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
description: Plugin-able Memcached adapters to add features (compression, safety)
|
142
|
+
email:
|
143
|
+
- camilo@camilolopez.com
|
144
|
+
- tom.burns@shopify.com
|
145
|
+
- arthurnn@gmail.com
|
146
|
+
executables: []
|
147
|
+
extensions: []
|
148
|
+
extra_rdoc_files: []
|
149
|
+
files:
|
150
|
+
- ".gitignore"
|
151
|
+
- ".travis.yml"
|
152
|
+
- Gemfile
|
153
|
+
- Gemfile.lock
|
154
|
+
- LICENSE
|
155
|
+
- README.md
|
156
|
+
- Rakefile
|
157
|
+
- lib/active_support/cache/memcached_snappy_store.rb
|
158
|
+
- lib/memcached_store.rb
|
159
|
+
- lib/memcached_store/memcached_safety.rb
|
160
|
+
- lib/memcached_store/version.rb
|
161
|
+
- memcached_store.gemspec
|
162
|
+
- test/test_helper.rb
|
163
|
+
- test/test_memcached_safety.rb
|
164
|
+
- test/test_memcached_snappy_store.rb
|
165
|
+
homepage: https://github.com/Shopify/memcached_store/
|
166
|
+
licenses: []
|
167
|
+
metadata: {}
|
168
|
+
post_install_message:
|
169
|
+
rdoc_options: []
|
170
|
+
require_paths:
|
171
|
+
- lib
|
172
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
173
|
+
requirements:
|
174
|
+
- - ">="
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '0'
|
177
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
requirements: []
|
183
|
+
rubyforge_project:
|
184
|
+
rubygems_version: 2.2.0
|
185
|
+
signing_key:
|
186
|
+
specification_version: 4
|
187
|
+
summary: Plugin-able Memcached adapters to add features (compression, safety)
|
188
|
+
test_files:
|
189
|
+
- test/test_helper.rb
|
190
|
+
- test/test_memcached_safety.rb
|
191
|
+
- test/test_memcached_snappy_store.rb
|