redis 3.2.0 → 4.6.0
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +278 -15
- data/README.md +260 -76
- data/lib/redis/client.rb +239 -115
- data/lib/redis/cluster/command.rb +79 -0
- data/lib/redis/cluster/command_loader.rb +33 -0
- data/lib/redis/cluster/key_slot_converter.rb +72 -0
- data/lib/redis/cluster/node.rb +120 -0
- data/lib/redis/cluster/node_key.rb +31 -0
- data/lib/redis/cluster/node_loader.rb +37 -0
- data/lib/redis/cluster/option.rb +93 -0
- data/lib/redis/cluster/slot.rb +86 -0
- data/lib/redis/cluster/slot_loader.rb +49 -0
- data/lib/redis/cluster.rb +315 -0
- data/lib/redis/commands/bitmaps.rb +63 -0
- data/lib/redis/commands/cluster.rb +45 -0
- data/lib/redis/commands/connection.rb +58 -0
- data/lib/redis/commands/geo.rb +84 -0
- data/lib/redis/commands/hashes.rb +251 -0
- data/lib/redis/commands/hyper_log_log.rb +37 -0
- data/lib/redis/commands/keys.rb +411 -0
- data/lib/redis/commands/lists.rb +289 -0
- data/lib/redis/commands/pubsub.rb +72 -0
- data/lib/redis/commands/scripting.rb +114 -0
- data/lib/redis/commands/server.rb +188 -0
- data/lib/redis/commands/sets.rb +207 -0
- data/lib/redis/commands/sorted_sets.rb +804 -0
- data/lib/redis/commands/streams.rb +382 -0
- data/lib/redis/commands/strings.rb +313 -0
- data/lib/redis/commands/transactions.rb +92 -0
- data/lib/redis/commands.rb +242 -0
- data/lib/redis/connection/command_helper.rb +7 -10
- data/lib/redis/connection/hiredis.rb +11 -6
- data/lib/redis/connection/registry.rb +2 -1
- data/lib/redis/connection/ruby.rb +173 -64
- data/lib/redis/connection/synchrony.rb +32 -8
- data/lib/redis/connection.rb +3 -1
- data/lib/redis/distributed.rb +233 -74
- data/lib/redis/errors.rb +48 -0
- data/lib/redis/hash_ring.rb +30 -72
- data/lib/redis/pipeline.rb +145 -12
- data/lib/redis/subscribe.rb +20 -13
- data/lib/redis/version.rb +3 -1
- data/lib/redis.rb +171 -2476
- metadata +71 -165
- data/.gitignore +0 -15
- data/.travis/Gemfile +0 -11
- data/.travis.yml +0 -54
- data/.yardopts +0 -3
- data/Gemfile +0 -4
- data/Rakefile +0 -68
- data/benchmarking/logging.rb +0 -71
- data/benchmarking/pipeline.rb +0 -51
- data/benchmarking/speed.rb +0 -21
- data/benchmarking/suite.rb +0 -24
- data/benchmarking/worker.rb +0 -71
- data/examples/basic.rb +0 -15
- data/examples/consistency.rb +0 -114
- data/examples/dist_redis.rb +0 -43
- data/examples/incr-decr.rb +0 -17
- data/examples/list.rb +0 -26
- data/examples/pubsub.rb +0 -37
- data/examples/sentinel/sentinel.conf +0 -9
- data/examples/sentinel/start +0 -49
- data/examples/sentinel.rb +0 -41
- data/examples/sets.rb +0 -36
- data/examples/unicorn/config.ru +0 -3
- data/examples/unicorn/unicorn.rb +0 -20
- data/redis.gemspec +0 -43
- data/test/bitpos_test.rb +0 -69
- data/test/blocking_commands_test.rb +0 -42
- data/test/command_map_test.rb +0 -30
- data/test/commands_on_hashes_test.rb +0 -21
- data/test/commands_on_hyper_log_log_test.rb +0 -21
- data/test/commands_on_lists_test.rb +0 -20
- data/test/commands_on_sets_test.rb +0 -77
- data/test/commands_on_sorted_sets_test.rb +0 -123
- data/test/commands_on_strings_test.rb +0 -101
- data/test/commands_on_value_types_test.rb +0 -131
- data/test/connection_handling_test.rb +0 -189
- data/test/db/.gitkeep +0 -0
- data/test/distributed_blocking_commands_test.rb +0 -46
- data/test/distributed_commands_on_hashes_test.rb +0 -10
- data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
- data/test/distributed_commands_on_lists_test.rb +0 -22
- data/test/distributed_commands_on_sets_test.rb +0 -83
- data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
- data/test/distributed_commands_on_strings_test.rb +0 -59
- data/test/distributed_commands_on_value_types_test.rb +0 -95
- data/test/distributed_commands_requiring_clustering_test.rb +0 -164
- data/test/distributed_connection_handling_test.rb +0 -23
- data/test/distributed_internals_test.rb +0 -70
- data/test/distributed_key_tags_test.rb +0 -52
- data/test/distributed_persistence_control_commands_test.rb +0 -26
- data/test/distributed_publish_subscribe_test.rb +0 -92
- data/test/distributed_remote_server_control_commands_test.rb +0 -66
- data/test/distributed_scripting_test.rb +0 -102
- data/test/distributed_sorting_test.rb +0 -20
- data/test/distributed_test.rb +0 -58
- data/test/distributed_transactions_test.rb +0 -32
- data/test/encoding_test.rb +0 -18
- data/test/error_replies_test.rb +0 -59
- data/test/fork_safety_test.rb +0 -65
- data/test/helper.rb +0 -232
- data/test/helper_test.rb +0 -24
- data/test/internals_test.rb +0 -434
- data/test/lint/blocking_commands.rb +0 -150
- data/test/lint/hashes.rb +0 -162
- data/test/lint/hyper_log_log.rb +0 -60
- data/test/lint/lists.rb +0 -143
- data/test/lint/sets.rb +0 -125
- data/test/lint/sorted_sets.rb +0 -238
- data/test/lint/strings.rb +0 -260
- data/test/lint/value_types.rb +0 -122
- data/test/persistence_control_commands_test.rb +0 -26
- data/test/pipelining_commands_test.rb +0 -242
- data/test/publish_subscribe_test.rb +0 -210
- data/test/remote_server_control_commands_test.rb +0 -117
- data/test/scanning_test.rb +0 -413
- data/test/scripting_test.rb +0 -78
- data/test/sorting_test.rb +0 -59
- data/test/support/connection/hiredis.rb +0 -1
- data/test/support/connection/ruby.rb +0 -1
- data/test/support/connection/synchrony.rb +0 -17
- data/test/support/redis_mock.rb +0 -115
- data/test/support/wire/synchrony.rb +0 -24
- data/test/support/wire/thread.rb +0 -5
- data/test/synchrony_driver.rb +0 -88
- data/test/test.conf +0 -9
- data/test/thread_safety_test.rb +0 -32
- data/test/transactions_test.rb +0 -264
- data/test/unknown_commands_test.rb +0 -14
- data/test/url_param_test.rb +0 -132
data/examples/basic.rb
DELETED
data/examples/consistency.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
# This file implements a simple consistency test for Redis-rb (or any other
|
2
|
-
# Redis environment if you pass a different client object) where a client
|
3
|
-
# writes to the database using INCR in order to increment keys, but actively
|
4
|
-
# remember the value the key should have. Before every write a read is performed
|
5
|
-
# to check if the value in the database matches the value expected.
|
6
|
-
#
|
7
|
-
# In this way this program can check for lost writes, or acknowledged writes
|
8
|
-
# that were executed.
|
9
|
-
#
|
10
|
-
# Copyright (C) 2013-2014 Salvatore Sanfilippo <antirez@gmail.com>
|
11
|
-
#
|
12
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
13
|
-
# a copy of this software and associated documentation files (the
|
14
|
-
# "Software"), to deal in the Software without restriction, including
|
15
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
16
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
17
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
18
|
-
# the following conditions:
|
19
|
-
#
|
20
|
-
# The above copyright notice and this permission notice shall be
|
21
|
-
# included in all copies or substantial portions of the Software.
|
22
|
-
#
|
23
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
24
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
25
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
26
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
27
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
28
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
29
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
30
|
-
|
31
|
-
require 'redis'
|
32
|
-
|
33
|
-
class ConsistencyTester
|
34
|
-
def initialize(redis)
|
35
|
-
@r = redis
|
36
|
-
@working_set = 10000
|
37
|
-
@keyspace = 100000
|
38
|
-
@writes = 0
|
39
|
-
@reads = 0
|
40
|
-
@failed_writes = 0
|
41
|
-
@failed_reads = 0
|
42
|
-
@lost_writes = 0
|
43
|
-
@not_ack_writes = 0
|
44
|
-
@delay = 0
|
45
|
-
@cached = {} # We take our view of data stored in the DB.
|
46
|
-
@prefix = [Process.pid.to_s,Time.now.usec,@r.object_id,""].join("|")
|
47
|
-
@errtime = {}
|
48
|
-
end
|
49
|
-
|
50
|
-
def genkey
|
51
|
-
# Write more often to a small subset of keys
|
52
|
-
ks = rand() > 0.5 ? @keyspace : @working_set
|
53
|
-
@prefix+"key_"+rand(ks).to_s
|
54
|
-
end
|
55
|
-
|
56
|
-
def check_consistency(key,value)
|
57
|
-
expected = @cached[key]
|
58
|
-
return if !expected # We lack info about previous state.
|
59
|
-
if expected > value
|
60
|
-
@lost_writes += expected-value
|
61
|
-
elsif expected < value
|
62
|
-
@not_ack_writes += value-expected
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def puterr(msg)
|
67
|
-
if !@errtime[msg] || Time.now.to_i != @errtime[msg]
|
68
|
-
puts msg
|
69
|
-
end
|
70
|
-
@errtime[msg] = Time.now.to_i
|
71
|
-
end
|
72
|
-
|
73
|
-
def test
|
74
|
-
last_report = Time.now.to_i
|
75
|
-
while true
|
76
|
-
# Read
|
77
|
-
key = genkey
|
78
|
-
begin
|
79
|
-
val = @r.get(key)
|
80
|
-
check_consistency(key,val.to_i)
|
81
|
-
@reads += 1
|
82
|
-
rescue => e
|
83
|
-
puterr "Reading: #{e.class}: #{e.message} (#{e.backtrace.first})"
|
84
|
-
@failed_reads += 1
|
85
|
-
end
|
86
|
-
|
87
|
-
# Write
|
88
|
-
begin
|
89
|
-
@cached[key] = @r.incr(key).to_i
|
90
|
-
@writes += 1
|
91
|
-
rescue => e
|
92
|
-
puterr "Writing: #{e.class}: #{e.message} (#{e.backtrace.first})"
|
93
|
-
@failed_writes += 1
|
94
|
-
end
|
95
|
-
|
96
|
-
# Report
|
97
|
-
sleep @delay
|
98
|
-
if Time.now.to_i != last_report
|
99
|
-
report = "#{@reads} R (#{@failed_reads} err) | " +
|
100
|
-
"#{@writes} W (#{@failed_writes} err) | "
|
101
|
-
report += "#{@lost_writes} lost | " if @lost_writes > 0
|
102
|
-
report += "#{@not_ack_writes} noack | " if @not_ack_writes > 0
|
103
|
-
last_report = Time.now.to_i
|
104
|
-
puts report
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
Sentinels = [{:host => "127.0.0.1", :port => 26379},
|
111
|
-
{:host => "127.0.0.1", :port => 26380}]
|
112
|
-
r = Redis.new(:url => "redis://master1", :sentinels => Sentinels, :role => :master)
|
113
|
-
tester = ConsistencyTester.new(r)
|
114
|
-
tester.test
|
data/examples/dist_redis.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require "redis"
|
2
|
-
require "redis/distributed"
|
3
|
-
|
4
|
-
r = Redis::Distributed.new %w[redis://localhost:6379 redis://localhost:6380 redis://localhost:6381 redis://localhost:6382]
|
5
|
-
|
6
|
-
r.flushdb
|
7
|
-
|
8
|
-
r['urmom'] = 'urmom'
|
9
|
-
r['urdad'] = 'urdad'
|
10
|
-
r['urmom1'] = 'urmom1'
|
11
|
-
r['urdad1'] = 'urdad1'
|
12
|
-
r['urmom2'] = 'urmom2'
|
13
|
-
r['urdad2'] = 'urdad2'
|
14
|
-
r['urmom3'] = 'urmom3'
|
15
|
-
r['urdad3'] = 'urdad3'
|
16
|
-
p r['urmom']
|
17
|
-
p r['urdad']
|
18
|
-
p r['urmom1']
|
19
|
-
p r['urdad1']
|
20
|
-
p r['urmom2']
|
21
|
-
p r['urdad2']
|
22
|
-
p r['urmom3']
|
23
|
-
p r['urdad3']
|
24
|
-
|
25
|
-
r.rpush 'listor', 'foo1'
|
26
|
-
r.rpush 'listor', 'foo2'
|
27
|
-
r.rpush 'listor', 'foo3'
|
28
|
-
r.rpush 'listor', 'foo4'
|
29
|
-
r.rpush 'listor', 'foo5'
|
30
|
-
|
31
|
-
p r.rpop('listor')
|
32
|
-
p r.rpop('listor')
|
33
|
-
p r.rpop('listor')
|
34
|
-
p r.rpop('listor')
|
35
|
-
p r.rpop('listor')
|
36
|
-
|
37
|
-
puts "key distribution:"
|
38
|
-
|
39
|
-
r.ring.nodes.each do |node|
|
40
|
-
p [node.client, node.keys("*")]
|
41
|
-
end
|
42
|
-
r.flushdb
|
43
|
-
p r.keys('*')
|
data/examples/incr-decr.rb
DELETED
data/examples/list.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'redis'
|
3
|
-
|
4
|
-
r = Redis.new
|
5
|
-
|
6
|
-
r.del 'logs'
|
7
|
-
|
8
|
-
puts
|
9
|
-
|
10
|
-
p "pushing log messages into a LIST"
|
11
|
-
r.rpush 'logs', 'some log message'
|
12
|
-
r.rpush 'logs', 'another log message'
|
13
|
-
r.rpush 'logs', 'yet another log message'
|
14
|
-
r.rpush 'logs', 'also another log message'
|
15
|
-
|
16
|
-
puts
|
17
|
-
p 'contents of logs LIST'
|
18
|
-
|
19
|
-
p r.lrange('logs', 0, -1)
|
20
|
-
|
21
|
-
puts
|
22
|
-
p 'Trim logs LIST to last 2 elements(easy circular buffer)'
|
23
|
-
|
24
|
-
r.ltrim('logs', -2, -1)
|
25
|
-
|
26
|
-
p r.lrange('logs', 0, -1)
|
data/examples/pubsub.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require "redis"
|
2
|
-
|
3
|
-
puts <<-EOS
|
4
|
-
To play with this example use redis-cli from another terminal, like this:
|
5
|
-
|
6
|
-
$ redis-cli publish one hello
|
7
|
-
|
8
|
-
Finally force the example to exit sending the 'exit' message with:
|
9
|
-
|
10
|
-
$ redis-cli publish two exit
|
11
|
-
|
12
|
-
EOS
|
13
|
-
|
14
|
-
redis = Redis.new
|
15
|
-
|
16
|
-
trap(:INT) { puts; exit }
|
17
|
-
|
18
|
-
begin
|
19
|
-
redis.subscribe(:one, :two) do |on|
|
20
|
-
on.subscribe do |channel, subscriptions|
|
21
|
-
puts "Subscribed to ##{channel} (#{subscriptions} subscriptions)"
|
22
|
-
end
|
23
|
-
|
24
|
-
on.message do |channel, message|
|
25
|
-
puts "##{channel}: #{message}"
|
26
|
-
redis.unsubscribe if message == "exit"
|
27
|
-
end
|
28
|
-
|
29
|
-
on.unsubscribe do |channel, subscriptions|
|
30
|
-
puts "Unsubscribed from ##{channel} (#{subscriptions} subscriptions)"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
rescue Redis::BaseConnectionError => error
|
34
|
-
puts "#{error}, retrying in 1s"
|
35
|
-
sleep 1
|
36
|
-
retry
|
37
|
-
end
|
@@ -1,9 +0,0 @@
|
|
1
|
-
sentinel monitor master1 127.0.0.1 6380 2
|
2
|
-
sentinel down-after-milliseconds master1 5000
|
3
|
-
sentinel failover-timeout master1 15000
|
4
|
-
sentinel parallel-syncs master1 1
|
5
|
-
|
6
|
-
sentinel monitor master2 127.0.0.1 6381 2
|
7
|
-
sentinel down-after-milliseconds master2 5000
|
8
|
-
sentinel failover-timeout master2 15000
|
9
|
-
sentinel parallel-syncs master2 1
|
data/examples/sentinel/start
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
|
-
|
3
|
-
# This is a helper script used together with examples/sentinel.rb
|
4
|
-
# It runs two Redis masters, two slaves for each of them, and two sentinels.
|
5
|
-
# After 30 seconds, the first master dies.
|
6
|
-
#
|
7
|
-
# You don't need to run this script yourself. Rather, use examples/sentinel.rb.
|
8
|
-
|
9
|
-
require "fileutils"
|
10
|
-
|
11
|
-
$pids = []
|
12
|
-
|
13
|
-
at_exit do
|
14
|
-
$pids.each do |pid|
|
15
|
-
begin
|
16
|
-
Process.kill(:INT, pid)
|
17
|
-
rescue Errno::ESRCH
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
Process.waitall
|
22
|
-
end
|
23
|
-
|
24
|
-
base = File.expand_path(File.dirname(__FILE__))
|
25
|
-
|
26
|
-
# Masters
|
27
|
-
$pids << spawn("redis-server --port 6380 --loglevel warning")
|
28
|
-
$pids << spawn("redis-server --port 6381 --loglevel warning")
|
29
|
-
|
30
|
-
# Slaves of Master 1
|
31
|
-
$pids << spawn("redis-server --port 63800 --slaveof 127.0.0.1 6380 --loglevel warning")
|
32
|
-
$pids << spawn("redis-server --port 63801 --slaveof 127.0.0.1 6380 --loglevel warning")
|
33
|
-
|
34
|
-
# Slaves of Master 2
|
35
|
-
$pids << spawn("redis-server --port 63810 --slaveof 127.0.0.1 6381 --loglevel warning")
|
36
|
-
$pids << spawn("redis-server --port 63811 --slaveof 127.0.0.1 6381 --loglevel warning")
|
37
|
-
|
38
|
-
FileUtils.cp(File.join(base, "sentinel.conf"), "tmp/sentinel1.conf")
|
39
|
-
FileUtils.cp(File.join(base, "sentinel.conf"), "tmp/sentinel2.conf")
|
40
|
-
|
41
|
-
# Sentinels
|
42
|
-
$pids << spawn("redis-server tmp/sentinel1.conf --sentinel --port 26379")
|
43
|
-
$pids << spawn("redis-server tmp/sentinel2.conf --sentinel --port 26380")
|
44
|
-
|
45
|
-
sleep 30
|
46
|
-
|
47
|
-
Process.kill(:KILL, $pids[0])
|
48
|
-
|
49
|
-
Process.waitall
|
data/examples/sentinel.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'redis'
|
2
|
-
|
3
|
-
# This example creates a master-slave setup with a sentinel, then connects to
|
4
|
-
# it and sends write commands in a loop.
|
5
|
-
#
|
6
|
-
# After 30 seconds, the master dies. You will be able to see how a new master
|
7
|
-
# is elected and things continue to work as if nothing happened.
|
8
|
-
#
|
9
|
-
# To run this example:
|
10
|
-
#
|
11
|
-
# $ ruby -I./lib examples/sentinel.rb
|
12
|
-
#
|
13
|
-
|
14
|
-
at_exit do
|
15
|
-
begin
|
16
|
-
Process.kill(:INT, $redises)
|
17
|
-
rescue Errno::ESRCH
|
18
|
-
end
|
19
|
-
|
20
|
-
Process.waitall
|
21
|
-
end
|
22
|
-
|
23
|
-
$redises = spawn("examples/sentinel/start")
|
24
|
-
|
25
|
-
Sentinels = [{:host => "127.0.0.1", :port => 26379},
|
26
|
-
{:host => "127.0.0.1", :port => 26380}]
|
27
|
-
r = Redis.new(:url => "redis://master1", :sentinels => Sentinels, :role => :master)
|
28
|
-
|
29
|
-
# Set keys into a loop.
|
30
|
-
#
|
31
|
-
# The example traps errors so that you can actually try to failover while
|
32
|
-
# running the script to see redis-rb reconfiguring.
|
33
|
-
(0..1000000).each{|i|
|
34
|
-
begin
|
35
|
-
r.set(i,i)
|
36
|
-
$stdout.write("SET (#{i} times)\n") if i % 100 == 0
|
37
|
-
rescue => e
|
38
|
-
$stdout.write("E")
|
39
|
-
end
|
40
|
-
sleep(0.01)
|
41
|
-
}
|
data/examples/sets.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'redis'
|
3
|
-
|
4
|
-
r = Redis.new
|
5
|
-
|
6
|
-
r.del 'foo-tags'
|
7
|
-
r.del 'bar-tags'
|
8
|
-
|
9
|
-
puts
|
10
|
-
p "create a set of tags on foo-tags"
|
11
|
-
|
12
|
-
r.sadd 'foo-tags', 'one'
|
13
|
-
r.sadd 'foo-tags', 'two'
|
14
|
-
r.sadd 'foo-tags', 'three'
|
15
|
-
|
16
|
-
puts
|
17
|
-
p "create a set of tags on bar-tags"
|
18
|
-
|
19
|
-
r.sadd 'bar-tags', 'three'
|
20
|
-
r.sadd 'bar-tags', 'four'
|
21
|
-
r.sadd 'bar-tags', 'five'
|
22
|
-
|
23
|
-
puts
|
24
|
-
p 'foo-tags'
|
25
|
-
|
26
|
-
p r.smembers('foo-tags')
|
27
|
-
|
28
|
-
puts
|
29
|
-
p 'bar-tags'
|
30
|
-
|
31
|
-
p r.smembers('bar-tags')
|
32
|
-
|
33
|
-
puts
|
34
|
-
p 'intersection of foo-tags and bar-tags'
|
35
|
-
|
36
|
-
p r.sinter('foo-tags', 'bar-tags')
|
data/examples/unicorn/config.ru
DELETED
data/examples/unicorn/unicorn.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require "redis"
|
2
|
-
|
3
|
-
worker_processes 3
|
4
|
-
|
5
|
-
# If you set the connection to Redis *before* forking,
|
6
|
-
# you will cause forks to share a file descriptor.
|
7
|
-
#
|
8
|
-
# This causes a concurrency problem by which one fork
|
9
|
-
# can read or write to the socket while others are
|
10
|
-
# performing other operations.
|
11
|
-
#
|
12
|
-
# Most likely you'll be getting ProtocolError exceptions
|
13
|
-
# mentioning a wrong initial byte in the reply.
|
14
|
-
#
|
15
|
-
# Thus we need to connect to Redis after forking the
|
16
|
-
# worker processes.
|
17
|
-
|
18
|
-
after_fork do |server, worker|
|
19
|
-
Redis.current.quit
|
20
|
-
end
|
data/redis.gemspec
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
$:.unshift File.expand_path("../lib", __FILE__)
|
4
|
-
|
5
|
-
require "redis/version"
|
6
|
-
|
7
|
-
Gem::Specification.new do |s|
|
8
|
-
s.name = "redis"
|
9
|
-
|
10
|
-
s.version = Redis::VERSION
|
11
|
-
|
12
|
-
s.homepage = "https://github.com/redis/redis-rb"
|
13
|
-
|
14
|
-
s.summary = "A Ruby client library for Redis"
|
15
|
-
|
16
|
-
s.description = <<-EOS
|
17
|
-
A Ruby client that tries to match Redis' API one-to-one, while still
|
18
|
-
providing an idiomatic interface. It features thread-safety,
|
19
|
-
client-side sharding, pipelining, and an obsession for performance.
|
20
|
-
EOS
|
21
|
-
|
22
|
-
s.license = "MIT"
|
23
|
-
|
24
|
-
s.authors = [
|
25
|
-
"Ezra Zygmuntowicz",
|
26
|
-
"Taylor Weibley",
|
27
|
-
"Matthew Clark",
|
28
|
-
"Brian McKinney",
|
29
|
-
"Salvatore Sanfilippo",
|
30
|
-
"Luca Guidi",
|
31
|
-
"Michel Martens",
|
32
|
-
"Damian Janowski",
|
33
|
-
"Pieter Noordhuis"
|
34
|
-
]
|
35
|
-
|
36
|
-
s.email = ["redis-db@googlegroups.com"]
|
37
|
-
|
38
|
-
s.files = `git ls-files`.split("\n")
|
39
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
40
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
41
|
-
|
42
|
-
s.add_development_dependency("rake")
|
43
|
-
end
|
data/test/bitpos_test.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
unless defined?(Enumerator)
|
6
|
-
Enumerator = Enumerable::Enumerator
|
7
|
-
end
|
8
|
-
|
9
|
-
class TestBitpos < Test::Unit::TestCase
|
10
|
-
|
11
|
-
include Helper::Client
|
12
|
-
|
13
|
-
def test_bitpos_empty_zero
|
14
|
-
target_version "2.9.11" do
|
15
|
-
r.del "foo"
|
16
|
-
assert_equal 0, r.bitpos("foo", 0)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_bitpos_empty_one
|
21
|
-
target_version "2.9.11" do
|
22
|
-
r.del "foo"
|
23
|
-
assert_equal -1, r.bitpos("foo", 1)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_bitpos_zero
|
28
|
-
target_version "2.9.11" do
|
29
|
-
r.set "foo", "\xff\xf0\x00"
|
30
|
-
assert_equal 12, r.bitpos("foo", 0)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_bitpos_one
|
35
|
-
target_version "2.9.11" do
|
36
|
-
r.set "foo", "\x00\x0f\x00"
|
37
|
-
assert_equal 12, r.bitpos("foo", 1)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_bitpos_zero_end_is_given
|
42
|
-
target_version "2.9.11" do
|
43
|
-
r.set "foo", "\xff\xff\xff"
|
44
|
-
assert_equal 24, r.bitpos("foo", 0)
|
45
|
-
assert_equal 24, r.bitpos("foo", 0, 0)
|
46
|
-
assert_equal -1, r.bitpos("foo", 0, 0, -1)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_bitpos_one_intervals
|
51
|
-
target_version "2.9.11" do
|
52
|
-
r.set "foo", "\x00\xff\x00"
|
53
|
-
assert_equal 8, r.bitpos("foo", 1, 0, -1)
|
54
|
-
assert_equal 8, r.bitpos("foo", 1, 1, -1)
|
55
|
-
assert_equal -1, r.bitpos("foo", 1, 2, -1)
|
56
|
-
assert_equal -1, r.bitpos("foo", 1, 2, 200)
|
57
|
-
assert_equal 8, r.bitpos("foo", 1, 1, 1)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_bitpos_raise_exception_if_stop_not_start
|
62
|
-
target_version "2.9.11" do
|
63
|
-
assert_raises(ArgumentError) do
|
64
|
-
r.bitpos("foo", 0, nil, 2)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
require "lint/blocking_commands"
|
5
|
-
|
6
|
-
class TestBlockingCommands < Test::Unit::TestCase
|
7
|
-
|
8
|
-
include Helper::Client
|
9
|
-
include Lint::BlockingCommands
|
10
|
-
|
11
|
-
def assert_takes_longer_than_client_timeout
|
12
|
-
timeout = OPTIONS[:timeout]
|
13
|
-
delay = timeout * 2
|
14
|
-
|
15
|
-
mock(:delay => delay) do |r|
|
16
|
-
t1 = Time.now
|
17
|
-
yield(r)
|
18
|
-
t2 = Time.now
|
19
|
-
|
20
|
-
assert timeout == r.client.timeout
|
21
|
-
assert delay <= (t2 - t1)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_blpop_disable_client_timeout
|
26
|
-
assert_takes_longer_than_client_timeout do |r|
|
27
|
-
assert_equal ["foo", "0"], r.blpop("foo")
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_brpop_disable_client_timeout
|
32
|
-
assert_takes_longer_than_client_timeout do |r|
|
33
|
-
assert_equal ["foo", "0"], r.brpop("foo")
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_brpoplpush_disable_client_timeout
|
38
|
-
assert_takes_longer_than_client_timeout do |r|
|
39
|
-
assert_equal "0", r.brpoplpush("foo", "bar")
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/test/command_map_test.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
class TestCommandMap < Test::Unit::TestCase
|
6
|
-
|
7
|
-
include Helper::Client
|
8
|
-
|
9
|
-
def test_override_existing_commands
|
10
|
-
r.set("counter", 1)
|
11
|
-
|
12
|
-
assert_equal 2, r.incr("counter")
|
13
|
-
|
14
|
-
r.client.command_map[:incr] = :decr
|
15
|
-
|
16
|
-
assert_equal 1, r.incr("counter")
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_override_non_existing_commands
|
20
|
-
r.set("key", "value")
|
21
|
-
|
22
|
-
assert_raise Redis::CommandError do
|
23
|
-
r.idontexist("key")
|
24
|
-
end
|
25
|
-
|
26
|
-
r.client.command_map[:idontexist] = :get
|
27
|
-
|
28
|
-
assert_equal "value", r.idontexist("key")
|
29
|
-
end
|
30
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
require "lint/hashes"
|
5
|
-
|
6
|
-
class TestCommandsOnHashes < Test::Unit::TestCase
|
7
|
-
|
8
|
-
include Helper::Client
|
9
|
-
include Lint::Hashes
|
10
|
-
|
11
|
-
def test_mapped_hmget_in_a_pipeline_returns_hash
|
12
|
-
r.hset("foo", "f1", "s1")
|
13
|
-
r.hset("foo", "f2", "s2")
|
14
|
-
|
15
|
-
result = r.pipelined do
|
16
|
-
r.mapped_hmget("foo", "f1", "f2")
|
17
|
-
end
|
18
|
-
|
19
|
-
assert_equal result[0], { "f1" => "s1", "f2" => "s2" }
|
20
|
-
end
|
21
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
require "lint/hyper_log_log"
|
5
|
-
|
6
|
-
class TestCommandsOnHyperLogLog < Test::Unit::TestCase
|
7
|
-
|
8
|
-
include Helper::Client
|
9
|
-
include Lint::HyperLogLog
|
10
|
-
|
11
|
-
def test_pfmerge
|
12
|
-
target_version "2.8.9" do
|
13
|
-
r.pfadd "foo", "s1"
|
14
|
-
r.pfadd "bar", "s2"
|
15
|
-
|
16
|
-
assert_equal true, r.pfmerge("res", "foo", "bar")
|
17
|
-
assert_equal 2, r.pfcount("res")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
require "lint/lists"
|
5
|
-
|
6
|
-
class TestCommandsOnLists < Test::Unit::TestCase
|
7
|
-
|
8
|
-
include Helper::Client
|
9
|
-
include Lint::Lists
|
10
|
-
|
11
|
-
def test_rpoplpush
|
12
|
-
r.rpush "foo", "s1"
|
13
|
-
r.rpush "foo", "s2"
|
14
|
-
|
15
|
-
assert_equal "s2", r.rpoplpush("foo", "bar")
|
16
|
-
assert_equal ["s2"], r.lrange("bar", 0, -1)
|
17
|
-
assert_equal "s1", r.rpoplpush("foo", "bar")
|
18
|
-
assert_equal ["s1", "s2"], r.lrange("bar", 0, -1)
|
19
|
-
end
|
20
|
-
end
|