memcached_store 0.12.8 → 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.
data/.gitignore DELETED
@@ -1,20 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- coverage
6
- InstalledFiles
7
- lib/bundler/man
8
- pkg
9
- rdoc
10
- spec/reports
11
- test/tmp
12
- test/version_tmp
13
- tmp
14
-
15
- # YARD artifacts
16
- .yardoc
17
- _yardoc
18
- doc/
19
-
20
- *.lock
@@ -1,16 +0,0 @@
1
- language: ruby
2
- services: memcache
3
- before_install:
4
- - gem update bundler
5
- rvm:
6
- - 1.9.3
7
- - 2.0.0
8
- - 2.1.0
9
- - 2.1.1
10
- env:
11
- - "AS_VERSION=3.2.18"
12
- - "AS_VERSION=4.0.5"
13
- - "AS_VERSION=4.1.0"
14
- matrix:
15
- allow_failures:
16
- - env: "AS_VERSION=4.1.0"
data/Gemfile DELETED
@@ -1,21 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in rails_cache_adapters.gemspec
4
- gemspec
5
-
6
- version = ENV["AS_VERSION"] || "4.0.5"
7
- as_version = case version
8
- when "master"
9
- {:github => "rails/rails"}
10
- else
11
- "~> #{version}"
12
- end
13
-
14
- gem "activesupport", as_version
15
-
16
- group :test do
17
- gem "minitest", '~> 4.0' if version == "3.2.18"
18
- gem "mocha"
19
- gem "timecop"
20
- gem "snappy"
21
- end
data/Rakefile DELETED
@@ -1,21 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'rake/testtask'
3
-
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 :tag => :build do
18
- system "git commit -m'Released version #{MemcachedStore::VERSION}' --allow-empty"
19
- system "git tag -a v#{MemcachedStore::VERSION} -m 'Tagging #{MemcachedStore::VERSION}'"
20
- system "git push --tags"
21
- end
@@ -1,88 +0,0 @@
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
- report_exception($!)
27
- end
28
- alias_method :exist_without_rescue?, :exist?
29
- alias_method :exist?, :exist_with_rescue?
30
-
31
- def cas_with_rescue(*args)
32
- cas_without_rescue(*args)
33
- rescue *NONFATAL_EXCEPTIONS
34
- report_exception($!)
35
- false
36
- end
37
- alias_method_chain :cas, :rescue
38
-
39
- def get_multi_with_rescue(*args)
40
- get_multi_without_rescue(*args)
41
- rescue *NONFATAL_EXCEPTIONS
42
- report_exception($!)
43
- {}
44
- end
45
- alias_method_chain :get_multi, :rescue
46
-
47
- def set_with_rescue(*args)
48
- set_without_rescue(*args)
49
- rescue *NONFATAL_EXCEPTIONS
50
- report_exception($!)
51
- false
52
- end
53
- alias_method_chain :set, :rescue
54
-
55
- def add_with_rescue(*args)
56
- add_without_rescue(*args)
57
- rescue *NONFATAL_EXCEPTIONS
58
- report_exception($!)
59
- @string_return_types? "NOT STORED\r\n" : true
60
- end
61
- alias_method_chain :add, :rescue
62
-
63
- %w{get delete incr decr append prepend}.each do |meth|
64
- class_eval <<-ENV
65
- def #{meth}_with_rescue(*args)
66
- #{meth}_without_rescue(*args)
67
- rescue *NONFATAL_EXCEPTIONS
68
- report_exception($!)
69
- end
70
- alias_method_chain :#{meth}, :rescue
71
- ENV
72
- end
73
-
74
- def logger
75
- return @logger if @logger
76
- @logger = ::Rails.logger if defined?(::Rails)
77
- end
78
-
79
- private
80
-
81
- def report_exception(exception)
82
- if defined?(::Rails)
83
- logger.error "[#{self.class}] exception=#{exception}"
84
- end
85
- nil # make sure return value is nil
86
- end
87
- end
88
- end
@@ -1,22 +0,0 @@
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", "Francis Bogsanyi"]
8
- gem.email = ["camilo@camilolopez.com", "tom.burns@shopify.com", "arthurnn@gmail.com", "francis.bogsanyi@shopify.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 "memcached", "~> 1.8.0"
20
-
21
- gem.add_development_dependency "rake"
22
- end
@@ -1,4 +0,0 @@
1
- dependencies:
2
- bundler:
3
- without:
4
- - test
@@ -1,21 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'mocha/setup'
3
- require 'timecop'
4
-
5
- require 'active_support/test_case'
6
-
7
- require 'memcached_store'
8
-
9
- class Rails
10
- def self.logger
11
- @logger ||= Logger.new("/dev/null")
12
- end
13
-
14
- def self.env
15
- Struct.new("Env") do
16
- def self.test?
17
- true
18
- end
19
- end
20
- end
21
- end
@@ -1,142 +0,0 @@
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
-
129
- test "logger defaults to rails logger" do
130
- assert_equal Rails.logger, @cache.logger
131
- end
132
-
133
- private
134
-
135
- def expect_nonfatal(sym)
136
- MemcachedStore::MemcachedSafety.any_instance.expects(sym).raises(Memcached::ServerIsMarkedDead)
137
- end
138
-
139
- def expect_fatal(sym)
140
- MemcachedStore::MemcachedSafety.any_instance.expects(sym).raises(Memcached::AKeyLengthOfZeroWasProvided)
141
- end
142
- end
@@ -1,172 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TestMemcachedSnappyStore < ActiveSupport::TestCase
4
-
5
- setup do
6
- @cache = ActiveSupport::Cache.lookup_store(:memcached_snappy_store, support_cas: true)
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 allow the implicit add operation when unless_exist is passed to write" do
23
- assert_nothing_raised(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 "get should work when there is a connection fail" do
65
- key = 'ponies2'
66
- @cache.instance_variable_get(:@data).expects(:check_return_code).raises(Memcached::ConnectionFailure).at_least_once
67
- assert_nil @cache.read(key)
68
- end
69
-
70
- test "should use snappy to multi read cache entries but not on missing entries" do
71
- keys = %w{ one tow three }
72
- values = keys.map{ |k| k * 10 }
73
- entries = values.map{ |v| ActiveSupport::Cache::Entry.new(v) }
74
-
75
- keys.each_with_index{ |k, i| @cache.write(k, values[i]) }
76
-
77
- keys_and_missing = keys << 'missing'
78
-
79
- Snappy.expects(:inflate).times(3).returns(*entries)
80
- assert_equal values, @cache.read_multi(*keys_and_missing).values
81
- end
82
-
83
- test "should use snappy to multi read cache entries" do
84
- keys = %w{ one tow three }
85
- values = keys.map{ |k| k * 10 }
86
- entries = values.map{ |v| ActiveSupport::Cache::Entry.new(v) }
87
-
88
- keys.each_with_index{ |k, i| @cache.write(k, values[i]) }
89
-
90
- Snappy.expects(:inflate).times(3).returns(*entries)
91
- assert_equal values, @cache.read_multi(*keys).values
92
- end
93
-
94
- test "should support raw writes that don't use marshal format" do
95
- key = 'key'
96
- @cache.write(key, 'value', :raw => true)
97
-
98
- actual_cache_value = @cache.instance_variable_get(:@data).get(key, true)
99
- assert_equal 'value', Snappy.inflate(actual_cache_value)
100
- end
101
-
102
- test "cas should use snappy to read and write cache entries" do
103
- entry_value = { :omg => 'data' }
104
- update_value = 'value'
105
- key = 'ponies'
106
-
107
- @cache.write(key, entry_value)
108
- result = @cache.cas(key) do |v|
109
- assert_equal entry_value, v
110
- update_value
111
- end
112
- assert result
113
- assert_equal update_value, @cache.read(key)
114
-
115
- actual_cache_value = @cache.instance_variable_get(:@data).get(key, true)
116
- serialized_entry = Snappy.inflate(actual_cache_value)
117
- entry = Marshal.load(serialized_entry)
118
- assert entry.is_a?(ActiveSupport::Cache::Entry)
119
- assert_equal update_value, entry.value
120
- end
121
-
122
- test "cas should support raw entries that don't use marshal format" do
123
- key = 'key'
124
- @cache.write(key, 'value', :raw => true)
125
- result = @cache.cas(key, :raw => true) do |v|
126
- assert_equal 'value', v
127
- 'new_value'
128
- end
129
- assert result
130
- actual_cache_value = @cache.instance_variable_get(:@data).get(key, true)
131
- assert_equal 'new_value', Snappy.inflate(actual_cache_value)
132
- end
133
-
134
- test "cas_multi should use snappy to read and write cache entries" do
135
- keys = %w{ one two three four }
136
- values = keys.map{ |k| k * 10 }
137
- update_hash = Hash[keys.drop(1).map {|k| [k, k * 11] }]
138
-
139
- keys.zip(values) { |k, v| @cache.write(k, v) }
140
-
141
- result = @cache.cas_multi(*keys) do |hash|
142
- assert_equal Hash[keys.zip(values)], hash
143
- update_hash
144
- end
145
- assert result
146
- assert_equal Hash[keys.zip(values)].merge(update_hash), @cache.read_multi(*keys)
147
-
148
- update_hash.each do |key, value|
149
- actual_cache_value = @cache.instance_variable_get(:@data).get(key, true)
150
- serialized_entry = Snappy.inflate(actual_cache_value)
151
- entry = Marshal.load(serialized_entry)
152
- assert entry.is_a?(ActiveSupport::Cache::Entry)
153
- assert_equal value, entry.value
154
- end
155
- end
156
-
157
- test "cas_multi should support raw entries that don't use marshal format" do
158
- keys = %w{ one two three }
159
- values = keys.map{ |k| k * 10 }
160
- update_hash = {"two" => "two" * 11}
161
-
162
- keys.zip(values) { |k, v| @cache.write(k, v) }
163
-
164
- result = @cache.cas_multi(*keys, :raw => true) do |hash|
165
- assert_equal Hash[keys.zip(values)], hash
166
- update_hash
167
- end
168
- assert result
169
- actual_cache_value = @cache.instance_variable_get(:@data).get("two", true)
170
- assert_equal update_hash["two"], Snappy.inflate(actual_cache_value)
171
- end
172
- end