redis 1.0.7 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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