memcached_store 0.11.3 → 0.12.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/lib/active_support/cache/memcached_store.rb +45 -5
- data/lib/memcached_store/version.rb +1 -1
- data/memcached_store.gemspec +2 -2
- data/test/test_memcached_store.rb +67 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 171a18683c77797d79f6c336d29904a50120607b
|
4
|
+
data.tar.gz: 3b2dc285bb4064f3b73dd620174934527a03cf5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52711d0a3a25db301f523fb90b097392d653965876d93d24e80cedc542526b345f825a1e61a32d116a94a963024aebdf36264a076712f64841977836138cc467
|
7
|
+
data.tar.gz: d6dbb652bc7fc0b58ee187ca023e512723daa77095aa8333f78af6dc14345d8f120250d0fd88801763555cb2582aa05429f08bb7b1b4ac886dee04d0f2d5d013
|
@@ -64,6 +64,41 @@ module ActiveSupport
|
|
64
64
|
{}
|
65
65
|
end
|
66
66
|
|
67
|
+
def cas(name, options = nil)
|
68
|
+
options = merged_options(options)
|
69
|
+
options.merge!(:raw => true)
|
70
|
+
key = namespaced_key(name, options)
|
71
|
+
|
72
|
+
@data.cas(key, expiration(options), true) do |raw_value|
|
73
|
+
entry = deserialize_entry(raw_value)
|
74
|
+
value = yield entry.value
|
75
|
+
serialize_entry(Entry.new(value, options), options)
|
76
|
+
end
|
77
|
+
rescue *NONFATAL_EXCEPTIONS => e
|
78
|
+
@data.log_exception(e)
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
def cas_multi(*names)
|
83
|
+
options = names.extract_options!
|
84
|
+
options = merged_options(options)
|
85
|
+
options.merge!(:raw => true)
|
86
|
+
keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
|
87
|
+
|
88
|
+
@data.cas(keys_to_names.keys, expiration(options), true) do |raw_values|
|
89
|
+
values = {}
|
90
|
+
raw_values.each do |key, raw_value|
|
91
|
+
entry = deserialize_entry(raw_value)
|
92
|
+
values[keys_to_names[key]] = entry.value unless entry.expired?
|
93
|
+
end
|
94
|
+
values = yield values
|
95
|
+
Hash[values.map{|name, value| [escape_key(namespaced_key(name, options)), serialize_entry(Entry.new(value, options), options)]}]
|
96
|
+
end
|
97
|
+
rescue *NONFATAL_EXCEPTIONS => e
|
98
|
+
@data.log_exception(e)
|
99
|
+
false
|
100
|
+
end
|
101
|
+
|
67
102
|
def increment(name, amount = 1, options = nil) # :nodoc:
|
68
103
|
options = merged_options(options)
|
69
104
|
instrument(:increment, name, :amount => amount) do
|
@@ -106,11 +141,7 @@ module ActiveSupport
|
|
106
141
|
|
107
142
|
def write_entry(key, entry, options) # :nodoc:
|
108
143
|
method = options && options[:unless_exist] ? :add : :set
|
109
|
-
expires_in = options
|
110
|
-
if expires_in > 0 && !options[:raw]
|
111
|
-
# Set the memcache expire a few minutes in the future to support race condition ttls on read
|
112
|
-
expires_in += 5.minutes
|
113
|
-
end
|
144
|
+
expires_in = expiration(options)
|
114
145
|
value = serialize_entry(entry, options)
|
115
146
|
@data.send(method, escape_key(key), value, expires_in, options[:raw])
|
116
147
|
rescue *NONFATAL_EXCEPTIONS => e
|
@@ -150,6 +181,15 @@ module ActiveSupport
|
|
150
181
|
entry
|
151
182
|
end
|
152
183
|
|
184
|
+
def expiration(options)
|
185
|
+
expires_in = options[:expires_in].to_i
|
186
|
+
if expires_in > 0 && !options[:raw]
|
187
|
+
# Set the memcache expire a few minutes in the future to support race condition ttls on read
|
188
|
+
expires_in += 5.minutes
|
189
|
+
end
|
190
|
+
expires_in
|
191
|
+
end
|
192
|
+
|
153
193
|
end
|
154
194
|
end
|
155
195
|
end
|
data/memcached_store.gemspec
CHANGED
@@ -4,8 +4,8 @@ $:.unshift lib unless $:.include?(lib)
|
|
4
4
|
require "memcached_store/version"
|
5
5
|
|
6
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"]
|
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
9
|
gem.summary = gem.description = %q{Plugin-able Memcached adapters to add features (compression, safety)}
|
10
10
|
gem.homepage = "https://github.com/Shopify/memcached_store/"
|
11
11
|
|
@@ -2,7 +2,7 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class TestMemcachedStore < ActiveSupport::TestCase
|
4
4
|
setup do
|
5
|
-
@cache = ActiveSupport::Cache.lookup_store(:memcached_store, expires_in: 60)
|
5
|
+
@cache = ActiveSupport::Cache.lookup_store(:memcached_store, expires_in: 60, support_cas: true)
|
6
6
|
@cache.clear
|
7
7
|
end
|
8
8
|
|
@@ -51,6 +51,72 @@ class TestMemcachedStore < ActiveSupport::TestCase
|
|
51
51
|
assert_nil @cache.fetch('foo') { 'baz' }
|
52
52
|
end
|
53
53
|
|
54
|
+
def test_cas
|
55
|
+
@cache.write('foo', nil)
|
56
|
+
assert @cache.cas('foo') {|value| assert_nil value; 'bar' }
|
57
|
+
assert_equal 'bar', @cache.read('foo')
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_cas_with_cache_miss
|
61
|
+
refute @cache.cas('not_exist') {|value| flunk }
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_cas_with_conflict
|
65
|
+
@cache.write('foo', 'bar')
|
66
|
+
refute @cache.cas('foo') {|value|
|
67
|
+
@cache.write('foo', 'baz')
|
68
|
+
'biz'
|
69
|
+
}
|
70
|
+
assert_equal 'baz', @cache.read('foo')
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_cas_multi_with_empty_set
|
74
|
+
refute @cache.cas_multi() {|hash| flunk }
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_cas_multi
|
78
|
+
@cache.write('foo', 'bar')
|
79
|
+
@cache.write('fud', 'biz')
|
80
|
+
assert @cache.cas_multi('foo', 'fud') {|hash| assert_equal({"foo" => "bar", "fud" => "biz"}, hash); {"foo" => "baz", "fud" => "buz"} }
|
81
|
+
assert_equal({"foo" => "baz", "fud" => "buz"}, @cache.read_multi('foo', 'fud'))
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_cas_multi_with_altered_key
|
85
|
+
@cache.write('foo', 'baz')
|
86
|
+
assert @cache.cas_multi('foo') {|hash| {'fu' => 'baz'}}
|
87
|
+
assert_nil @cache.read('fu')
|
88
|
+
assert_equal 'baz', @cache.read('foo')
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_cas_multi_with_cache_miss
|
92
|
+
assert @cache.cas_multi('not_exist') {|hash| assert hash.empty?; {} }
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_cas_multi_with_partial_miss
|
96
|
+
@cache.write('foo', 'baz')
|
97
|
+
assert @cache.cas_multi('foo', 'bar') {|hash| assert_equal({"foo" => "baz"}, hash); {} }
|
98
|
+
assert_equal 'baz', @cache.read('foo')
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_cas_multi_with_partial_update
|
102
|
+
@cache.write('foo', 'bar')
|
103
|
+
@cache.write('fud', 'biz')
|
104
|
+
assert @cache.cas_multi('foo', 'fud') {|hash| assert_equal({"foo" => "bar", "fud" => "biz"}, hash); {"foo" => "baz"} }
|
105
|
+
assert_equal({"foo" => "baz", "fud" => "biz"}, @cache.read_multi('foo', 'fud'))
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_cas_multi_with_partial_conflict
|
109
|
+
@cache.write('foo', 'bar')
|
110
|
+
@cache.write('fud', 'biz')
|
111
|
+
result = @cache.cas_multi('foo', 'fud') do |hash|
|
112
|
+
assert_equal({"foo" => "bar", "fud" => "biz"}, hash)
|
113
|
+
@cache.write('foo', 'bad')
|
114
|
+
{"foo" => "baz", "fud" => "buz"}
|
115
|
+
end
|
116
|
+
assert result
|
117
|
+
assert_equal({"foo" => "bad", "fud" => "buz"}, @cache.read_multi('foo', 'fud'))
|
118
|
+
end
|
119
|
+
|
54
120
|
def test_should_read_and_write_hash
|
55
121
|
assert @cache.write('foo', {:a => "b"})
|
56
122
|
assert_equal({:a => "b"}, @cache.read('foo'))
|
metadata
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memcached_store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Camilo Lopez
|
8
8
|
- Tom Burns
|
9
9
|
- Arthur Neves
|
10
|
+
- Francis Bogsanyi
|
10
11
|
autorequire:
|
11
12
|
bindir: bin
|
12
13
|
cert_chain: []
|
13
|
-
date: 2014-05-
|
14
|
+
date: 2014-05-09 00:00:00.000000000 Z
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
17
|
name: activesupport
|
@@ -115,6 +116,7 @@ email:
|
|
115
116
|
- camilo@camilolopez.com
|
116
117
|
- tom.burns@shopify.com
|
117
118
|
- arthurnn@gmail.com
|
119
|
+
- francis.bogsanyi@shopify.com
|
118
120
|
executables: []
|
119
121
|
extensions: []
|
120
122
|
extra_rdoc_files: []
|