memcached 1.2 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +2 -1
- data/CHANGELOG +2 -0
- data/README +15 -4
- data/ext/rlibmemcached.i +7 -6
- data/ext/rlibmemcached_wrap.c +5 -11
- data/lib/memcached/exceptions.rb +13 -13
- data/lib/memcached/memcached.rb +9 -9
- data/memcached.gemspec +2 -2
- data/test/profile/exercise.rb +5 -3
- data/test/unit/memcached_test.rb +21 -5
- metadata +4 -3
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
�UU>�������/�s���!x塓�D��C��)�r�����e��I<��n�ߡMq�9��d�C�G�*d�@b[�]�.Y��^2,�ɉ�ZIKf�I���<�`���V�3���9T�S�;�H�G����U%��o$ˣ.F�4J��|F�Ѻ2���J�
|
2
|
+
�y���|��I�n�#~J�ƚ>�5�b��'Y��P���R#��f����d�U����<��7<b%.�{ԥ�1��)(�)��:s,�S�kФ�
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
v1.2.1. Fix large allocation on error bug.
|
2
|
+
|
1
3
|
v1.2. Clean up duplicated set_prefix_key API. Pipeline deletes and remove dead replication code. Apply prefix_key to binary protocol properly (tarrall). Add Memcached::Rails#exist? (ssoroka).
|
2
4
|
|
3
5
|
v1.1.3. Register new objects to fix leaks around memcached_server_st and other rich structs (tobi).
|
data/README
CHANGED
@@ -54,10 +54,10 @@ You can get multiple values at once:
|
|
54
54
|
$cache.get ['test', 'test2', 'missing']
|
55
55
|
#=> {"test" => "hello", "test2" => "hello"}
|
56
56
|
|
57
|
-
You can set a counter and increment it:
|
57
|
+
You can set a counter and increment it. Note that you must initialize it with an integer, encoded as an unmarshalled ASCII string:
|
58
58
|
|
59
59
|
start = 1
|
60
|
-
$cache.set 'counter', start, 0, false
|
60
|
+
$cache.set 'counter', start.to_s, 0, false
|
61
61
|
$cache.increment 'counter' #=> 2
|
62
62
|
$cache.increment 'counter' #=> 3
|
63
63
|
$cache.get('counter', false).to_i #=> 3
|
@@ -73,9 +73,16 @@ Note that the API is not the same as that of <b>Ruby-MemCache</b> or <b>memcache
|
|
73
73
|
$cache.delete 'test'
|
74
74
|
$cache.get 'test' #=> raises Memcached::NotFound
|
75
75
|
|
76
|
-
==
|
76
|
+
== Pipelining
|
77
77
|
|
78
|
-
|
78
|
+
Pipelining updates is extremely effective in <b>memcached</b>, leading to more than 25x write throughput than the default settings. Use the following options to enable it:
|
79
|
+
|
80
|
+
:no_block => true,
|
81
|
+
:buffer_requests => true,
|
82
|
+
:noreply => true,
|
83
|
+
:binary_protocol => false
|
84
|
+
|
85
|
+
Currently #append, #prepend, #set, and #delete are pipelined. Note that when you perform a read, all pending writes are flushed to the servers.
|
79
86
|
|
80
87
|
== Threading
|
81
88
|
|
@@ -91,6 +98,10 @@ There is a compatibility wrapper for legacy applications called Memcached::Rails
|
|
91
98
|
# Join the thread so that exceptions don't get lost
|
92
99
|
thread.join
|
93
100
|
|
101
|
+
== Legacy applications
|
102
|
+
|
103
|
+
There is a compatibility wrapper for legacy applications called Memcached::Rails.
|
104
|
+
|
94
105
|
== Benchmarks
|
95
106
|
|
96
107
|
<b>memcached</b>, correctly configured, is at least twice as fast as <b>memcache-client</b> and <b>dalli</b>. See BENCHMARKS[link:files/BENCHMARKS.html] for details.
|
data/ext/rlibmemcached.i
CHANGED
@@ -17,13 +17,15 @@
|
|
17
17
|
|
18
18
|
// Register libmemcached's struct free function to prevent memory leaks
|
19
19
|
%freefunc memcached_st "memcached_free";
|
20
|
+
%freefunc memcached_stat_st "memcached_stat_free";
|
20
21
|
%freefunc memcached_server_st "memcached_server_free";
|
21
22
|
|
22
23
|
// Register which functions generate new objects
|
23
|
-
%newobject memcached_server_by_key;
|
24
24
|
%newobject memcached_create;
|
25
25
|
%newobject memcached_clone;
|
26
26
|
%newobject memcached_stat_get_value;
|
27
|
+
// %newobject memcached_stat;
|
28
|
+
%newobject memcached_server_by_key;
|
27
29
|
|
28
30
|
// %trackobjects; // Doesn't fix any interesting leaks
|
29
31
|
|
@@ -155,7 +157,7 @@ VALUE memcached_get_rvalue(memcached_st *ptr, const char *key, size_t key_length
|
|
155
157
|
%{
|
156
158
|
VALUE memcached_get_rvalue(memcached_st *ptr, const char *key, size_t key_length, uint32_t *flags, memcached_return *error) {
|
157
159
|
VALUE ret;
|
158
|
-
size_t value_length;
|
160
|
+
size_t value_length = 0;
|
159
161
|
char *value = memcached_get(ptr, key, key_length, &value_length, flags, error);
|
160
162
|
ret = rb_str_new(value, value_length);
|
161
163
|
free(value);
|
@@ -167,7 +169,7 @@ VALUE memcached_get_len_rvalue(memcached_st *ptr, const char *key, size_t key_le
|
|
167
169
|
%{
|
168
170
|
VALUE memcached_get_len_rvalue(memcached_st *ptr, const char *key, size_t key_length, uint32_t user_spec_len, uint32_t *flags, memcached_return *error) {
|
169
171
|
VALUE ret;
|
170
|
-
size_t value_length;
|
172
|
+
size_t value_length = 0;
|
171
173
|
char *value = memcached_get_len(ptr, key, key_length, user_spec_len, &value_length, flags, error);
|
172
174
|
ret = rb_str_new(value, value_length);
|
173
175
|
free(value);
|
@@ -179,7 +181,7 @@ VALUE memcached_get_from_last_rvalue(memcached_st *ptr, const char *key, size_t
|
|
179
181
|
%{
|
180
182
|
VALUE memcached_get_from_last_rvalue(memcached_st *ptr, const char *key, size_t key_length, uint32_t *flags, memcached_return *error) {
|
181
183
|
VALUE ret;
|
182
|
-
size_t value_length;
|
184
|
+
size_t value_length = 0;
|
183
185
|
char *value = memcached_get_from_last(ptr, key, key_length, &value_length, flags, error);
|
184
186
|
ret = rb_str_new(value, value_length);
|
185
187
|
free(value);
|
@@ -191,9 +193,8 @@ VALUE memcached_get_from_last_rvalue(memcached_st *ptr, const char *key, size_t
|
|
191
193
|
VALUE memcached_fetch_rvalue(memcached_st *ptr, char *key, size_t *key_length, uint32_t *flags, memcached_return *error);
|
192
194
|
%{
|
193
195
|
VALUE memcached_fetch_rvalue(memcached_st *ptr, char *key, size_t *key_length, uint32_t *flags, memcached_return *error) {
|
194
|
-
size_t value_length;
|
196
|
+
size_t value_length = 0;
|
195
197
|
VALUE result = rb_ary_new();
|
196
|
-
|
197
198
|
char *value = memcached_fetch(ptr, key, key_length, &value_length, flags, error);
|
198
199
|
VALUE ret = rb_str_new(value, value_length);
|
199
200
|
rb_ary_push(result, ret);
|
data/ext/rlibmemcached_wrap.c
CHANGED
@@ -2254,7 +2254,7 @@ SWIG_From_unsigned_SS_int (unsigned int value)
|
|
2254
2254
|
|
2255
2255
|
VALUE memcached_get_rvalue(memcached_st *ptr, const char *key, size_t key_length, uint32_t *flags, memcached_return *error) {
|
2256
2256
|
VALUE ret;
|
2257
|
-
size_t value_length;
|
2257
|
+
size_t value_length = 0;
|
2258
2258
|
char *value = memcached_get(ptr, key, key_length, &value_length, flags, error);
|
2259
2259
|
ret = rb_str_new(value, value_length);
|
2260
2260
|
free(value);
|
@@ -2264,7 +2264,7 @@ VALUE memcached_get_rvalue(memcached_st *ptr, const char *key, size_t key_length
|
|
2264
2264
|
|
2265
2265
|
VALUE memcached_get_len_rvalue(memcached_st *ptr, const char *key, size_t key_length, uint32_t user_spec_len, uint32_t *flags, memcached_return *error) {
|
2266
2266
|
VALUE ret;
|
2267
|
-
size_t value_length;
|
2267
|
+
size_t value_length = 0;
|
2268
2268
|
char *value = memcached_get_len(ptr, key, key_length, user_spec_len, &value_length, flags, error);
|
2269
2269
|
ret = rb_str_new(value, value_length);
|
2270
2270
|
free(value);
|
@@ -2274,7 +2274,7 @@ VALUE memcached_get_len_rvalue(memcached_st *ptr, const char *key, size_t key_le
|
|
2274
2274
|
|
2275
2275
|
VALUE memcached_get_from_last_rvalue(memcached_st *ptr, const char *key, size_t key_length, uint32_t *flags, memcached_return *error) {
|
2276
2276
|
VALUE ret;
|
2277
|
-
size_t value_length;
|
2277
|
+
size_t value_length = 0;
|
2278
2278
|
char *value = memcached_get_from_last(ptr, key, key_length, &value_length, flags, error);
|
2279
2279
|
ret = rb_str_new(value, value_length);
|
2280
2280
|
free(value);
|
@@ -2283,9 +2283,8 @@ VALUE memcached_get_from_last_rvalue(memcached_st *ptr, const char *key, size_t
|
|
2283
2283
|
|
2284
2284
|
|
2285
2285
|
VALUE memcached_fetch_rvalue(memcached_st *ptr, char *key, size_t *key_length, uint32_t *flags, memcached_return *error) {
|
2286
|
-
size_t value_length;
|
2286
|
+
size_t value_length = 0;
|
2287
2287
|
VALUE result = rb_ary_new();
|
2288
|
-
|
2289
2288
|
char *value = memcached_fetch(ptr, key, key_length, &value_length, flags, error);
|
2290
2289
|
VALUE ret = rb_str_new(value, value_length);
|
2291
2290
|
rb_ary_push(result, ret);
|
@@ -4324,11 +4323,6 @@ fail:
|
|
4324
4323
|
}
|
4325
4324
|
|
4326
4325
|
|
4327
|
-
SWIGINTERN void
|
4328
|
-
free_memcached_stat_st(struct memcached_stat_st *arg1) {
|
4329
|
-
free((char *) arg1);
|
4330
|
-
}
|
4331
|
-
|
4332
4326
|
swig_class SwigClassMemcachedSt;
|
4333
4327
|
|
4334
4328
|
SWIGINTERN VALUE
|
@@ -13208,7 +13202,7 @@ SWIGEXPORT void Init_rlibmemcached(void) {
|
|
13208
13202
|
rb_define_method(SwigClassMemcachedStatSt.klass, "version=", _wrap_MemcachedStatSt_version_set, -1);
|
13209
13203
|
rb_define_method(SwigClassMemcachedStatSt.klass, "version", _wrap_MemcachedStatSt_version_get, -1);
|
13210
13204
|
SwigClassMemcachedStatSt.mark = 0;
|
13211
|
-
SwigClassMemcachedStatSt.destroy = (void (*)(void *))
|
13205
|
+
SwigClassMemcachedStatSt.destroy = (void (*)(void *)) memcached_stat_free;
|
13212
13206
|
SwigClassMemcachedStatSt.trackObjects = 0;
|
13213
13207
|
|
13214
13208
|
SwigClassMemcachedSt.klass = rb_define_class_under(mRlibmemcached, "MemcachedSt", rb_cObject);
|
data/lib/memcached/exceptions.rb
CHANGED
@@ -3,7 +3,7 @@ class Memcached
|
|
3
3
|
|
4
4
|
=begin rdoc
|
5
5
|
|
6
|
-
Superclass for all Memcached runtime exceptions.
|
6
|
+
Superclass for all Memcached runtime exceptions.
|
7
7
|
|
8
8
|
Subclasses correspond one-to-one with server response strings or libmemcached errors. For example, raising <b>Memcached::NotFound</b> means that the server returned <tt>"NOT_FOUND\r\n"</tt>.
|
9
9
|
|
@@ -48,15 +48,15 @@ Subclasses correspond one-to-one with server response strings or libmemcached er
|
|
48
48
|
=end
|
49
49
|
class Error < RuntimeError
|
50
50
|
attr_accessor :no_backtrace
|
51
|
-
|
51
|
+
|
52
52
|
def set_backtrace(*args)
|
53
53
|
@no_backtrace ? [] : super
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
def backtrace(*args)
|
57
57
|
@no_backtrace ? [] : super
|
58
58
|
end
|
59
|
-
end
|
59
|
+
end
|
60
60
|
|
61
61
|
#:stopdoc:
|
62
62
|
|
@@ -64,21 +64,21 @@ Subclasses correspond one-to-one with server response strings or libmemcached er
|
|
64
64
|
private
|
65
65
|
def camelize(string)
|
66
66
|
string.downcase.gsub('/', ' or ').split(' ').map {|s| s.capitalize}.join
|
67
|
-
end
|
67
|
+
end
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
ERRNO_HASH = Hash[*Errno.constants.grep(/^E/).map{ |c| [Errno.const_get(c)::Errno, Errno.const_get(c).new.message] }.flatten]
|
71
|
-
|
71
|
+
|
72
72
|
EXCEPTIONS = []
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
empty_struct = Lib.memcached_create(nil)
|
74
|
+
Lib.memcached_create(empty_struct)
|
75
|
+
|
76
76
|
# Generate exception classes
|
77
|
-
|
78
|
-
description =
|
77
|
+
Lib::MEMCACHED_MAXIMUM_RETURN.times do |index|
|
78
|
+
description = Lib.memcached_strerror(empty_struct, index).gsub("!", "")
|
79
79
|
exception_class = eval("class #{camelize(description)} < Error; self; end")
|
80
80
|
EXCEPTIONS << exception_class
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
#:startdoc:
|
84
84
|
end
|
data/lib/memcached/memcached.rb
CHANGED
@@ -115,17 +115,16 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
if options[:credentials]
|
118
|
+
if !options[:credentials] and ENV["MEMCACHE_USERNAME"] and ENV["MEMCACHE_PASSWORD"]
|
119
119
|
options[:credentials] = [ENV["MEMCACHE_USERNAME"], ENV["MEMCACHE_PASSWORD"]]
|
120
120
|
end
|
121
121
|
|
122
122
|
instance_eval { send(:extend, Experimental) } if options[:experimental_features]
|
123
123
|
|
124
|
-
options[:binary_protocol] = true if options[:credentials]
|
124
|
+
options[:binary_protocol] = true if options[:credentials]
|
125
125
|
|
126
126
|
# Force :buffer_requests to use :no_block
|
127
|
-
#
|
128
|
-
# consistently
|
127
|
+
# FIXME This should all be wrapped up in a single :pipeline option.
|
129
128
|
options[:no_block] = true if options[:buffer_requests]
|
130
129
|
|
131
130
|
# Disallow weights without ketama
|
@@ -137,8 +136,8 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
|
|
137
136
|
end
|
138
137
|
|
139
138
|
# Read timeouts
|
140
|
-
options[:rcv_timeout] ||= options[:timeout]
|
141
|
-
options[:poll_timeout] ||= options[:timeout]
|
139
|
+
options[:rcv_timeout] ||= options[:timeout]
|
140
|
+
options[:poll_timeout] ||= options[:timeout]
|
142
141
|
|
143
142
|
# Set the prefix key. Support the legacy name.
|
144
143
|
set_prefix_key(options[:prefix_key] || options[:namespace])
|
@@ -234,15 +233,16 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
|
|
234
233
|
end
|
235
234
|
|
236
235
|
# Reset the state of the libmemcached struct. This is useful for changing the server list at runtime.
|
237
|
-
def reset(current_servers = nil
|
236
|
+
def reset(current_servers = nil)
|
238
237
|
# Store state and teardown
|
239
238
|
current_servers ||= servers
|
240
239
|
prev_prefix_key = prefix_key
|
240
|
+
quit
|
241
241
|
|
242
242
|
# Create
|
243
243
|
# FIXME Duplicates logic with initialize()
|
244
244
|
@struct = Lib.memcached_create(nil)
|
245
|
-
set_prefix_key(prev_prefix_key)
|
245
|
+
set_prefix_key(prev_prefix_key)
|
246
246
|
set_behaviors
|
247
247
|
set_credentials
|
248
248
|
set_servers(current_servers)
|
@@ -289,7 +289,7 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
|
|
289
289
|
#
|
290
290
|
# Accepts an optional <tt>ttl</tt> value to specify the maximum lifetime of the key on the server, in seconds. <tt>ttl</tt> must be a <tt>FixNum</tt>. <tt>0</tt> means no ttl. Note that there is no guarantee that the key will persist as long as the <tt>ttl</tt>, but it will not persist longer.
|
291
291
|
#
|
292
|
-
# Also accepts a <tt>marshal</tt> value, which defaults to <tt>true</tt>. Set <tt>marshal</tt> to <tt>false</tt
|
292
|
+
# Also accepts a <tt>marshal</tt> value, which defaults to <tt>true</tt>. Set <tt>marshal</tt> to <tt>false</tt>, and pass a String as the <tt>value</tt>, if you want to set a raw byte array.
|
293
293
|
#
|
294
294
|
def set(key, value, ttl=@default_ttl, marshal=true, flags=FLAGS)
|
295
295
|
value = marshal ? Marshal.dump(value) : value
|
data/memcached.gemspec
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{memcached}
|
5
|
-
s.version = "1.2"
|
5
|
+
s.version = "1.2.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Evan Weaver"]
|
9
9
|
s.cert_chain = ["/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-public_cert.pem"]
|
10
|
-
s.date = %q{2011-03-
|
10
|
+
s.date = %q{2011-03-07}
|
11
11
|
s.description = %q{An interface to the libmemcached C client.}
|
12
12
|
s.email = %q{}
|
13
13
|
s.extensions = ["ext/extconf.rb"]
|
data/test/profile/exercise.rb
CHANGED
@@ -8,8 +8,6 @@ require 'ostruct'
|
|
8
8
|
|
9
9
|
GC.copy_on_write_friendly = true if GC.respond_to?("copy_on_write_friendly=")
|
10
10
|
|
11
|
-
Struct
|
12
|
-
|
13
11
|
class Worker
|
14
12
|
def initialize(method_name, iterations, with_memory = 'false')
|
15
13
|
@method = method_name || 'mixed'
|
@@ -32,7 +30,7 @@ class Worker
|
|
32
30
|
{
|
33
31
|
:buffer_requests => true,
|
34
32
|
:no_block => true,
|
35
|
-
:noreply =>
|
33
|
+
:noreply => false,
|
36
34
|
:namespace => "namespace"
|
37
35
|
}
|
38
36
|
]
|
@@ -112,9 +110,11 @@ class Worker
|
|
112
110
|
@cache.prepend @key2, @marshalled
|
113
111
|
@cache.get @key1
|
114
112
|
@cache.get @key3
|
113
|
+
cache = Memcached::Rails.new(*@opts)
|
115
114
|
cache = @cache.clone
|
116
115
|
servers = @cache.servers
|
117
116
|
server = @cache.server_by_key(@key1)
|
117
|
+
@cache.stats
|
118
118
|
end
|
119
119
|
@i.times do
|
120
120
|
@cache.reset
|
@@ -151,6 +151,8 @@ class Worker
|
|
151
151
|
raise "No such method"
|
152
152
|
end
|
153
153
|
|
154
|
+
@cache = nil
|
155
|
+
|
154
156
|
if @with_memory == "true"
|
155
157
|
puts "*** Garbage collect. ***"
|
156
158
|
10.times do
|
data/test/unit/memcached_test.rb
CHANGED
@@ -434,15 +434,19 @@ class MemcachedTest < Test::Unit::TestCase
|
|
434
434
|
|
435
435
|
def test_random_distribution_is_statistically_random
|
436
436
|
cache = Memcached.new(@servers, :distribution => :random)
|
437
|
-
|
438
|
-
|
437
|
+
read_cache = Memcached.new(@servers.first)
|
438
|
+
hits = 4
|
439
439
|
|
440
|
-
cache, hits = Memcached.new(@servers.first), 4
|
441
440
|
while hits == 4 do
|
441
|
+
cache.flush
|
442
|
+
20.times do |i|
|
443
|
+
cache.set "#{key}#{i}", @value
|
444
|
+
end
|
445
|
+
|
442
446
|
hits = 0
|
443
447
|
20.times do |i|
|
444
448
|
begin
|
445
|
-
|
449
|
+
read_cache.get "#{key}#{i}"
|
446
450
|
hits += 1
|
447
451
|
rescue Memcached::NotFound
|
448
452
|
end
|
@@ -794,11 +798,23 @@ class MemcachedTest < Test::Unit::TestCase
|
|
794
798
|
|
795
799
|
# Stats
|
796
800
|
|
797
|
-
def
|
801
|
+
def disable_test_stats
|
798
802
|
stats = @cache.stats
|
799
803
|
assert_equal 3, stats[:pid].size
|
800
804
|
assert_instance_of Fixnum, stats[:pid].first
|
801
805
|
assert_instance_of String, stats[:version].first
|
806
|
+
|
807
|
+
stats = @binary_protocol_cache.stats
|
808
|
+
assert_equal 3, stats[:pid].size
|
809
|
+
assert_instance_of Fixnum, stats[:pid].first
|
810
|
+
assert_instance_of String, stats[:version].first
|
811
|
+
|
812
|
+
assert_nothing_raised do
|
813
|
+
@noblock_cache.stats
|
814
|
+
end
|
815
|
+
assert_raises(TypeError) do
|
816
|
+
@udp_cache.stats
|
817
|
+
end
|
802
818
|
end
|
803
819
|
|
804
820
|
def test_missing_stats
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memcached
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 2
|
9
|
-
|
9
|
+
- 1
|
10
|
+
version: 1.2.1
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Evan Weaver
|
@@ -35,7 +36,7 @@ cert_chain:
|
|
35
36
|
yZ0=
|
36
37
|
-----END CERTIFICATE-----
|
37
38
|
|
38
|
-
date: 2011-03-
|
39
|
+
date: 2011-03-07 00:00:00 -08:00
|
39
40
|
default_executable:
|
40
41
|
dependencies: []
|
41
42
|
|
metadata.gz.sig
CHANGED
Binary file
|