ruby-redis 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +9 -0
- data/README +90 -0
- data/bin/ruby-redis +12 -0
- data/bin/ruby-redis.compiled.rbc +243 -0
- data/lib/redis/bin.rb +74 -0
- data/lib/redis/bin.rbc +1325 -0
- data/lib/redis/buftok.rbc +2658 -0
- data/lib/redis/config.rb +46 -0
- data/lib/redis/config.rbc +1009 -0
- data/lib/redis/connection.rb +69 -0
- data/lib/redis/connection.rbc +1354 -0
- data/lib/redis/database.rb +109 -0
- data/lib/redis/database.rbc +2275 -0
- data/lib/redis/hashes.rb +72 -0
- data/lib/redis/hashes.rbc +1843 -0
- data/lib/redis/hiredis.rbc +658 -0
- data/lib/redis/keys.rb +165 -0
- data/lib/redis/keys.rbc +3386 -0
- data/lib/redis/lists.rb +227 -0
- data/lib/redis/lists.rbc +5241 -0
- data/lib/redis/logger.rb +81 -0
- data/lib/redis/logger.rbc +2106 -0
- data/lib/redis/protocol.rb +170 -0
- data/lib/redis/protocol.rbc +3735 -0
- data/lib/redis/pubsub.rb +153 -0
- data/lib/redis/pubsub.rbc +3447 -0
- data/lib/redis/reader.rb +164 -0
- data/lib/redis/reader.rbc +2769 -0
- data/lib/redis/send.rbc +1268 -0
- data/lib/redis/sender.rb +49 -0
- data/lib/redis/sender.rbc +1057 -0
- data/lib/redis/server.rb +62 -0
- data/lib/redis/server.rbc +1177 -0
- data/lib/redis/sets.rb +105 -0
- data/lib/redis/sets.rbc +2800 -0
- data/lib/redis/strict.rb +67 -0
- data/lib/redis/strict.rbc +1419 -0
- data/lib/redis/strings.rb +144 -0
- data/lib/redis/strings.rbc +3338 -0
- data/lib/redis/synchrony.rb +58 -0
- data/lib/redis/synchrony.rbc +1397 -0
- data/lib/redis/version.rb +7 -0
- data/lib/redis/version.rbc +180 -0
- data/lib/redis/zsets.rb +281 -0
- data/lib/redis/zsets.rbc +6596 -0
- data/lib/redis.rb +215 -0
- data/lib/redis.rbc +4391 -0
- metadata +117 -0
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Copyright (c) 2011, David Turnbull et al
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
7
|
+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
8
|
+
|
9
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
This project was started because I needed an authenticating and routable
|
2
|
+
proxy for Redis. The main feature is a high-performance, evented, pure-Ruby,
|
3
|
+
implementation of the complete Redis wire protocol with the same interface as
|
4
|
+
hiredis/reader.
|
5
|
+
|
6
|
+
In the worst possible scenario of very small payloads, I was benching 30k GETs
|
7
|
+
per second with pure ruby and 40k/s with hiredis/reader. With larger payloads,
|
8
|
+
the performance gap narrows to zero. Not near-zero, actual zero.
|
9
|
+
|
10
|
+
Ruby Gem:
|
11
|
+
|
12
|
+
gem install ruby-redis
|
13
|
+
|
14
|
+
|
15
|
+
Server:
|
16
|
+
|
17
|
+
# Runs a server that looks and feels like the C redis-server
|
18
|
+
bin/ruby-redis
|
19
|
+
# Run the TCL test suite from C Redis against the Ruby server
|
20
|
+
src/redis-test
|
21
|
+
|
22
|
+
|
23
|
+
Client example:
|
24
|
+
|
25
|
+
require 'redis'
|
26
|
+
EventMachine.run {
|
27
|
+
redis = EventMachine.connect '127.0.0.1', 6379, Redis
|
28
|
+
# Subscribe and publish messages will call here
|
29
|
+
redis.pubsub_callback do |message|
|
30
|
+
# case message[0]
|
31
|
+
# when 'psubscribe' ...
|
32
|
+
end
|
33
|
+
# All commands implemented uniformly with method_missing
|
34
|
+
# Returns instance of Redis::Command < EventMachine::Deferrable
|
35
|
+
# Pipelining is implicit
|
36
|
+
redis.set :pi, 3.14159
|
37
|
+
redis.get('pi') do |result|
|
38
|
+
p result
|
39
|
+
end
|
40
|
+
redis.blpop('mylist', 1).callback do |result|
|
41
|
+
p result
|
42
|
+
EM.stop
|
43
|
+
end.errback do |e|
|
44
|
+
EM.stop
|
45
|
+
raise e
|
46
|
+
end
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
Using hiredis/reader (only affects clients):
|
51
|
+
|
52
|
+
# require it before you connect
|
53
|
+
require 'hiredis/reader'
|
54
|
+
|
55
|
+
|
56
|
+
Fibers; compatible with em-synchrony:
|
57
|
+
|
58
|
+
require 'redis/synchrony'
|
59
|
+
Redis.synchrony {
|
60
|
+
# Use redis to pipeline and sync to block
|
61
|
+
redis = EventMachine.connect '127.0.0.1', 6379, Redis, :hiredis => true
|
62
|
+
sync = redis.synchrony
|
63
|
+
# repeat transaction until success
|
64
|
+
reply = nil
|
65
|
+
until reply
|
66
|
+
redis.watch 'mykey' # never fails, use pipeline
|
67
|
+
x = sync.get('mykey').to_i
|
68
|
+
reply = sync.multi_exec do |multi|
|
69
|
+
# multi is pipelined (async)
|
70
|
+
# no reason to block in here
|
71
|
+
multi.set 'mykey', x + 1
|
72
|
+
end
|
73
|
+
end
|
74
|
+
redis.close
|
75
|
+
p reply
|
76
|
+
EM.stop
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
Ruby to Redis type conversions:
|
81
|
+
|
82
|
+
String === Status reply
|
83
|
+
RuntimeError === Error reply
|
84
|
+
String === Bulk reply
|
85
|
+
Integer === Integer reply
|
86
|
+
Array === Multi-bulk reply
|
87
|
+
Hash === Multi-bulk reply to hgetall
|
88
|
+
NilClass === Nil element or nil multi-bulk
|
89
|
+
TrueClass === :1
|
90
|
+
FalseClass === :0
|
data/bin/ruby-redis
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
begin
|
3
|
+
require 'rubygems'
|
4
|
+
rescue LoadError
|
5
|
+
end
|
6
|
+
direct_bin_filename = File.expand_path '../lib/redis/bin', File.dirname(__FILE__)
|
7
|
+
if File.exist? direct_bin_filename + '.rb'
|
8
|
+
require direct_bin_filename
|
9
|
+
else
|
10
|
+
require 'redis/bin'
|
11
|
+
end
|
12
|
+
Redis::Bin.server
|
@@ -0,0 +1,243 @@
|
|
1
|
+
!RBIX
|
2
|
+
6235178746665710376
|
3
|
+
x
|
4
|
+
M
|
5
|
+
1
|
6
|
+
n
|
7
|
+
n
|
8
|
+
x
|
9
|
+
10
|
10
|
+
__script__
|
11
|
+
i
|
12
|
+
115
|
13
|
+
26
|
14
|
+
93
|
15
|
+
0
|
16
|
+
15
|
17
|
+
29
|
18
|
+
18
|
19
|
+
0
|
20
|
+
5
|
21
|
+
7
|
22
|
+
0
|
23
|
+
64
|
24
|
+
47
|
25
|
+
49
|
26
|
+
1
|
27
|
+
1
|
28
|
+
30
|
29
|
+
8
|
30
|
+
45
|
31
|
+
26
|
32
|
+
93
|
33
|
+
1
|
34
|
+
15
|
35
|
+
24
|
36
|
+
13
|
37
|
+
45
|
38
|
+
2
|
39
|
+
3
|
40
|
+
12
|
41
|
+
49
|
42
|
+
4
|
43
|
+
1
|
44
|
+
10
|
45
|
+
35
|
46
|
+
8
|
47
|
+
40
|
48
|
+
15
|
49
|
+
1
|
50
|
+
25
|
51
|
+
8
|
52
|
+
45
|
53
|
+
15
|
54
|
+
92
|
55
|
+
1
|
56
|
+
27
|
57
|
+
34
|
58
|
+
92
|
59
|
+
0
|
60
|
+
27
|
61
|
+
15
|
62
|
+
45
|
63
|
+
5
|
64
|
+
6
|
65
|
+
7
|
66
|
+
7
|
67
|
+
64
|
68
|
+
45
|
69
|
+
5
|
70
|
+
8
|
71
|
+
65
|
72
|
+
49
|
73
|
+
9
|
74
|
+
0
|
75
|
+
49
|
76
|
+
10
|
77
|
+
1
|
78
|
+
49
|
79
|
+
11
|
80
|
+
2
|
81
|
+
19
|
82
|
+
0
|
83
|
+
15
|
84
|
+
45
|
85
|
+
5
|
86
|
+
12
|
87
|
+
20
|
88
|
+
0
|
89
|
+
7
|
90
|
+
13
|
91
|
+
64
|
92
|
+
81
|
93
|
+
14
|
94
|
+
49
|
95
|
+
15
|
96
|
+
1
|
97
|
+
9
|
98
|
+
95
|
99
|
+
5
|
100
|
+
20
|
101
|
+
0
|
102
|
+
47
|
103
|
+
49
|
104
|
+
1
|
105
|
+
1
|
106
|
+
8
|
107
|
+
103
|
108
|
+
5
|
109
|
+
7
|
110
|
+
16
|
111
|
+
64
|
112
|
+
47
|
113
|
+
49
|
114
|
+
1
|
115
|
+
1
|
116
|
+
15
|
117
|
+
45
|
118
|
+
17
|
119
|
+
18
|
120
|
+
43
|
121
|
+
19
|
122
|
+
49
|
123
|
+
20
|
124
|
+
0
|
125
|
+
15
|
126
|
+
2
|
127
|
+
11
|
128
|
+
I
|
129
|
+
7
|
130
|
+
I
|
131
|
+
1
|
132
|
+
I
|
133
|
+
0
|
134
|
+
I
|
135
|
+
0
|
136
|
+
n
|
137
|
+
p
|
138
|
+
21
|
139
|
+
s
|
140
|
+
8
|
141
|
+
rubygems
|
142
|
+
x
|
143
|
+
7
|
144
|
+
require
|
145
|
+
x
|
146
|
+
9
|
147
|
+
LoadError
|
148
|
+
n
|
149
|
+
x
|
150
|
+
3
|
151
|
+
===
|
152
|
+
x
|
153
|
+
4
|
154
|
+
File
|
155
|
+
n
|
156
|
+
s
|
157
|
+
16
|
158
|
+
../lib/redis/bin
|
159
|
+
n
|
160
|
+
x
|
161
|
+
11
|
162
|
+
active_path
|
163
|
+
x
|
164
|
+
7
|
165
|
+
dirname
|
166
|
+
x
|
167
|
+
11
|
168
|
+
expand_path
|
169
|
+
n
|
170
|
+
s
|
171
|
+
3
|
172
|
+
.rb
|
173
|
+
x
|
174
|
+
1
|
175
|
+
+
|
176
|
+
x
|
177
|
+
6
|
178
|
+
exist?
|
179
|
+
s
|
180
|
+
9
|
181
|
+
redis/bin
|
182
|
+
x
|
183
|
+
5
|
184
|
+
Redis
|
185
|
+
n
|
186
|
+
x
|
187
|
+
3
|
188
|
+
Bin
|
189
|
+
x
|
190
|
+
6
|
191
|
+
server
|
192
|
+
p
|
193
|
+
21
|
194
|
+
I
|
195
|
+
0
|
196
|
+
I
|
197
|
+
3
|
198
|
+
I
|
199
|
+
12
|
200
|
+
I
|
201
|
+
0
|
202
|
+
I
|
203
|
+
17
|
204
|
+
I
|
205
|
+
4
|
206
|
+
I
|
207
|
+
2d
|
208
|
+
I
|
209
|
+
0
|
210
|
+
I
|
211
|
+
31
|
212
|
+
I
|
213
|
+
6
|
214
|
+
I
|
215
|
+
47
|
216
|
+
I
|
217
|
+
7
|
218
|
+
I
|
219
|
+
56
|
220
|
+
I
|
221
|
+
8
|
222
|
+
I
|
223
|
+
5f
|
224
|
+
I
|
225
|
+
a
|
226
|
+
I
|
227
|
+
67
|
228
|
+
I
|
229
|
+
0
|
230
|
+
I
|
231
|
+
68
|
232
|
+
I
|
233
|
+
c
|
234
|
+
I
|
235
|
+
73
|
236
|
+
x
|
237
|
+
47
|
238
|
+
/Users/dturnbull/ruby/ruby-redis/bin/ruby-redis
|
239
|
+
p
|
240
|
+
1
|
241
|
+
x
|
242
|
+
19
|
243
|
+
direct_bin_filename
|
data/lib/redis/bin.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.expand_path '../redis', File.dirname(__FILE__)
|
2
|
+
require_relative 'config'
|
3
|
+
require_relative 'connection'
|
4
|
+
require_relative 'logger'
|
5
|
+
|
6
|
+
class Redis
|
7
|
+
class Bin
|
8
|
+
|
9
|
+
class StrictConnection < Connection
|
10
|
+
include Strict
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.server
|
14
|
+
|
15
|
+
if ARGV==['-v'] or ARGV==['--version']
|
16
|
+
print "Redis server version %s (Ruby)\n" % Redis::VERSION
|
17
|
+
exit 0
|
18
|
+
end
|
19
|
+
|
20
|
+
if ARGV==['--help'] or ARGV.size > 1
|
21
|
+
STDERR.print "Usage: ruby-redis [/path/to/redis.conf]\n"
|
22
|
+
STDERR.print " ruby-redis - (read config from stdin)\n"
|
23
|
+
exit 1
|
24
|
+
end
|
25
|
+
|
26
|
+
show_no_config_warning = (ARGV.size == 0)
|
27
|
+
|
28
|
+
config = Config.new(ARGV.empty? ? [] : ARGF)
|
29
|
+
|
30
|
+
Dir.chdir config[:dir]
|
31
|
+
|
32
|
+
Redis.logger config[:logfile] unless config[:logfile] == 'stdout'
|
33
|
+
|
34
|
+
#TODO
|
35
|
+
# Set server verbosity to 'debug'
|
36
|
+
# it can be one of:
|
37
|
+
# debug (a lot of information, useful for development/testing)
|
38
|
+
# verbose (many rarely useful info, but not a mess like the debug level)
|
39
|
+
# notice (moderately verbose, what you want in production probably)
|
40
|
+
# warning (only very important / critical messages are logged)
|
41
|
+
# loglevel verbose
|
42
|
+
|
43
|
+
if show_no_config_warning
|
44
|
+
Redis.logger.warn "Warning: no config file specified, using the default config. In order to specify a config file use 'ruby-redis /path/to/redis.conf'"
|
45
|
+
end
|
46
|
+
|
47
|
+
EventMachine.epoll
|
48
|
+
EventMachine.run {
|
49
|
+
|
50
|
+
(0...config[:databases]).each do |db_index|
|
51
|
+
Redis.databases[db_index] ||= Database.new
|
52
|
+
end
|
53
|
+
|
54
|
+
#TODO support changing host and EventMachine::start_unix_domain_server
|
55
|
+
EventMachine::start_server "127.0.0.1", config[:port], StrictConnection, config[:requirepass]
|
56
|
+
|
57
|
+
if config[:daemonize]
|
58
|
+
raise 'todo'
|
59
|
+
# daemonize();
|
60
|
+
# FILE *fp = fopen(server.pidfile,"w");
|
61
|
+
# if (fp) { fprintf(fp,"%d\n",(int)getpid()); fclose(fp); }
|
62
|
+
end
|
63
|
+
|
64
|
+
Redis.logger.notice "Server started, Ruby Redis version %s" % Redis::VERSION
|
65
|
+
Redis.logger.notice "The server is now ready to accept connections on port %d" % config[:port]
|
66
|
+
|
67
|
+
# The test suite blocks until it gets the pid from the log.
|
68
|
+
Redis.logger.flush
|
69
|
+
|
70
|
+
}
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|