astro-remcached 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +2 -2
- data/lib/remcached.rb +78 -11
- data/lib/remcached/client.rb +0 -17
- data/lib/remcached/const.rb +4 -0
- data/lib/remcached/packet.rb +56 -8
- data/remcached.gemspec +9 -6
- data/spec/client_spec.rb +0 -116
- data/spec/memcached_spec.rb +201 -5
- metadata +3 -3
data/VERSION.yml
CHANGED
data/lib/remcached.rb
CHANGED
@@ -56,31 +56,98 @@ module Memcached
|
|
56
56
|
hashed
|
57
57
|
end
|
58
58
|
|
59
|
-
|
59
|
+
|
60
|
+
##
|
61
|
+
# Memcached operations
|
62
|
+
##
|
63
|
+
|
64
|
+
def operation(request_klass, contents, &callback)
|
60
65
|
client = client_for_key(contents[:key])
|
61
66
|
if client
|
62
|
-
client.
|
67
|
+
client.send_request request_klass.new(contents), &callback
|
63
68
|
elsif callback
|
64
69
|
callback.call :status => Errors::DISCONNECTED
|
65
70
|
end
|
66
71
|
end
|
67
72
|
|
68
|
-
|
69
|
-
##
|
70
|
-
# Memcached operations
|
71
|
-
##
|
72
|
-
|
73
73
|
def add(contents, &callback)
|
74
|
-
operation
|
74
|
+
operation Request::Add, contents, &callback
|
75
75
|
end
|
76
76
|
def get(contents, &callback)
|
77
|
-
operation
|
77
|
+
operation Request::Get, contents, &callback
|
78
78
|
end
|
79
79
|
def set(contents, &callback)
|
80
|
-
operation
|
80
|
+
operation Request::Set, contents, &callback
|
81
81
|
end
|
82
82
|
def delete(contents, &callback)
|
83
|
-
operation
|
83
|
+
operation Request::Delete, contents, &callback
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
##
|
88
|
+
# Multi operations
|
89
|
+
#
|
90
|
+
##
|
91
|
+
|
92
|
+
def multi_operation(request_klass, contents_list, &callback)
|
93
|
+
results = {}
|
94
|
+
|
95
|
+
# Assemble client connections per keys
|
96
|
+
client_contents = {}
|
97
|
+
contents_list.each do |contents|
|
98
|
+
client = client_for_key(contents[:key])
|
99
|
+
if client
|
100
|
+
client_contents[client] ||= []
|
101
|
+
client_contents[client] << contents
|
102
|
+
else
|
103
|
+
puts "no client for #{contents[:key].inspect}"
|
104
|
+
results[contents[:key]] = {:status => Memcached::Errors::DISCONNECTED}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# send requests and wait for responses per client
|
109
|
+
clients_pending = client_contents.length
|
110
|
+
client_contents.each do |client,contents_list|
|
111
|
+
last_i = contents_list.length - 1
|
112
|
+
client_results = {}
|
113
|
+
|
114
|
+
contents_list.each_with_index do |contents,i|
|
115
|
+
if i < last_i
|
116
|
+
request = request_klass::Quiet.new(contents)
|
117
|
+
client.send_request(request) { |response|
|
118
|
+
results[contents[:key]] = response
|
119
|
+
}
|
120
|
+
else # last request for this client
|
121
|
+
request = request_klass.new(contents)
|
122
|
+
client.send_request(request) { |response|
|
123
|
+
results[contents[:key]] = response
|
124
|
+
clients_pending -= 1
|
125
|
+
if clients_pending < 1
|
126
|
+
callback.call results
|
127
|
+
end
|
128
|
+
}
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
self
|
84
134
|
end
|
135
|
+
|
136
|
+
def multi_add(contents_list, &callback)
|
137
|
+
multi_operation Request::Add, contents_list, &callback
|
138
|
+
end
|
139
|
+
|
140
|
+
def multi_get(contents_list, &callback)
|
141
|
+
multi_operation Request::Get, contents_list, &callback
|
142
|
+
end
|
143
|
+
|
144
|
+
def multi_set(contents_list, &callback)
|
145
|
+
multi_operation Request::Set, contents_list, &callback
|
146
|
+
end
|
147
|
+
|
148
|
+
def multi_delete(contents_list, &callback)
|
149
|
+
multi_operation Request::Delete, contents_list, &callback
|
150
|
+
end
|
151
|
+
|
85
152
|
end
|
86
153
|
end
|
data/lib/remcached/client.rb
CHANGED
@@ -129,23 +129,6 @@ module Memcached
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
|
133
|
-
def get(contents, &callback)
|
134
|
-
send_request Request::Get.new(contents), &callback
|
135
|
-
end
|
136
|
-
|
137
|
-
def add(contents, &callback)
|
138
|
-
send_request Request::Add.new(contents), &callback
|
139
|
-
end
|
140
|
-
|
141
|
-
def set(contents, &callback)
|
142
|
-
send_request Request::Set.new(contents), &callback
|
143
|
-
end
|
144
|
-
|
145
|
-
def delete(contents, &callback)
|
146
|
-
send_request Request::Delete.new(contents), &callback
|
147
|
-
end
|
148
|
-
|
149
132
|
# Callback will be called multiple times
|
150
133
|
def stats(contents={}, &callback)
|
151
134
|
send_request Request::Stats.new(contents) do |result|
|
data/lib/remcached/const.rb
CHANGED
data/lib/remcached/packet.rb
CHANGED
@@ -2,6 +2,8 @@ require 'remcached/pack_array'
|
|
2
2
|
|
3
3
|
module Memcached
|
4
4
|
class Packet
|
5
|
+
##
|
6
|
+
# Initialize with fields
|
5
7
|
def initialize(contents={})
|
6
8
|
@contents = contents
|
7
9
|
(self.class.fields +
|
@@ -10,15 +12,20 @@ module Memcached
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
15
|
+
##
|
16
|
+
# Get field
|
13
17
|
def [](field)
|
14
18
|
@contents[field]
|
15
19
|
end
|
16
20
|
|
21
|
+
##
|
22
|
+
# Set field
|
17
23
|
def []=(field, value)
|
18
24
|
@contents[field] = value
|
19
25
|
end
|
20
26
|
|
21
|
-
|
27
|
+
##
|
28
|
+
# Define a field for subclasses
|
22
29
|
def self.field(name, packed, default=nil)
|
23
30
|
instance_eval do
|
24
31
|
@fields ||= []
|
@@ -26,6 +33,8 @@ module Memcached
|
|
26
33
|
end
|
27
34
|
end
|
28
35
|
|
36
|
+
##
|
37
|
+
# Fields of parent and this class
|
29
38
|
def self.fields
|
30
39
|
parent_class = ancestors[1]
|
31
40
|
parent_fields = parent_class.respond_to?(:fields) ? parent_class.fields : []
|
@@ -33,6 +42,8 @@ module Memcached
|
|
33
42
|
parent_fields + class_fields
|
34
43
|
end
|
35
44
|
|
45
|
+
##
|
46
|
+
# Define an extra for subclasses
|
36
47
|
def self.extra(name, packed, default=nil)
|
37
48
|
instance_eval do
|
38
49
|
@extras ||= []
|
@@ -40,10 +51,17 @@ module Memcached
|
|
40
51
|
end
|
41
52
|
end
|
42
53
|
|
54
|
+
##
|
55
|
+
# Extras of this class
|
43
56
|
def self.extras
|
44
|
-
|
57
|
+
parent_class = ancestors[1]
|
58
|
+
parent_extras = parent_class.respond_to?(:extras) ? parent_class.extras : []
|
59
|
+
class_extras = instance_eval { @extras || [] }
|
60
|
+
parent_extras + class_extras
|
45
61
|
end
|
46
62
|
|
63
|
+
##
|
64
|
+
# Build a packet by parsing header fields
|
47
65
|
def self.parse_header(buf)
|
48
66
|
pack_fmt = fields.collect { |name,fmt,default| fmt }.join
|
49
67
|
values = PackArray.unpack(buf, pack_fmt)
|
@@ -56,7 +74,11 @@ module Memcached
|
|
56
74
|
new contents
|
57
75
|
end
|
58
76
|
|
59
|
-
|
77
|
+
##
|
78
|
+
# Parse body of packet when the +:total_body_length+ field is
|
79
|
+
# known by header. Pass it at least +total_body_length+ bytes.
|
80
|
+
#
|
81
|
+
# return:: [String] remaining bytes
|
60
82
|
def parse_body(buf)
|
61
83
|
buf, rest = buf[0..(self[:total_body_length] - 1)], buf[self[:total_body_length]..-1]
|
62
84
|
|
@@ -75,6 +97,8 @@ module Memcached
|
|
75
97
|
rest
|
76
98
|
end
|
77
99
|
|
100
|
+
##
|
101
|
+
# Serialize for wire
|
78
102
|
def to_s
|
79
103
|
extras_s = extras_to_s
|
80
104
|
key_s = self[:key].to_s
|
@@ -154,7 +178,13 @@ module Memcached
|
|
154
178
|
|
155
179
|
class Get < Request
|
156
180
|
def initialize(contents)
|
157
|
-
super(
|
181
|
+
super({:opcode=>Commands::GET}.merge(contents))
|
182
|
+
end
|
183
|
+
|
184
|
+
class Quiet < Get
|
185
|
+
def initialize(contents)
|
186
|
+
super({:opcode=>Commands::GETQ}.merge(contents))
|
187
|
+
end
|
158
188
|
end
|
159
189
|
end
|
160
190
|
|
@@ -163,7 +193,13 @@ module Memcached
|
|
163
193
|
extra :expiration, 'N', 0
|
164
194
|
|
165
195
|
def initialize(contents)
|
166
|
-
super(
|
196
|
+
super({:opcode=>Commands::ADD}.merge(contents))
|
197
|
+
end
|
198
|
+
|
199
|
+
class Quiet < Add
|
200
|
+
def initialize(contents)
|
201
|
+
super({:opcode=>Commands::ADDQ}.merge(contents))
|
202
|
+
end
|
167
203
|
end
|
168
204
|
end
|
169
205
|
|
@@ -172,19 +208,31 @@ module Memcached
|
|
172
208
|
extra :expiration, 'N', 0
|
173
209
|
|
174
210
|
def initialize(contents)
|
175
|
-
super(
|
211
|
+
super({:opcode=>Commands::SET}.merge(contents))
|
212
|
+
end
|
213
|
+
|
214
|
+
class Quiet < Set
|
215
|
+
def initialize(contents)
|
216
|
+
super({:opcode=>Commands::SETQ}.merge(contents))
|
217
|
+
end
|
176
218
|
end
|
177
219
|
end
|
178
220
|
|
179
221
|
class Delete < Request
|
180
222
|
def initialize(contents)
|
181
|
-
super(
|
223
|
+
super({:opcode=>Commands::DELETE}.merge(contents))
|
224
|
+
end
|
225
|
+
|
226
|
+
class Quiet < Delete
|
227
|
+
def initialize(contents)
|
228
|
+
super({:opcode=>Commands::DELETEQ}.merge(contents))
|
229
|
+
end
|
182
230
|
end
|
183
231
|
end
|
184
232
|
|
185
233
|
class Stats < Request
|
186
234
|
def initialize(contents)
|
187
|
-
super(
|
235
|
+
super({:opcode=>Commands::STAT}.merge(contents))
|
188
236
|
end
|
189
237
|
end
|
190
238
|
end
|
data/remcached.gemspec
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
1
4
|
# -*- encoding: utf-8 -*-
|
2
5
|
|
3
6
|
Gem::Specification.new do |s|
|
4
7
|
s.name = %q{remcached}
|
5
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
6
9
|
|
7
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
11
|
s.authors = ["Stephan Maka"]
|
9
|
-
s.date = %q{2009-09-
|
12
|
+
s.date = %q{2009-09-17}
|
10
13
|
s.description = %q{Ruby EventMachine memcached client}
|
11
14
|
s.email = %q{astro@spaceboyz.net}
|
12
15
|
s.files = [
|
@@ -26,12 +29,12 @@ Gem::Specification.new do |s|
|
|
26
29
|
s.homepage = %q{http://github.com/astro/remcached/}
|
27
30
|
s.rdoc_options = ["--charset=UTF-8"]
|
28
31
|
s.require_paths = ["lib"]
|
29
|
-
s.rubygems_version = %q{1.3.
|
32
|
+
s.rubygems_version = %q{1.3.4}
|
30
33
|
s.summary = %q{Ruby EventMachine memcached client}
|
31
34
|
s.test_files = [
|
32
|
-
"spec/
|
33
|
-
"spec/
|
34
|
-
"spec/
|
35
|
+
"spec/packet_spec.rb",
|
36
|
+
"spec/client_spec.rb",
|
37
|
+
"spec/memcached_spec.rb"
|
35
38
|
]
|
36
39
|
|
37
40
|
if s.respond_to? :specification_version then
|
data/spec/client_spec.rb
CHANGED
@@ -14,122 +14,6 @@ describe Memcached::Client do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
|
17
|
-
it "should add a value" do
|
18
|
-
run do
|
19
|
-
@cl.add(:key => 'Hello',
|
20
|
-
:value => 'World') do |result|
|
21
|
-
result.should be_kind_of(Memcached::Response)
|
22
|
-
result[:status].should == Memcached::Errors::NO_ERROR
|
23
|
-
result[:cas].should_not == 0
|
24
|
-
stop
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should get a value" do
|
30
|
-
run do
|
31
|
-
@cl.get(:key => 'Hello') do |result|
|
32
|
-
result.should be_kind_of(Memcached::Response)
|
33
|
-
result[:status].should == Memcached::Errors::NO_ERROR
|
34
|
-
result[:value].should == 'World'
|
35
|
-
result[:cas].should_not == 0
|
36
|
-
@old_cas = result[:cas]
|
37
|
-
stop
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should set a value" do
|
43
|
-
run do
|
44
|
-
@cl.set(:key => 'Hello',
|
45
|
-
:value => 'Planet') do |result|
|
46
|
-
result.should be_kind_of(Memcached::Response)
|
47
|
-
result[:status].should == Memcached::Errors::NO_ERROR
|
48
|
-
result[:cas].should_not == 0
|
49
|
-
result[:cas].should_not == @old_cas
|
50
|
-
stop
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should get a value" do
|
56
|
-
run do
|
57
|
-
@cl.get(:key => 'Hello') do |result|
|
58
|
-
result.should be_kind_of(Memcached::Response)
|
59
|
-
result[:status].should == Memcached::Errors::NO_ERROR
|
60
|
-
result[:value].should == 'Planet'
|
61
|
-
result[:cas].should_not == @old_cas
|
62
|
-
stop
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should delete a value" do
|
68
|
-
run do
|
69
|
-
@cl.delete(:key => 'Hello') do |result|
|
70
|
-
result.should be_kind_of(Memcached::Response)
|
71
|
-
result[:status].should == Memcached::Errors::NO_ERROR
|
72
|
-
stop
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should not get a value" do
|
78
|
-
run do
|
79
|
-
@cl.get(:key => 'Hello') do |result|
|
80
|
-
result.should be_kind_of(Memcached::Response)
|
81
|
-
result[:status].should == Memcached::Errors::KEY_NOT_FOUND
|
82
|
-
stop
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
$n = 100
|
88
|
-
context "when incrementing a counter #{$n} times" do
|
89
|
-
it "should initialize the counter" do
|
90
|
-
run do
|
91
|
-
@cl.set(:key => 'counter',
|
92
|
-
:value => '0') do |result|
|
93
|
-
stop
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should count #{$n} times" do
|
99
|
-
$counted = 0
|
100
|
-
def count
|
101
|
-
@cl.get(:key => 'counter') do |result|
|
102
|
-
result[:status].should == Memcached::Errors::NO_ERROR
|
103
|
-
value = result[:value].to_i
|
104
|
-
@cl.set(:key => 'counter',
|
105
|
-
:value => (value + 1).to_s,
|
106
|
-
:cas => result[:cas]) do |result|
|
107
|
-
if result[:status] == Memcached::Errors::KEY_EXISTS
|
108
|
-
count # again
|
109
|
-
else
|
110
|
-
result[:status].should == Memcached::Errors::NO_ERROR
|
111
|
-
$counted += 1
|
112
|
-
stop if $counted >= $n
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
run do
|
118
|
-
$n.times { count }
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should have counted up to #{$n}" do
|
123
|
-
run do
|
124
|
-
@cl.get(:key => 'counter') do |result|
|
125
|
-
result[:status].should == Memcached::Errors::NO_ERROR
|
126
|
-
result[:value].to_i.should == $n
|
127
|
-
stop
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
17
|
context "when getting stats" do
|
134
18
|
before :all do
|
135
19
|
@stats = {}
|
data/spec/memcached_spec.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
$: << File.dirname(__FILE__) + '/../lib'
|
2
2
|
require 'remcached'
|
3
3
|
|
4
|
-
describe Memcached
|
4
|
+
describe Memcached do
|
5
5
|
def run(&block)
|
6
6
|
EM.run do
|
7
7
|
Memcached.servers = %w(127.0.0.2 localhost:11212 localhost localhost)
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
if
|
12
|
-
|
9
|
+
@timer = EM::PeriodicTimer.new(0.01) do
|
10
|
+
# at least localhost & localhost
|
11
|
+
if Memcached.usable_clients.length >= 2
|
12
|
+
@timer.cancel
|
13
13
|
block.call
|
14
14
|
end
|
15
15
|
end
|
@@ -21,6 +21,125 @@ describe Memcached::Client do
|
|
21
21
|
EM.stop
|
22
22
|
end
|
23
23
|
|
24
|
+
|
25
|
+
context "when doing a simple operation" do
|
26
|
+
it "should add a value" do
|
27
|
+
run do
|
28
|
+
Memcached.add(:key => 'Hello',
|
29
|
+
:value => 'World') do |result|
|
30
|
+
result.should be_kind_of(Memcached::Response)
|
31
|
+
result[:status].should == Memcached::Errors::NO_ERROR
|
32
|
+
result[:cas].should_not == 0
|
33
|
+
stop
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should get a value" do
|
39
|
+
run do
|
40
|
+
Memcached.get(:key => 'Hello') do |result|
|
41
|
+
result.should be_kind_of(Memcached::Response)
|
42
|
+
result[:status].should == Memcached::Errors::NO_ERROR
|
43
|
+
result[:value].should == 'World'
|
44
|
+
result[:cas].should_not == 0
|
45
|
+
@old_cas = result[:cas]
|
46
|
+
stop
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set a value" do
|
52
|
+
run do
|
53
|
+
Memcached.set(:key => 'Hello',
|
54
|
+
:value => 'Planet') do |result|
|
55
|
+
result.should be_kind_of(Memcached::Response)
|
56
|
+
result[:status].should == Memcached::Errors::NO_ERROR
|
57
|
+
result[:cas].should_not == 0
|
58
|
+
result[:cas].should_not == @old_cas
|
59
|
+
stop
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should get a value" do
|
65
|
+
run do
|
66
|
+
Memcached.get(:key => 'Hello') do |result|
|
67
|
+
result.should be_kind_of(Memcached::Response)
|
68
|
+
result[:status].should == Memcached::Errors::NO_ERROR
|
69
|
+
result[:value].should == 'Planet'
|
70
|
+
result[:cas].should_not == @old_cas
|
71
|
+
stop
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should delete a value" do
|
77
|
+
run do
|
78
|
+
Memcached.delete(:key => 'Hello') do |result|
|
79
|
+
result.should be_kind_of(Memcached::Response)
|
80
|
+
result[:status].should == Memcached::Errors::NO_ERROR
|
81
|
+
stop
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should not get a value" do
|
87
|
+
run do
|
88
|
+
Memcached.get(:key => 'Hello') do |result|
|
89
|
+
result.should be_kind_of(Memcached::Response)
|
90
|
+
result[:status].should == Memcached::Errors::KEY_NOT_FOUND
|
91
|
+
stop
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
$n = 100
|
97
|
+
context "when incrementing a counter #{$n} times" do
|
98
|
+
it "should initialize the counter" do
|
99
|
+
run do
|
100
|
+
Memcached.set(:key => 'counter',
|
101
|
+
:value => '0') do |result|
|
102
|
+
stop
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should count #{$n} times" do
|
108
|
+
@counted = 0
|
109
|
+
def count
|
110
|
+
Memcached.get(:key => 'counter') do |result|
|
111
|
+
result[:status].should == Memcached::Errors::NO_ERROR
|
112
|
+
value = result[:value].to_i
|
113
|
+
Memcached.set(:key => 'counter',
|
114
|
+
:value => (value + 1).to_s,
|
115
|
+
:cas => result[:cas]) do |result|
|
116
|
+
if result[:status] == Memcached::Errors::KEY_EXISTS
|
117
|
+
count # again
|
118
|
+
else
|
119
|
+
result[:status].should == Memcached::Errors::NO_ERROR
|
120
|
+
@counted += 1
|
121
|
+
stop if @counted >= $n
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
run do
|
127
|
+
$n.times { count }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should have counted up to #{$n}" do
|
132
|
+
run do
|
133
|
+
Memcached.get(:key => 'counter') do |result|
|
134
|
+
result[:status].should == Memcached::Errors::NO_ERROR
|
135
|
+
result[:value].to_i.should == $n
|
136
|
+
stop
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
24
143
|
context "when using multiple servers" do
|
25
144
|
it "should not return the same hash for the succeeding key" do
|
26
145
|
run do
|
@@ -56,4 +175,81 @@ describe Memcached::Client do
|
|
56
175
|
end
|
57
176
|
end
|
58
177
|
|
178
|
+
context "when manipulating multiple records at once" do
|
179
|
+
before :all do
|
180
|
+
@n = 10
|
181
|
+
end
|
182
|
+
|
183
|
+
def key(n)
|
184
|
+
"test:item:#{n}"
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should add some items" do
|
188
|
+
run do
|
189
|
+
items = []
|
190
|
+
@n.times { |i|
|
191
|
+
items << { :key => key(i),
|
192
|
+
:value => 'Foo',
|
193
|
+
:expiration => 20 } if i % 2 == 0
|
194
|
+
}
|
195
|
+
Memcached.multi_add(items) { |responses|
|
196
|
+
stop
|
197
|
+
@n.times { |i|
|
198
|
+
if i % 2 == 0 && (response_i = responses[key(i)])
|
199
|
+
response_i[:status].should == Memcached::Errors::NO_ERROR
|
200
|
+
end
|
201
|
+
}
|
202
|
+
}
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should get all items" do
|
207
|
+
run do
|
208
|
+
items = []
|
209
|
+
@n.times { |i|
|
210
|
+
items << { :key => key(i) }
|
211
|
+
}
|
212
|
+
Memcached.multi_get(items) { |responses|
|
213
|
+
stop
|
214
|
+
@n.times { |i|
|
215
|
+
if i % 2 == 0
|
216
|
+
responses.should have_key(key(i))
|
217
|
+
responses[key(i)][:status].should == Memcached::Errors::NO_ERROR
|
218
|
+
responses[key(i)][:value].should == 'Foo'
|
219
|
+
else
|
220
|
+
# either no response because request was quiet, or not
|
221
|
+
# found in case of last response
|
222
|
+
if (response_i = responses[key(i)])
|
223
|
+
response_i[:status].should == Memcached::Errors::KEY_NOT_FOUND
|
224
|
+
end
|
225
|
+
end
|
226
|
+
}
|
227
|
+
}
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should delete all items" do
|
232
|
+
run do
|
233
|
+
items = []
|
234
|
+
@n.times { |i|
|
235
|
+
items << { :key => key(i) }
|
236
|
+
}
|
237
|
+
Memcached.multi_delete(items) { |responses|
|
238
|
+
stop
|
239
|
+
@n.times { |i|
|
240
|
+
if i % 2 == 0
|
241
|
+
# either no response because request was quiet, or ok in
|
242
|
+
# case of last response
|
243
|
+
if (response_i = responses[key(i)])
|
244
|
+
response_i[:status].should == Memcached::Errors::NO_ERROR
|
245
|
+
end
|
246
|
+
else
|
247
|
+
responses[key(i)][:status].should == Memcached::Errors::KEY_NOT_FOUND
|
248
|
+
end
|
249
|
+
}
|
250
|
+
}
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
59
255
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: astro-remcached
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephan Maka
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-17 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -62,6 +62,6 @@ signing_key:
|
|
62
62
|
specification_version: 3
|
63
63
|
summary: Ruby EventMachine memcached client
|
64
64
|
test_files:
|
65
|
+
- spec/packet_spec.rb
|
65
66
|
- spec/client_spec.rb
|
66
67
|
- spec/memcached_spec.rb
|
67
|
-
- spec/packet_spec.rb
|