memcached 0.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +2 -0
- data/Manifest +4 -2
- data/README +95 -11
- data/TODO +11 -0
- data/ext/extconf.rb +9 -1
- data/ext/libmemcached.i +12 -1
- data/ext/libmemcached_wrap.c +140 -0
- data/lib/memcached.rb +17 -0
- data/lib/memcached/behaviors.rb +6 -1
- data/lib/memcached/exceptions.rb +53 -8
- data/lib/memcached/memcached.rb +111 -35
- data/memcached.gemspec +18 -5
- data/test/benchmark/benchmark.rb +259 -0
- data/test/benchmark/benchmark_set_get.rb +56 -0
- data/test/benchmark/profile.rb +49 -0
- data/test/setup.rb +7 -5
- data/test/unit/memcached_test.rb +109 -18
- metadata +6 -5
- metadata.gz.sig +0 -0
- data/ext/libmemcached.h +0 -425
- data/test/benchmark/benchmark_test.rb +0 -42
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
data/Manifest
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
ext/extconf.rb
|
3
|
-
ext/libmemcached.h
|
4
3
|
ext/libmemcached.i
|
5
4
|
ext/libmemcached_wrap.c
|
6
5
|
lib/memcached/behaviors.rb
|
@@ -11,9 +10,12 @@ lib/memcached.rb
|
|
11
10
|
LICENSE
|
12
11
|
Manifest
|
13
12
|
README
|
14
|
-
test/benchmark/
|
13
|
+
test/benchmark/benchmark.rb
|
14
|
+
test/benchmark/benchmark_set_get.rb
|
15
|
+
test/benchmark/profile.rb
|
15
16
|
test/setup.rb
|
16
17
|
test/teardown.rb
|
17
18
|
test/test_helper.rb
|
18
19
|
test/unit/binding_test.rb
|
19
20
|
test/unit/memcached_test.rb
|
21
|
+
TODO
|
data/README
CHANGED
@@ -7,14 +7,10 @@ An interface to the libmemcached C client.
|
|
7
7
|
|
8
8
|
Copyright 2008 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file. Portions copyright 2008 TangentOrg, Brian Aker, licensed under the BSD license, and used with permission.
|
9
9
|
|
10
|
-
The public certificate for
|
10
|
+
The public certificate for this gem is here[http://rubyforge.org/frs/download.php/25331/evan_weaver-original-public_cert.pem].
|
11
11
|
|
12
12
|
If you like this software, please {make a donation}[http://blog.evanweaver.com/donate/], or {recommend Evan}[http://www.workingwithrails.com/person/7739-evan-weaver] at Working with Rails.
|
13
13
|
|
14
|
-
== Status
|
15
|
-
|
16
|
-
Very new. Risky in production.
|
17
|
-
|
18
14
|
== Features
|
19
15
|
|
20
16
|
* clean API
|
@@ -22,13 +18,13 @@ Very new. Risky in production.
|
|
22
18
|
* multiple hashing modes, including consistent hashing
|
23
19
|
* ludicrous speed, including optional non-blocking IO
|
24
20
|
|
25
|
-
|
21
|
+
The <b>memcached</b> library wraps the pure-C libmemcached client via SWIG. Both libraries are very new; use caution.
|
26
22
|
|
27
|
-
|
23
|
+
== Installation
|
28
24
|
|
29
|
-
Other versions of libmemcached are not supported.
|
25
|
+
You need {libmemcached 0.13}[http://tangent.org/552/libmemcached.html]. Other versions of libmemcached are not supported. You also need {memcached itself}[http://www.danga.com/memcached/] if you want to test against a local server.
|
30
26
|
|
31
|
-
|
27
|
+
Download and extract the {libmemcached tarball}[http://download.tangent.org/libmemcached-0.13.tar.gz]. Then for Linux, run:
|
32
28
|
./configure
|
33
29
|
make && sudo make install
|
34
30
|
|
@@ -36,9 +32,96 @@ For OS X/MacPorts, run:
|
|
36
32
|
./configure --prefix=/opt/local
|
37
33
|
make && sudo make install
|
38
34
|
|
35
|
+
Now install the gem:
|
36
|
+
sudo gem install memcached --no-rdoc --no-ri
|
37
|
+
|
39
38
|
== Usage
|
40
39
|
|
41
|
-
|
40
|
+
Start a local memcached server:
|
41
|
+
$ memcached -p 11211 &
|
42
|
+
|
43
|
+
Now, in Ruby, require the library and instantiate a Memcached object at a global level:
|
44
|
+
|
45
|
+
require 'memcached'
|
46
|
+
$cache = Memcached.new("127.0.0.1:11211")
|
47
|
+
|
48
|
+
Now you can set things and get things:
|
49
|
+
|
50
|
+
value = 'hello'
|
51
|
+
$cache.set 'test', value
|
52
|
+
$cache.get 'test' #=> "hello"
|
53
|
+
|
54
|
+
You can set with an expiration timeout:
|
55
|
+
|
56
|
+
value = 'hello'
|
57
|
+
$cache.set 'test', value, 1
|
58
|
+
sleep(2)
|
59
|
+
$cache.get 'test' #=> raises Memcached::NotFound
|
60
|
+
|
61
|
+
You can get multiple values at once:
|
62
|
+
|
63
|
+
value = 'hello'
|
64
|
+
$cache.set 'test', value
|
65
|
+
$cache.get ['test', 'test2'] #=> ["hello", Memcached::NotFound]
|
66
|
+
|
67
|
+
You can set a counter and increment it:
|
68
|
+
|
69
|
+
start = 1
|
70
|
+
$cache.set 'counter', start, 0, false
|
71
|
+
$cache.increment 'counter' #=> 2
|
72
|
+
$cache.increment 'counter' #=> 3
|
73
|
+
$cache.get('counter', false).to_i #=> 3
|
74
|
+
|
75
|
+
You can get some server stats:
|
76
|
+
|
77
|
+
$cache.stats #=> {..., :bytes_written=>[62], :version=>["1.2.4"] ...}
|
78
|
+
|
79
|
+
Note that the API is not the same as that of <b>Ruby-MemCache</b> or <b>memcache-client</b>. In particular, <tt>nil</tt> is a valid record value. Memcached#get does not return <tt>nil</tt> on failure, rather it raises <b>Memcached::NotFound</b>. This is consistent with the behavior of memcached itself. For example:
|
80
|
+
|
81
|
+
$cache.set 'test', nil
|
82
|
+
$cache.get 'test' #=> nil
|
83
|
+
$cache.delete 'test'
|
84
|
+
$cache.get 'test' #=> raises Memcached::NotFound
|
85
|
+
|
86
|
+
A compatibility wrapper for legacy applications is in progress.
|
87
|
+
|
88
|
+
== Threading
|
89
|
+
|
90
|
+
<b>memcached</b> is threadsafe, but each thread requires its own Memcached instance. Create a global Memcached, and then call Memcached#clone each time you spawn a thread.
|
91
|
+
|
92
|
+
thread = Thread.new do
|
93
|
+
cache = $cache.clone
|
94
|
+
# Perform operations on cache, not $cache
|
95
|
+
cache.set 'example', 1
|
96
|
+
cache.get 'example'
|
97
|
+
# ...
|
98
|
+
end
|
99
|
+
|
100
|
+
# Join the thread so that exceptions don't get lost
|
101
|
+
thread.join
|
102
|
+
|
103
|
+
== Benchmarks
|
104
|
+
|
105
|
+
<b>memcached</b> is much, much faster than <b>memcache-client</b>:
|
106
|
+
|
107
|
+
user system total real
|
108
|
+
set:ruby:noblock:memcached 0.050000 0.000000 0.050000 ( 0.054205)
|
109
|
+
set:ruby:memcached 0.130000 0.160000 0.290000 ( 0.338529)
|
110
|
+
set:ruby:memcache-client 3.690000 0.130000 3.820000 ( 4.030806)
|
111
|
+
...
|
112
|
+
get:ruby:memcached 0.110000 0.020000 0.130000 ( 0.316446)
|
113
|
+
get:ruby:memcache-client 3.730000 0.120000 3.850000 ( 4.040446)
|
114
|
+
...
|
115
|
+
missing:ruby:memcached 0.160000 0.090000 0.250000 ( 0.401891)
|
116
|
+
missing:ruby:memcache-client 3.650000 0.090000 3.740000 ( 3.880192)
|
117
|
+
...
|
118
|
+
mixed:ruby:noblock:memcached 0.190000 0.230000 0.420000 ( 0.667130)
|
119
|
+
mixed:ruby:memcached 0.250000 0.250000 0.500000 ( 0.663093)
|
120
|
+
mixed:ruby:memcache-client 7.410000 0.210000 7.620000 ( 7.942145)
|
121
|
+
|
122
|
+
These benchmarks were run on x86-64 Linux. You can easily run your own benchmarks, as long as you have memcached itself on your system:
|
123
|
+
$ ruby -e 'system("ruby #{File.dirname(`gem which memcached`.split("\n").
|
124
|
+
last)}/../test/benchmark/benchmark.rb")'
|
42
125
|
|
43
126
|
== Reporting problems
|
44
127
|
|
@@ -48,4 +131,5 @@ Patches and contributions are very welcome. Please note that contributors are re
|
|
48
131
|
|
49
132
|
== Further resources
|
50
133
|
|
51
|
-
|
134
|
+
* {Memcached wiki}[http://www.socialtext.net/memcached/index.cgi]
|
135
|
+
* {Libmemcached homepage}[http://tangent.org/552/libmemcached.html]
|
data/TODO
ADDED
data/ext/extconf.rb
CHANGED
@@ -12,5 +12,13 @@ if ENV['DEBUG']
|
|
12
12
|
end
|
13
13
|
|
14
14
|
dir_config 'libmemcached'
|
15
|
-
|
15
|
+
|
16
|
+
# XXX There's probably a better way to do this
|
17
|
+
unless find_library 'memcached', 'memcached_server_add', *ENV['LD_LIBRARY_PATH'].to_s.split(":")
|
18
|
+
raise "shared library 'libmemcached' not found"
|
19
|
+
end
|
20
|
+
unless find_header 'libmemcached/memcached.h', *ENV['INCLUDE_PATH'].to_s.split(":")
|
21
|
+
raise "header file 'libmemcached/memcached.h' not found"
|
22
|
+
end
|
23
|
+
|
16
24
|
create_makefile 'libmemcached'
|
data/ext/libmemcached.i
CHANGED
@@ -55,7 +55,7 @@
|
|
55
55
|
free($1);
|
56
56
|
};
|
57
57
|
|
58
|
-
%include "libmemcached.h"
|
58
|
+
%include "/opt/local/include/libmemcached/memcached.h"
|
59
59
|
|
60
60
|
// Manual wrappers
|
61
61
|
|
@@ -94,3 +94,14 @@ void memcached_repair_server_st(memcached_st *in_ptr, memcached_server_st *host)
|
|
94
94
|
host->write_ptr= 0;
|
95
95
|
};
|
96
96
|
%}
|
97
|
+
|
98
|
+
// Stub some bogus methods left in the 0.13 memcached.h header
|
99
|
+
%{
|
100
|
+
memcached_return memcached_mdelete(memcached_st *ptr, char **key, size_t *key_length, unsigned int number_of_keys, time_t expiration) {
|
101
|
+
return;
|
102
|
+
};
|
103
|
+
memcached_return memcached_mdelete_by_key(memcached_st *ptr, char *master_key, size_t master_key_length,
|
104
|
+
char **key, size_t *key_length, unsigned int number_of_keys, time_t expiration) {
|
105
|
+
return;
|
106
|
+
};
|
107
|
+
%}
|
data/ext/libmemcached_wrap.c
CHANGED
@@ -1940,6 +1940,15 @@ void memcached_repair_server_st(memcached_st *in_ptr, memcached_server_st *host)
|
|
1940
1940
|
host->write_ptr= 0;
|
1941
1941
|
};
|
1942
1942
|
|
1943
|
+
|
1944
|
+
memcached_return memcached_mdelete(memcached_st *ptr, char **key, size_t *key_length, unsigned int number_of_keys, time_t expiration) {
|
1945
|
+
return;
|
1946
|
+
};
|
1947
|
+
memcached_return memcached_mdelete_by_key(memcached_st *ptr, char *master_key, size_t master_key_length,
|
1948
|
+
char **key, size_t *key_length, unsigned int number_of_keys, time_t expiration) {
|
1949
|
+
return;
|
1950
|
+
};
|
1951
|
+
|
1943
1952
|
swig_class cMemcachedServerSt;
|
1944
1953
|
|
1945
1954
|
SWIGINTERN VALUE
|
@@ -8222,6 +8231,135 @@ fail:
|
|
8222
8231
|
}
|
8223
8232
|
|
8224
8233
|
|
8234
|
+
SWIGINTERN VALUE
|
8235
|
+
_wrap_memcached_mdelete(int argc, VALUE *argv, VALUE self) {
|
8236
|
+
memcached_st *arg1 = (memcached_st *) 0 ;
|
8237
|
+
char **arg2 = (char **) 0 ;
|
8238
|
+
size_t *arg3 = (size_t *) 0 ;
|
8239
|
+
unsigned int arg4 ;
|
8240
|
+
time_t arg5 ;
|
8241
|
+
memcached_return result;
|
8242
|
+
void *argp1 = 0 ;
|
8243
|
+
int res1 = 0 ;
|
8244
|
+
void *argp2 = 0 ;
|
8245
|
+
int res2 = 0 ;
|
8246
|
+
void *argp3 = 0 ;
|
8247
|
+
int res3 = 0 ;
|
8248
|
+
unsigned int val4 ;
|
8249
|
+
int ecode4 = 0 ;
|
8250
|
+
VALUE vresult = Qnil;
|
8251
|
+
|
8252
|
+
if ((argc < 5) || (argc > 5)) {
|
8253
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 5)",argc); SWIG_fail;
|
8254
|
+
}
|
8255
|
+
res1 = SWIG_ConvertPtr(argv[0], &argp1,SWIGTYPE_p_memcached_st, 0 | 0 );
|
8256
|
+
if (!SWIG_IsOK(res1)) {
|
8257
|
+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "memcached_mdelete" "', argument " "1"" of type '" "memcached_st *""'");
|
8258
|
+
}
|
8259
|
+
arg1 = (memcached_st *)(argp1);
|
8260
|
+
res2 = SWIG_ConvertPtr(argv[1], &argp2,SWIGTYPE_p_p_char, 0 | 0 );
|
8261
|
+
if (!SWIG_IsOK(res2)) {
|
8262
|
+
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "memcached_mdelete" "', argument " "2"" of type '" "char **""'");
|
8263
|
+
}
|
8264
|
+
arg2 = (char **)(argp2);
|
8265
|
+
res3 = SWIG_ConvertPtr(argv[2], &argp3,SWIGTYPE_p_size_t, 0 | 0 );
|
8266
|
+
if (!SWIG_IsOK(res3)) {
|
8267
|
+
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "memcached_mdelete" "', argument " "3"" of type '" "size_t *""'");
|
8268
|
+
}
|
8269
|
+
arg3 = (size_t *)(argp3);
|
8270
|
+
ecode4 = SWIG_AsVal_unsigned_SS_int(argv[3], &val4);
|
8271
|
+
if (!SWIG_IsOK(ecode4)) {
|
8272
|
+
SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "memcached_mdelete" "', argument " "4"" of type '" "unsigned int""'");
|
8273
|
+
}
|
8274
|
+
arg4 = (unsigned int)(val4);
|
8275
|
+
{
|
8276
|
+
if (NIL_P(argv[4]))
|
8277
|
+
arg5 = (time_t)-1;
|
8278
|
+
else
|
8279
|
+
arg5 = NUM2LONG(rb_funcall(argv[4], rb_intern("tv_sec"), 0));
|
8280
|
+
}
|
8281
|
+
result = (memcached_return)memcached_mdelete(arg1,arg2,arg3,arg4,arg5);
|
8282
|
+
vresult = SWIG_From_int((int)(result));
|
8283
|
+
return vresult;
|
8284
|
+
fail:
|
8285
|
+
return Qnil;
|
8286
|
+
}
|
8287
|
+
|
8288
|
+
|
8289
|
+
SWIGINTERN VALUE
|
8290
|
+
_wrap_memcached_mdelete_by_key(int argc, VALUE *argv, VALUE self) {
|
8291
|
+
memcached_st *arg1 = (memcached_st *) 0 ;
|
8292
|
+
char *arg2 = (char *) 0 ;
|
8293
|
+
size_t arg3 ;
|
8294
|
+
char **arg4 = (char **) 0 ;
|
8295
|
+
size_t *arg5 = (size_t *) 0 ;
|
8296
|
+
unsigned int arg6 ;
|
8297
|
+
time_t arg7 ;
|
8298
|
+
memcached_return result;
|
8299
|
+
void *argp1 = 0 ;
|
8300
|
+
int res1 = 0 ;
|
8301
|
+
int res2 ;
|
8302
|
+
char *buf2 = 0 ;
|
8303
|
+
int alloc2 = 0 ;
|
8304
|
+
size_t val3 ;
|
8305
|
+
int ecode3 = 0 ;
|
8306
|
+
void *argp4 = 0 ;
|
8307
|
+
int res4 = 0 ;
|
8308
|
+
void *argp5 = 0 ;
|
8309
|
+
int res5 = 0 ;
|
8310
|
+
unsigned int val6 ;
|
8311
|
+
int ecode6 = 0 ;
|
8312
|
+
VALUE vresult = Qnil;
|
8313
|
+
|
8314
|
+
if ((argc < 7) || (argc > 7)) {
|
8315
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 7)",argc); SWIG_fail;
|
8316
|
+
}
|
8317
|
+
res1 = SWIG_ConvertPtr(argv[0], &argp1,SWIGTYPE_p_memcached_st, 0 | 0 );
|
8318
|
+
if (!SWIG_IsOK(res1)) {
|
8319
|
+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "memcached_mdelete_by_key" "', argument " "1"" of type '" "memcached_st *""'");
|
8320
|
+
}
|
8321
|
+
arg1 = (memcached_st *)(argp1);
|
8322
|
+
res2 = SWIG_AsCharPtrAndSize(argv[1], &buf2, NULL, &alloc2);
|
8323
|
+
if (!SWIG_IsOK(res2)) {
|
8324
|
+
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "memcached_mdelete_by_key" "', argument " "2"" of type '" "char *""'");
|
8325
|
+
}
|
8326
|
+
arg2 = buf2;
|
8327
|
+
ecode3 = SWIG_AsVal_size_t(argv[2], &val3);
|
8328
|
+
if (!SWIG_IsOK(ecode3)) {
|
8329
|
+
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "memcached_mdelete_by_key" "', argument " "3"" of type '" "size_t""'");
|
8330
|
+
}
|
8331
|
+
arg3 = (size_t)(val3);
|
8332
|
+
res4 = SWIG_ConvertPtr(argv[3], &argp4,SWIGTYPE_p_p_char, 0 | 0 );
|
8333
|
+
if (!SWIG_IsOK(res4)) {
|
8334
|
+
SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "memcached_mdelete_by_key" "', argument " "4"" of type '" "char **""'");
|
8335
|
+
}
|
8336
|
+
arg4 = (char **)(argp4);
|
8337
|
+
res5 = SWIG_ConvertPtr(argv[4], &argp5,SWIGTYPE_p_size_t, 0 | 0 );
|
8338
|
+
if (!SWIG_IsOK(res5)) {
|
8339
|
+
SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "memcached_mdelete_by_key" "', argument " "5"" of type '" "size_t *""'");
|
8340
|
+
}
|
8341
|
+
arg5 = (size_t *)(argp5);
|
8342
|
+
ecode6 = SWIG_AsVal_unsigned_SS_int(argv[5], &val6);
|
8343
|
+
if (!SWIG_IsOK(ecode6)) {
|
8344
|
+
SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "memcached_mdelete_by_key" "', argument " "6"" of type '" "unsigned int""'");
|
8345
|
+
}
|
8346
|
+
arg6 = (unsigned int)(val6);
|
8347
|
+
{
|
8348
|
+
if (NIL_P(argv[6]))
|
8349
|
+
arg7 = (time_t)-1;
|
8350
|
+
else
|
8351
|
+
arg7 = NUM2LONG(rb_funcall(argv[6], rb_intern("tv_sec"), 0));
|
8352
|
+
}
|
8353
|
+
result = (memcached_return)memcached_mdelete_by_key(arg1,arg2,arg3,arg4,arg5,arg6,arg7);
|
8354
|
+
vresult = SWIG_From_int((int)(result));
|
8355
|
+
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
|
8356
|
+
return vresult;
|
8357
|
+
fail:
|
8358
|
+
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
|
8359
|
+
return Qnil;
|
8360
|
+
}
|
8361
|
+
|
8362
|
+
|
8225
8363
|
SWIGINTERN VALUE
|
8226
8364
|
_wrap_memcached_fetch_execute(int argc, VALUE *argv, VALUE self) {
|
8227
8365
|
memcached_st *arg1 = (memcached_st *) 0 ;
|
@@ -9146,6 +9284,8 @@ SWIGEXPORT void Init_libmemcached(void) {
|
|
9146
9284
|
rb_define_module_function(mLibmemcached, "memcached_append_by_key", _wrap_memcached_append_by_key, -1);
|
9147
9285
|
rb_define_module_function(mLibmemcached, "memcached_cas_by_key", _wrap_memcached_cas_by_key, -1);
|
9148
9286
|
rb_define_module_function(mLibmemcached, "memcached_delete_by_key", _wrap_memcached_delete_by_key, -1);
|
9287
|
+
rb_define_module_function(mLibmemcached, "memcached_mdelete", _wrap_memcached_mdelete, -1);
|
9288
|
+
rb_define_module_function(mLibmemcached, "memcached_mdelete_by_key", _wrap_memcached_mdelete_by_key, -1);
|
9149
9289
|
rb_define_module_function(mLibmemcached, "memcached_fetch_execute", _wrap_memcached_fetch_execute, -1);
|
9150
9290
|
rb_define_module_function(mLibmemcached, "memcached_result_free", _wrap_memcached_result_free, -1);
|
9151
9291
|
rb_define_module_function(mLibmemcached, "memcached_result_create", _wrap_memcached_result_create, -1);
|
data/lib/memcached.rb
CHANGED
@@ -4,3 +4,20 @@ require 'memcached/integer'
|
|
4
4
|
require 'memcached/exceptions'
|
5
5
|
require 'memcached/behaviors'
|
6
6
|
require 'memcached/memcached'
|
7
|
+
|
8
|
+
=begin rdoc
|
9
|
+
The generated SWIG module for accessing libmemcached's C API.
|
10
|
+
|
11
|
+
Includes the full set of libmemcached static methods (as defined in <tt>$INCLUDE_PATH/libmemcached/memcached.h</tt>), and classes for the available structs:
|
12
|
+
|
13
|
+
* Libmemcached::MemcachedResultSt
|
14
|
+
* Libmemcached::MemcachedServerSt
|
15
|
+
* Libmemcached::MemcachedSt
|
16
|
+
* Libmemcached::MemcachedStatSt
|
17
|
+
* Libmemcached::MemcachedStringSt
|
18
|
+
|
19
|
+
A number of SWIG typemaps and C helper methods are also defined in <tt>ext/libmemcached.i</tt>.
|
20
|
+
|
21
|
+
=end
|
22
|
+
module Libmemcached
|
23
|
+
end
|
data/lib/memcached/behaviors.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
|
2
2
|
class Memcached
|
3
3
|
|
4
|
+
#:stopdoc:
|
5
|
+
|
4
6
|
def self.load_constants(prefix, hash = {}, offset = 0)
|
5
7
|
Libmemcached.constants.grep(/^#{prefix}/).each do |const_name|
|
6
8
|
hash[const_name[prefix.length..-1].downcase.to_sym] = Libmemcached.const_get(const_name) + offset
|
@@ -21,9 +23,12 @@ class Memcached
|
|
21
23
|
DISTRIBUTION_VALUES = {}
|
22
24
|
BEHAVIOR_VALUES.merge!(load_constants("MEMCACHED_DISTRIBUTION_", DISTRIBUTION_VALUES, 2))
|
23
25
|
|
26
|
+
#:startdoc:
|
27
|
+
|
24
28
|
private
|
25
29
|
|
26
|
-
|
30
|
+
# Set a behavior option for this Memcached instance. Accepts a Symbol <tt>behavior</tt> and either <tt>true</tt>, <tt>false</tt>, or a Symbol for <tt>value</tt>. Arguments are validated and converted into integers for the struct setter method.
|
31
|
+
def set_behavior(behavior, value) #:doc:
|
27
32
|
raise ArgumentError, "No setting #{behavior.inspect}" unless b_id = BEHAVIORS[behavior]
|
28
33
|
raise ArgumentError, "No setting value #{value.inspect}" unless v_id = BEHAVIOR_VALUES[value]
|
29
34
|
|
data/lib/memcached/exceptions.rb
CHANGED
@@ -1,12 +1,55 @@
|
|
1
1
|
|
2
2
|
class Memcached
|
3
3
|
|
4
|
+
=begin rdoc
|
5
|
+
|
6
|
+
Superclass for all Memcached runtime exceptions.
|
7
|
+
|
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
|
+
|
10
|
+
== Subclasses
|
11
|
+
|
12
|
+
* Memcached::AKeyLengthOfZeroWasProvided
|
13
|
+
* Memcached::ATimeoutOccurred
|
14
|
+
* Memcached::ActionNotSupported
|
15
|
+
* Memcached::ActionQueued
|
16
|
+
* Memcached::ClientError
|
17
|
+
* Memcached::ConnectionBindFailure
|
18
|
+
* Memcached::ConnectionDataDoesNotExist
|
19
|
+
* Memcached::ConnectionDataExists
|
20
|
+
* Memcached::ConnectionFailure
|
21
|
+
* Memcached::ConnectionSocketCreateFailure
|
22
|
+
* Memcached::CouldNotOpenUnixSocket
|
23
|
+
* Memcached::Failure
|
24
|
+
* Memcached::FetchWasNotCompleted
|
25
|
+
* Memcached::HostnameLookupFailure
|
26
|
+
* Memcached::MemoryAllocationFailure
|
27
|
+
* Memcached::NoServersDefined
|
28
|
+
* Memcached::NotFound
|
29
|
+
* Memcached::NotStored
|
30
|
+
* Memcached::PartialRead
|
31
|
+
* Memcached::ProtocolError
|
32
|
+
* Memcached::ReadFailure
|
33
|
+
* Memcached::ServerDelete
|
34
|
+
* Memcached::ServerEnd
|
35
|
+
* Memcached::ServerError
|
36
|
+
* Memcached::ServerValue
|
37
|
+
* Memcached::SomeErrorsWereReported
|
38
|
+
* Memcached::StatValue
|
39
|
+
* Memcached::SystemError
|
40
|
+
* Memcached::UnknownReadFailure
|
41
|
+
* Memcached::WriteFailure
|
42
|
+
|
43
|
+
=end
|
4
44
|
class Error < RuntimeError
|
5
45
|
end
|
6
46
|
|
7
|
-
|
47
|
+
# Raised if a method depends on functionality not yet completed in libmemcached.
|
48
|
+
class NotImplemented < NoMethodError
|
8
49
|
end
|
9
50
|
|
51
|
+
#:stopdoc:
|
52
|
+
|
10
53
|
class << self
|
11
54
|
private
|
12
55
|
def camelize(string)
|
@@ -14,17 +57,19 @@ class Memcached
|
|
14
57
|
end
|
15
58
|
end
|
16
59
|
|
17
|
-
|
18
|
-
|
19
|
-
Libmemcached.memcached_create(
|
60
|
+
EXCEPTIONS = []
|
61
|
+
EMPTY_STRUCT = Libmemcached::MemcachedSt.new
|
62
|
+
Libmemcached.memcached_create(EMPTY_STRUCT)
|
20
63
|
|
21
64
|
# Generate exception classes
|
22
|
-
Libmemcached::MEMCACHED_MAXIMUM_RETURN.times do |
|
23
|
-
description = Libmemcached.memcached_strerror(
|
65
|
+
Libmemcached::MEMCACHED_MAXIMUM_RETURN.times do |index|
|
66
|
+
description = Libmemcached.memcached_strerror(EMPTY_STRUCT, index)
|
24
67
|
exception_class = eval("class #{camelize(description)} < Error; self; end")
|
25
|
-
|
68
|
+
EXCEPTIONS << exception_class
|
26
69
|
end
|
27
70
|
|
28
71
|
# Verify library version
|
29
|
-
# XXX
|
72
|
+
# XXX Waiting on libmemcached 0.14
|
73
|
+
|
74
|
+
#:startdoc:
|
30
75
|
end
|