redis 1.0.7 → 2.0.0.rc1

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.
@@ -1,115 +1,436 @@
1
- require 'redis/hash_ring'
1
+ require "redis/hash_ring"
2
2
 
3
3
  class Redis
4
4
  class Distributed
5
+
6
+ class CannotDistribute < RuntimeError
7
+ def initialize(command)
8
+ @command = command
9
+ end
10
+
11
+ def message
12
+ "#{@command.to_s.upcase} cannot be used in Redis::Distributed because the keys involved need to be on the same server or because we cannot guarantee that the operation will be atomic."
13
+ end
14
+ end
15
+
5
16
  attr_reader :ring
6
- def initialize(opts={})
7
- hosts = []
8
17
 
9
- db = opts[:db] || nil
10
- timeout = opts[:timeout] || nil
18
+ def initialize(urls, options = {})
19
+ @default_options = options
20
+ @ring = HashRing.new urls.map { |url| Redis.connect(options.merge(:url => url)) }
21
+ end
11
22
 
12
- raise "No hosts given" unless opts[:hosts]
23
+ def node_for(key)
24
+ @ring.get_node(key.to_s)
25
+ end
13
26
 
14
- opts[:hosts].each do |h|
15
- host, port = h.split(':')
16
- hosts << Client.new(:host => host, :port => port, :db => db, :timeout => timeout)
17
- end
27
+ def nodes
28
+ @ring.nodes
29
+ end
30
+
31
+ def add_node(url)
32
+ @ring.add_node Redis.connect(@default_options.merge(:url => url))
33
+ end
34
+
35
+ def quit
36
+ on_each_node :quit
37
+ rescue Errno::ECONNRESET
38
+ end
39
+
40
+ def select(db)
41
+ on_each_node :select, db
42
+ end
43
+
44
+ def ping
45
+ on_each_node :ping
46
+ end
47
+
48
+ def quit
49
+ on_each_node :quit
50
+ end
51
+
52
+ def flushall
53
+ on_each_node :flushall
54
+ end
55
+
56
+ def exists(key)
57
+ node_for(key).exists(key)
58
+ end
59
+
60
+ def del(*keys)
61
+ on_each_node(:del, *keys)
62
+ end
63
+
64
+ def type(key)
65
+ node_for(key).type(key)
66
+ end
67
+
68
+ def keys(glob = "*")
69
+ on_each_node(:keys, glob).flatten
70
+ end
71
+
72
+ def randomkey
73
+ raise CannotDistribute, :randomkey
74
+ end
75
+
76
+ def rename(old_name, new_name)
77
+ raise CannotDistribute, :rename
78
+ end
79
+
80
+ def renamenx(old_name, new_name)
81
+ raise CannotDistribute, :renamenx
82
+ end
83
+
84
+ def dbsize
85
+ on_each_node :dbsize
86
+ end
87
+
88
+ def expire(key, seconds)
89
+ node_for(key).expire(key, seconds)
90
+ end
91
+
92
+ def expireat(key, unix_time)
93
+ node_for(key).expireat(key, unix_time)
94
+ end
95
+
96
+ def ttl(key)
97
+ node_for(key).ttl(key)
98
+ end
99
+
100
+ def move(key, db)
101
+ node_for(key).move(key, db)
102
+ end
103
+
104
+ def flushdb
105
+ on_each_node :flushdb
106
+ end
107
+
108
+ def set(key, value)
109
+ node_for(key).set(key, value)
110
+ end
111
+
112
+ def setex(key, ttl, value)
113
+ node_for(key).setex(key, ttl, value)
114
+ end
115
+
116
+ def get(key)
117
+ node_for(key).get(key)
118
+ end
119
+
120
+ def getset(key, value)
121
+ node_for(key).getset(key, value)
122
+ end
123
+
124
+ def [](key)
125
+ get(key)
126
+ end
127
+
128
+ def []=(key,value)
129
+ set(key, value)
130
+ end
131
+
132
+ def mget(*keys)
133
+ raise CannotDistribute, :mget
134
+ end
135
+
136
+ def mapped_mget(*keys)
137
+ raise CannotDistribute, :mapped_mget
138
+ end
139
+
140
+ def setnx(key, value)
141
+ node_for(key).setnx(key, value)
142
+ end
143
+
144
+ def mset(*args)
145
+ raise CannotDistribute, :mset
146
+ end
147
+
148
+ def mapped_mset(hash)
149
+ mset(*hash.to_a.flatten)
150
+ end
151
+
152
+ def msetnx(*args)
153
+ raise CannotDistribute, :msetnx
154
+ end
155
+
156
+ def mapped_msetnx(hash)
157
+ raise CannotDistribute, :mapped_msetnx
158
+ end
159
+
160
+ def incr(key)
161
+ node_for(key).incr(key)
162
+ end
163
+
164
+ def incrby(key, increment)
165
+ node_for(key).incrby(key, increment)
166
+ end
167
+
168
+ def decr(key)
169
+ node_for(key).decr(key)
170
+ end
171
+
172
+ def decrby(key, decrement)
173
+ node_for(key).decrby(key, decrement)
174
+ end
175
+
176
+ def rpush(key, value)
177
+ node_for(key).rpush(key, value)
178
+ end
179
+
180
+ def lpush(key, value)
181
+ node_for(key).lpush(key, value)
182
+ end
183
+
184
+ def llen(key)
185
+ node_for(key).llen(key)
186
+ end
187
+
188
+ def lrange(key, start, stop)
189
+ node_for(key).lrange(key, start, stop)
190
+ end
191
+
192
+ def ltrim(key, start, stop)
193
+ node_for(key).ltrim(key, start, stop)
194
+ end
18
195
 
19
- @ring = HashRing.new hosts
196
+ def lindex(key, index)
197
+ node_for(key).lindex(key, index)
20
198
  end
21
199
 
22
- def node_for_key(key)
23
- key = $1 if key =~ /\{(.*)?\}/
24
- @ring.get_node(key)
200
+ def lset(key, index, value)
201
+ node_for(key).lset(key, index, value)
25
202
  end
26
203
 
27
- def add_server(server)
28
- server, port = server.split(':')
29
- @ring.add_node Client.new(:host => server, :port => port)
204
+ def lrem(key, count, value)
205
+ node_for(key).lrem(key, count, value)
30
206
  end
31
207
 
32
- def method_missing(sym, *args, &blk)
33
- if redis = node_for_key(args.first.to_s)
34
- redis.send sym, *args, &blk
208
+ def lpop(key)
209
+ node_for(key).lpop(key)
210
+ end
211
+
212
+ def rpop(key)
213
+ node_for(key).rpop(key)
214
+ end
215
+
216
+ def rpoplpush(source, destination)
217
+ raise CannotDistribute, :rpoplpush
218
+ end
219
+
220
+ def blpop(key, timeout)
221
+ node_for(key).blpop(key, timeout)
222
+ end
223
+
224
+ def brpop(key, timeout)
225
+ node_for(key).brpop(key, timeout)
226
+ end
227
+
228
+ def sadd(key, value)
229
+ node_for(key).sadd(key, value)
230
+ end
231
+
232
+ def srem(key, value)
233
+ node_for(key).srem(key, value)
234
+ end
235
+
236
+ def spop(key)
237
+ node_for(key).spop(key)
238
+ end
239
+
240
+ def smove(source, destination, member)
241
+ raise CannotDistribute, :smove
242
+ end
243
+
244
+ def scard(key)
245
+ node_for(key).scard(key)
246
+ end
247
+
248
+ def sismember(key, member)
249
+ node_for(key).sismember(key, member)
250
+ end
251
+
252
+ def sinter(*keys)
253
+ raise CannotDistribute, :sinter
254
+ end
255
+
256
+ def sinterstore(destination, *keys)
257
+ raise CannotDistribute, :sinterstore
258
+ end
259
+
260
+ def sunion(*keys)
261
+ raise CannotDistribute, :sunion
262
+ end
263
+
264
+ def sunionstore(*keys)
265
+ raise CannotDistribute, :sunionstore
266
+ end
267
+
268
+ def sdiff(*keys)
269
+ raise CannotDistribute, :sdiff
270
+ end
271
+
272
+ def sdiffstore(*keys)
273
+ raise CannotDistribute, :sdiffstore
274
+ end
275
+
276
+ def smembers(key)
277
+ node_for(key).smembers(key)
278
+ end
279
+
280
+ def srandmember(key)
281
+ node_for(key).srandmember(key)
282
+ end
283
+
284
+ def zadd(key, score, member)
285
+ node_for(key).zadd(key, score, member)
286
+ end
287
+
288
+ def zrem(key, member)
289
+ node_for(key).zrem(key, member)
290
+ end
291
+
292
+ def zincrby(key, increment, member)
293
+ node_for(key).zincrby(key, increment, member)
294
+ end
295
+
296
+ def zrange(key, start, stop, with_scores = false)
297
+ if with_scores
298
+ node_for(key).zrange(key, start, stop, "WITHSCORES")
35
299
  else
36
- super
300
+ node_for(key).zrange(key, start, stop)
37
301
  end
38
302
  end
39
303
 
40
- def node_keys(glob)
41
- @ring.nodes.map do |red|
42
- red.keys(glob)
304
+ def zrevrange(key, start, stop, with_scores = false)
305
+ if with_scores
306
+ node_for(key).zrevrange(key, start, stop, "WITHSCORES")
307
+ else
308
+ node_for(key).zrevrange(key, start, stop)
43
309
  end
44
310
  end
45
311
 
46
- def keys(glob)
47
- node_keys(glob).flatten
312
+ def zrangebyscore(key, min, max)
313
+ node_for(key).zrangebyscore(key, min, max)
48
314
  end
49
315
 
50
- def save
51
- on_each_node :save
316
+ def zcard(key)
317
+ node_for(key).zcard(key)
52
318
  end
53
319
 
54
- def bgsave
55
- on_each_node :bgsave
320
+ def zscore(key, member)
321
+ node_for(key).zscore(key, member)
56
322
  end
57
323
 
58
- def quit
59
- on_each_node :quit
324
+ def hset(key, field, value)
325
+ node_for(key).hset(key, field, value)
60
326
  end
61
327
 
62
- def flush_all
63
- on_each_node :flush_all
328
+ def hget(key, field)
329
+ node_for(key).hget(key, field)
64
330
  end
65
- alias_method :flushall, :flush_all
66
331
 
67
- def flush_db
68
- on_each_node :flush_db
332
+ def hdel(key, field)
333
+ node_for(key).hdel(key, field)
69
334
  end
70
- alias_method :flushdb, :flush_db
71
335
 
72
- def delete_cloud!
73
- @ring.nodes.each do |red|
74
- red.keys("*").each do |key|
75
- red.del key
76
- end
77
- end
336
+ def hexists(key, field)
337
+ node_for(key).hexists(key, field)
78
338
  end
79
339
 
80
- def on_each_node(command, *args)
81
- @ring.nodes.each do |red|
82
- red.send(command, *args)
83
- end
340
+ def hlen(key)
341
+ node_for(key).hlen(key)
342
+ end
343
+
344
+ def hkeys(key)
345
+ node_for(key).hkeys(key)
84
346
  end
85
347
 
86
- def mset()
348
+ def hvals(key)
349
+ node_for(key).hvals(key)
350
+ end
87
351
 
352
+ def hgetall(key)
353
+ node_for(key).hgetall(key)
88
354
  end
89
355
 
90
- def mget(*keyz)
91
- results = {}
92
- kbn = keys_by_node(keyz)
93
- kbn.each do |node, node_keyz|
94
- node.mapped_mget(*node_keyz).each do |k, v|
95
- results[k] = v
96
- end
97
- end
98
- keyz.flatten.map { |k| results[k] }
356
+ def hmset(key, *attrs)
357
+ node_for(key).hmset(key, *attrs)
358
+ end
359
+
360
+ def sort(key, options = {})
361
+ raise CannotDistribute, :sort
362
+ end
363
+
364
+ def multi(&block)
365
+ raise CannotDistribute, :multi
366
+ end
367
+
368
+ def exec
369
+ raise CannotDistribute, :exec
370
+ end
371
+
372
+ def discard
373
+ raise CannotDistribute, :discard
374
+ end
375
+
376
+ def publish(channel, message)
377
+ raise NotImplementedError
378
+ end
379
+
380
+ def unsubscribe(*channels)
381
+ raise NotImplementedError
382
+ end
383
+
384
+ def subscribe(*channels, &block)
385
+ raise NotImplementedError
386
+ end
387
+
388
+ def punsubscribe(*channels)
389
+ raise NotImplementedError
390
+ end
391
+
392
+ def psubscribe(*channels, &block)
393
+ raise NotImplementedError
394
+ end
395
+
396
+ def save
397
+ on_each_node :save
398
+ end
399
+
400
+ def bgsave
401
+ on_each_node :bgsave
402
+ end
403
+
404
+ def lastsave
405
+ on_each_node :lastsave
406
+ end
407
+
408
+ def info
409
+ on_each_node :info
410
+ end
411
+
412
+ def monitor
413
+ raise NotImplementedError
414
+ end
415
+
416
+ def echo(value)
417
+ on_each_node :echo, value
418
+ end
419
+
420
+ def pipelined
421
+ raise CannotDistribute, :pipelined
99
422
  end
100
423
 
101
- def keys_by_node(*keyz)
102
- keyz.flatten.inject({}) do |kbn, k|
103
- node = node_for_key(k)
104
- next if kbn[node] && kbn[node].include?(k)
105
- kbn[node] ||= []
106
- kbn[node] << k
107
- kbn
424
+ protected
425
+
426
+ def on_each_node(command, *args)
427
+ nodes.map do |node|
428
+ node.send(command, *args)
108
429
  end
109
430
  end
110
431
 
111
- def type(key)
112
- method_missing(:type, key)
432
+ def node_index_for(key)
433
+ nodes.index(node_for(key))
113
434
  end
114
435
  end
115
436
  end