Support CAS properly from Memcached::Rails.

This commit is contained in:
Evan Weaver 2009-02-06 17:43:37 -08:00
Родитель 05c6465c95
Коммит 37e0b4ccaf
3 изменённых файлов: 42 добавлений и 1 удалений

Просмотреть файл

@ -264,7 +264,10 @@ Please note that when pipelining is enabled, setter and deleter methods do not r
def cas(key, ttl=nil, marshal=true, flags=FLAGS)
raise ClientError, "CAS not enabled for this Memcached instance" unless options[:support_cas]
value = get(key, marshal)
value, flags, ret = Lib.memcached_get_rvalue(@struct, key)
check_return_code(ret, key)
value = Marshal.load(value) if marshal
value = yield value
value = marshal ? Marshal.dump(value) : value.to_s
@ -273,6 +276,8 @@ Please note that when pipelining is enabled, setter and deleter methods do not r
key
)
end
alias :compare_and_swap :cas
### Deleters

Просмотреть файл

@ -25,6 +25,12 @@ class Memcached
super(key, !raw)
rescue NotFound
end
# Wraps Memcached#cas so that it doesn't raise. Doesn't set anything if no value is present.
def cas(key, ttl=nil, raw=false, &block)
super(key, ttl, !raw, &block)
rescue NotFound
end
# Wraps Memcached#get with multiple arguments.
def get_multi(*keys)

Просмотреть файл

@ -47,6 +47,36 @@ class RailsTest < Test::Unit::TestCase
assert_equal @value, result
end
def test_cas
cache = Memcached::Rails.new(:servers => @servers, :namespace => @namespace, :support_cas => true)
value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
# Existing set
cache.set key, @value
cache.cas(key) do |current|
assert_equal @value, current
value2
end
assert_equal value2, cache.get(key)
# Missing set
cache.delete key
assert_nothing_raised do
cache.cas(key) { @called = true }
end
assert_nil cache.get(key)
assert_nil @called
# Conflicting set
cache.set key, @value
assert_raises(Memcached::ConnectionDataExists) do
cache.cas(key) do |current|
cache.set key, value2
current
end
end
end
def test_get_missing
@cache.delete key rescue nil
result = @cache.get key