memcached 1.2 → 1.2.1
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.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
|