зеркало из https://github.com/github/memcached.git
CAS support, as long as you patch libmemcached to send the right operator.
This commit is contained in:
Родитель
8b3822363b
Коммит
92454b4bda
|
@ -16,6 +16,7 @@
|
|||
%apply unsigned short { uint8_t };
|
||||
%apply unsigned int { uint16_t };
|
||||
%apply unsigned long { uint32_t flags, uint32_t offset };
|
||||
/* %apply unsigned long long { uint64_t cas }; */
|
||||
|
||||
// For behavior's weird set interface
|
||||
|
||||
|
@ -63,6 +64,7 @@
|
|||
|
||||
//// Output maps
|
||||
|
||||
/* %apply unsigned long long { uint64_t cas }; */
|
||||
%apply unsigned short *OUTPUT {memcached_return *error}
|
||||
%apply unsigned int *OUTPUT {uint32_t *flags}
|
||||
%apply size_t *OUTPUT {size_t *value_length}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -48,7 +48,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|||
=end
|
||||
|
||||
def initialize(servers, opts = {})
|
||||
@struct = Lib::MemcachedSt.new
|
||||
@struct = Lib::MemcachedSt.new
|
||||
Lib.memcached_create(@struct)
|
||||
|
||||
# Servers
|
||||
|
@ -104,6 +104,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|||
def destroy(disable_methods = true)
|
||||
Lib.memcached_free(@struct)
|
||||
@struct = nil
|
||||
|
||||
if disable_methods
|
||||
class << self
|
||||
Memcached.instance_methods.each do |method_name|
|
||||
|
@ -215,17 +216,22 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|||
)
|
||||
end
|
||||
|
||||
# Not yet implemented.
|
||||
#
|
||||
# Reads a key's value from the server and yields it to a block. Replaces the key's value with the result of the block as long as the key hasn't been updated in the meantime, otherwise raises <b>Memcached::NotStored</b>. Accepts a String <tt>key</tt> and a block.
|
||||
#
|
||||
# Also accepts an optional <tt>timeout</tt> value.
|
||||
#
|
||||
# CAS stands for "compare and swap", and avoids the need for manual key mutexing. CAS support must be enabled in Memcached.new or a <b>Memcached::ClientError</b> will be raised.
|
||||
def cas(*args)
|
||||
# Requires memcached HEAD
|
||||
raise NotImplemented
|
||||
# CAS stands for "compare and swap", and avoids the need for manual key mutexing. CAS support must be enabled in Memcached.new or a <b>Memcached::ClientError</b> will be raised. Note that CAS may be buggy in memcached itself.
|
||||
#
|
||||
def cas(key, timeout = 0, marshal = true)
|
||||
raise ClientError, "CAS not enabled for this Memcached instance" unless options[:support_cas]
|
||||
|
||||
value = get(key)
|
||||
value = yield value
|
||||
value = marshal ? Marshal.dump(value) : value.to_s
|
||||
|
||||
check_return_code(
|
||||
Lib.memcached_cas(@struct, Lib.ns(@namespace, key), value, timeout, FLAGS, @struct.result.cas)
|
||||
)
|
||||
end
|
||||
|
||||
### Deleters
|
||||
|
|
|
@ -336,29 +336,38 @@ class MemcachedTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_cas
|
||||
cache = Memcached.new(
|
||||
@servers,
|
||||
:namespace => @namespace,
|
||||
:support_cas => true
|
||||
)
|
||||
value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
|
||||
|
||||
@cache.set key, @value
|
||||
@cache.cas(key) do |current|
|
||||
# Existing set
|
||||
cache.set key, @value
|
||||
cache.cas(key) do |current|
|
||||
assert_equal @value, current
|
||||
value2
|
||||
end
|
||||
assert_equal value2, @cache.get(key)
|
||||
assert_equal value2, cache.get(key)
|
||||
|
||||
@cache.delete key
|
||||
@cache.cas(key) do |current|
|
||||
value2
|
||||
end
|
||||
assert_equal value2, @cache.get(key)
|
||||
|
||||
@cache.set key, @value
|
||||
# Missing set
|
||||
cache.delete key
|
||||
assert_raises(Memcached::NotFound) do
|
||||
@cache.cas(key) do |current|
|
||||
@cache.set key, value2
|
||||
cache.cas(key) {}
|
||||
end
|
||||
|
||||
# Conflicting set
|
||||
cache.set key, @value
|
||||
# XXX Should raise Memcached::Exists
|
||||
assert_raises(Memcached::UnknownReadFailure) do
|
||||
cache.cas(key) do |current|
|
||||
cache.set key, value2
|
||||
current
|
||||
end
|
||||
end
|
||||
|
||||
cache.destroy
|
||||
end
|
||||
|
||||
# Namespace and key validation
|
||||
|
|
Загрузка…
Ссылка в новой задаче