redis 3.0.0.rc1 → 3.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +50 -0
- data/.travis/Gemfile +11 -0
- data/CHANGELOG.md +47 -19
- data/README.md +160 -149
- data/Rakefile +15 -50
- data/examples/pubsub.rb +1 -1
- data/examples/unicorn/config.ru +1 -1
- data/examples/unicorn/unicorn.rb +1 -1
- data/lib/redis.rb +790 -390
- data/lib/redis/client.rb +137 -49
- data/lib/redis/connection/hiredis.rb +26 -15
- data/lib/redis/connection/ruby.rb +170 -53
- data/lib/redis/connection/synchrony.rb +23 -35
- data/lib/redis/distributed.rb +92 -32
- data/lib/redis/errors.rb +4 -2
- data/lib/redis/pipeline.rb +17 -6
- data/lib/redis/version.rb +1 -1
- data/redis.gemspec +4 -6
- data/test/blocking_commands_test.rb +42 -0
- data/test/command_map_test.rb +18 -17
- data/test/commands_on_hashes_test.rb +13 -12
- data/test/commands_on_lists_test.rb +35 -45
- data/test/commands_on_sets_test.rb +55 -54
- data/test/commands_on_sorted_sets_test.rb +106 -105
- data/test/commands_on_strings_test.rb +64 -55
- data/test/commands_on_value_types_test.rb +66 -54
- data/test/connection_handling_test.rb +136 -151
- data/test/distributed_blocking_commands_test.rb +33 -40
- data/test/distributed_commands_on_hashes_test.rb +6 -7
- data/test/distributed_commands_on_lists_test.rb +13 -14
- data/test/distributed_commands_on_sets_test.rb +57 -58
- data/test/distributed_commands_on_sorted_sets_test.rb +11 -12
- data/test/distributed_commands_on_strings_test.rb +31 -32
- data/test/distributed_commands_on_value_types_test.rb +61 -46
- data/test/distributed_commands_requiring_clustering_test.rb +108 -108
- data/test/distributed_connection_handling_test.rb +14 -15
- data/test/distributed_internals_test.rb +7 -19
- data/test/distributed_key_tags_test.rb +36 -36
- data/test/distributed_persistence_control_commands_test.rb +17 -14
- data/test/distributed_publish_subscribe_test.rb +61 -69
- data/test/distributed_remote_server_control_commands_test.rb +39 -28
- data/test/distributed_sorting_test.rb +12 -13
- data/test/distributed_test.rb +40 -41
- data/test/distributed_transactions_test.rb +20 -21
- data/test/encoding_test.rb +12 -9
- data/test/error_replies_test.rb +42 -36
- data/test/helper.rb +118 -85
- data/test/helper_test.rb +20 -6
- data/test/internals_test.rb +167 -103
- data/test/lint/blocking_commands.rb +124 -0
- data/test/lint/hashes.rb +115 -93
- data/test/lint/lists.rb +86 -80
- data/test/lint/sets.rb +68 -62
- data/test/lint/sorted_sets.rb +200 -195
- data/test/lint/strings.rb +112 -94
- data/test/lint/value_types.rb +76 -55
- data/test/persistence_control_commands_test.rb +17 -12
- data/test/pipelining_commands_test.rb +135 -126
- data/test/publish_subscribe_test.rb +105 -110
- data/test/remote_server_control_commands_test.rb +74 -58
- data/test/sorting_test.rb +31 -29
- data/test/support/connection/hiredis.rb +1 -0
- data/test/support/connection/ruby.rb +1 -0
- data/test/support/connection/synchrony.rb +17 -0
- data/test/{redis_mock.rb → support/redis_mock.rb} +24 -21
- data/test/support/wire/synchrony.rb +24 -0
- data/test/support/wire/thread.rb +5 -0
- data/test/synchrony_driver.rb +9 -9
- data/test/test.conf +1 -1
- data/test/thread_safety_test.rb +21 -19
- data/test/transactions_test.rb +189 -118
- data/test/unknown_commands_test.rb +9 -8
- data/test/url_param_test.rb +46 -41
- metadata +28 -43
- data/TODO.md +0 -4
- data/benchmarking/thread_safety.rb +0 -38
- data/test/lint/internals.rb +0 -36
data/.travis.yml
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
language: ruby
|
2
|
+
|
3
|
+
branches:
|
4
|
+
only:
|
5
|
+
- master
|
6
|
+
- test-unit
|
7
|
+
|
8
|
+
rvm:
|
9
|
+
- 1.8.7
|
10
|
+
- 1.9.2
|
11
|
+
- 1.9.3
|
12
|
+
- jruby-18mode
|
13
|
+
- jruby-19mode
|
14
|
+
|
15
|
+
gemfile:
|
16
|
+
- .travis/Gemfile
|
17
|
+
|
18
|
+
env:
|
19
|
+
- conn=ruby
|
20
|
+
- conn=hiredis
|
21
|
+
- conn=synchrony
|
22
|
+
|
23
|
+
matrix:
|
24
|
+
exclude:
|
25
|
+
# hiredis
|
26
|
+
- rvm: jruby-18mode
|
27
|
+
gemfile: .travis/Gemfile
|
28
|
+
env: conn=hiredis
|
29
|
+
- rvm: jruby-19mode
|
30
|
+
gemfile: .travis/Gemfile
|
31
|
+
env: conn=hiredis
|
32
|
+
|
33
|
+
# synchrony
|
34
|
+
- rvm: 1.8.7
|
35
|
+
gemfile: .travis/Gemfile
|
36
|
+
env: conn=synchrony
|
37
|
+
- rvm: jruby-18mode
|
38
|
+
gemfile: .travis/Gemfile
|
39
|
+
env: conn=synchrony
|
40
|
+
- rvm: jruby-19mode
|
41
|
+
gemfile: .travis/Gemfile
|
42
|
+
env: conn=synchrony
|
43
|
+
|
44
|
+
notifications:
|
45
|
+
irc:
|
46
|
+
- irc.freenode.net#redis-rb
|
47
|
+
email:
|
48
|
+
- damian.janowski@gmail.com
|
49
|
+
- michel@soveran.com
|
50
|
+
- pcnoordhuis@gmail.com
|
data/.travis/Gemfile
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# 3.0 (unreleased)
|
2
2
|
|
3
|
+
* The repository now lives at [https://github.com/redis/redis-rb](https://github.com/redis/redis-rb).
|
4
|
+
Thanks, Ezra!
|
5
|
+
|
6
|
+
* Added support for `PEXPIRE`, `PTTL`, `PEXPIREAT`, `PSETEX`,
|
7
|
+
`INCRYBYFLOAT`, `HINCRYBYFLOAT` and `TIME` (Redis 2.6).
|
8
|
+
|
9
|
+
* `Redis.current` is now thread unsafe, because the client itself is thread safe.
|
10
|
+
|
11
|
+
In the future you'll be able to do something like:
|
12
|
+
|
13
|
+
Redis.current = Redis::Pool.connect
|
14
|
+
|
15
|
+
This makes `Redis.current` actually usable in multi-threaded environments,
|
16
|
+
while not affecting those running a single thread.
|
17
|
+
|
18
|
+
* Change API for `BLPOP`, `BRPOP` and `BRPOPLPUSH`. Both `BLPOP` and
|
19
|
+
`BRPOP` now take a single argument equal to a string key, or an array
|
20
|
+
with string keys, followed by an optional hash with a `:timeout` key.
|
21
|
+
`BRPOPLPUSH` also takes an optional hash with a `:timeout` key as last
|
22
|
+
argument for consistency. By default, these commands use a timeout of
|
23
|
+
`0` to not time out.
|
24
|
+
|
25
|
+
* When `SORT` is passed multiple key patterns to get via the `:get`
|
26
|
+
option, it now returns an array per result element, holding all `GET`
|
27
|
+
substitutions.
|
28
|
+
|
29
|
+
* The `MSETNX` command now returns a boolean.
|
30
|
+
|
3
31
|
* The `ZRANGE`, `ZREVRANGE`, `ZRANGEBYSCORE` and `ZREVRANGEBYSCORE` commands
|
4
32
|
now return an array containing `[String, Float]` pairs when
|
5
33
|
`:with_scores => true` is passed.
|
@@ -9,34 +37,34 @@
|
|
9
37
|
|
10
38
|
* The client now raises custom exceptions where it makes sense.
|
11
39
|
|
12
|
-
|
13
|
-
|
40
|
+
If by any chance you were rescuing low-level exceptions (`Errno::*`),
|
41
|
+
you should now rescue as follows:
|
14
42
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
43
|
+
Errno::ECONNRESET -> Redis::ConnectionError
|
44
|
+
Errno::EPIPE -> Redis::ConnectionError
|
45
|
+
Errno::ECONNABORTED -> Redis::ConnectionError
|
46
|
+
Errno::EBADF -> Redis::ConnectionError
|
47
|
+
Errno::EINVAL -> Redis::ConnectionError
|
48
|
+
Errno::EAGAIN -> Redis::TimeoutError
|
49
|
+
Errno::ECONNREFUSED -> Redis::CannotConnectError
|
22
50
|
|
23
51
|
* Always raise exceptions originating from erroneous command invocation
|
24
52
|
inside pipelines and MULTI/EXEC blocks.
|
25
53
|
|
26
|
-
|
27
|
-
|
54
|
+
The old behavior (swallowing exceptions) could cause application bugs
|
55
|
+
to go unnoticed.
|
28
56
|
|
29
57
|
* Implement futures for assigning values inside pipelines and MULTI/EXEC
|
30
58
|
blocks. Futures are assigned their value after the pipeline or
|
31
59
|
MULTI/EXEC block has executed.
|
32
60
|
|
33
|
-
```ruby
|
34
|
-
$redis.pipelined do
|
35
|
-
|
36
|
-
end
|
61
|
+
```ruby
|
62
|
+
$redis.pipelined do
|
63
|
+
@future = $redis.get "key"
|
64
|
+
end
|
37
65
|
|
38
|
-
puts @future.value
|
39
|
-
```
|
66
|
+
puts @future.value
|
67
|
+
```
|
40
68
|
|
41
69
|
* Ruby 1.8.6 is officially not supported.
|
42
70
|
|
@@ -45,7 +73,7 @@ puts @future.value
|
|
45
73
|
* Pipelined commands now return the same replies as when called outside
|
46
74
|
a pipeline.
|
47
75
|
|
48
|
-
|
76
|
+
In the past, pipelined replies were returned without post-processing.
|
49
77
|
|
50
78
|
* Support `SLOWLOG` command (Michael Bernstein).
|
51
79
|
|
@@ -56,7 +84,7 @@ puts @future.value
|
|
56
84
|
|
57
85
|
* Connecting using a URL now checks that a host is given.
|
58
86
|
|
59
|
-
|
87
|
+
It's just a small sanity check, cf. #126
|
60
88
|
|
61
89
|
* Support variadic commands introduced in Redis 2.4.
|
62
90
|
|
data/README.md
CHANGED
@@ -1,195 +1,205 @@
|
|
1
|
-
# redis-rb
|
1
|
+
# redis-rb [![Build Status][travis-image]][travis-link]
|
2
2
|
|
3
|
-
|
3
|
+
[travis-image]: https://secure.travis-ci.org/redis/redis-rb.png?branch=master
|
4
|
+
[travis-link]: http://travis-ci.org/redis/redis-rb
|
5
|
+
[travis-home]: http://travis-ci.org/
|
4
6
|
|
5
|
-
A
|
6
|
-
It features thread safety, client-side sharding, and an obsession for performance.
|
7
|
+
A Ruby client library for [Redis][redis-home].
|
7
8
|
|
8
|
-
|
9
|
+
[redis-home]: http://redis.io
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
backwards-compatible when it shouldn't. It does not support Redis' original protocol, favoring the
|
14
|
-
new, binary-safe one. You should be using this version if you're running Redis 1.2+.
|
15
|
-
|
16
|
-
## Information about Redis
|
17
|
-
|
18
|
-
Redis is a key-value store with some interesting features:
|
19
|
-
|
20
|
-
1. It's fast.
|
21
|
-
2. Keys are strings but values are typed. Currently Redis supports strings, lists, sets, sorted sets and hashes. [Atomic operations](http://redis.io/commands) can be done on all of these types.
|
22
|
-
|
23
|
-
See [the Redis homepage](http://redis.io) for more information.
|
11
|
+
A Ruby client that tries to match Redis' API one-to-one, while still
|
12
|
+
providing an idiomatic interface. It features thread-safety, client-side
|
13
|
+
sharding, pipelining, and an obsession for performance.
|
24
14
|
|
25
15
|
## Getting started
|
26
16
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
redis = Redis.new
|
32
|
-
|
33
|
-
This assumes Redis was started with default values listening on `localhost`, port 6379. If you need to connect to a remote server or a different port, try:
|
34
|
-
|
35
|
-
redis = Redis.new(:host => "10.0.1.1", :port => 6380)
|
36
|
-
|
37
|
-
To connect to Redis listening on a unix socket, try:
|
38
|
-
|
39
|
-
redis = Redis.new(:path => "/tmp/redis.sock")
|
40
|
-
|
41
|
-
Once connected, you can start running commands against Redis:
|
42
|
-
|
43
|
-
>> redis.set "foo", "bar"
|
44
|
-
=> "OK"
|
45
|
-
|
46
|
-
>> redis.get "foo"
|
47
|
-
=> "bar"
|
48
|
-
|
49
|
-
>> redis.sadd "users", "albert"
|
50
|
-
=> true
|
51
|
-
|
52
|
-
>> redis.sadd "users", "bernard"
|
53
|
-
=> true
|
54
|
-
|
55
|
-
>> redis.sadd "users", "charles"
|
56
|
-
=> true
|
57
|
-
|
58
|
-
How many users?
|
59
|
-
|
60
|
-
>> redis.scard "users"
|
61
|
-
=> 3
|
17
|
+
As of version 2.0 this client only targets Redis version 2.0 and higher.
|
18
|
+
You can use an older version of this client if you need to interface
|
19
|
+
with a Redis instance older than 2.0, but this is no longer supported.
|
62
20
|
|
63
|
-
|
64
|
-
|
65
|
-
>> redis.sismember "users", "albert"
|
66
|
-
=> true
|
67
|
-
|
68
|
-
Is `isabel` a user?
|
69
|
-
|
70
|
-
>> redis.sismember "users", "isabel"
|
71
|
-
=> false
|
21
|
+
You can connect to Redis by instantiating the `Redis` class:
|
72
22
|
|
73
|
-
|
23
|
+
```ruby
|
24
|
+
require "redis"
|
74
25
|
|
75
|
-
|
76
|
-
|
26
|
+
redis = Redis.new
|
27
|
+
```
|
77
28
|
|
78
|
-
|
79
|
-
|
29
|
+
This assumes Redis was started with a default configuration, and it
|
30
|
+
listening on `localhost`, port 6379. If you need to connect to a remote
|
31
|
+
server or a different port, try:
|
80
32
|
|
81
|
-
|
33
|
+
```ruby
|
34
|
+
redis = Redis.new(:host => "10.0.1.1", :port => 6380)
|
35
|
+
```
|
82
36
|
|
83
|
-
|
84
|
-
=> ["albert"]
|
37
|
+
To connect to Redis listening on a Unix socket, try:
|
85
38
|
|
86
|
-
|
39
|
+
```ruby
|
40
|
+
redis = Redis.new(:path => "/tmp/redis.sock")
|
41
|
+
```
|
87
42
|
|
88
|
-
|
89
|
-
|
43
|
+
The Redis class exports methods that are named identical to the commands
|
44
|
+
they execute. The arguments these methods accept are often identical to
|
45
|
+
the arguments specified on the [Redis website][redis-commands]. For
|
46
|
+
instance, the `SET` and `GET` commands can be called like this:
|
90
47
|
|
91
|
-
|
48
|
+
[redis-commands]: http://redis.io/commands
|
92
49
|
|
93
|
-
|
94
|
-
|
50
|
+
```ruby
|
51
|
+
redis.set("mykey", "hello world")
|
52
|
+
# => "OK"
|
95
53
|
|
96
|
-
|
54
|
+
redis.get("mykey")
|
55
|
+
# => "hello world"
|
56
|
+
```
|
97
57
|
|
98
|
-
|
99
|
-
|
58
|
+
All commands, their arguments and return values are documented, and
|
59
|
+
available on [rdoc.info][rdoc].
|
100
60
|
|
61
|
+
[rdoc]: http://rdoc.info/github/redis/redis-rb/
|
101
62
|
|
102
63
|
## Storing objects
|
103
64
|
|
104
|
-
Redis only stores strings as values. If you want to store an object
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
the
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
65
|
+
Redis only stores strings as values. If you want to store an object, you
|
66
|
+
can use a serialization mechanism such as JSON:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
require "json"
|
70
|
+
|
71
|
+
redis.set "foo", [1, 2, 3].to_json
|
72
|
+
# => OK
|
73
|
+
|
74
|
+
JSON.parse(redis.get("foo"))
|
75
|
+
# => [1, 2, 3]
|
76
|
+
```
|
77
|
+
|
78
|
+
## Pipelining
|
79
|
+
|
80
|
+
When multiple commands are executed sequentially, but are not dependent,
|
81
|
+
the calls can be *pipelined*. This means that the client doesn't wait
|
82
|
+
for reply of the first command before sending the next command. The
|
83
|
+
advantage is that multiple commands are sent at once, resulting in
|
84
|
+
faster overall execution.
|
85
|
+
|
86
|
+
The client can be instructed to pipeline commands by using the
|
87
|
+
`#pipelined` method. After the block is executed, the client sends all
|
88
|
+
commands to Redis and gathers their replies. These replies are returned
|
89
|
+
by the `#pipelined` method.
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
redis.pipelined do
|
93
|
+
redis.set "foo", "bar"
|
94
|
+
redis.incr "baz"
|
95
|
+
end
|
96
|
+
# => ["OK", 1]
|
97
|
+
```
|
98
|
+
|
99
|
+
### Executing commands atomically
|
100
|
+
|
101
|
+
You can use `MULTI/EXEC` to run a number of commands in an atomic
|
102
|
+
fashion. This is similar to executing a pipeline, but the commands are
|
103
|
+
preceded by a call to `MULTI`, and followed by a call to `EXEC`. Like
|
104
|
+
the regular pipeline, the replies to the commands are returned by the
|
105
|
+
`#multi` method.
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
redis.multi do
|
109
|
+
redis.set "foo", "bar"
|
110
|
+
redis.incr "baz"
|
111
|
+
end
|
112
|
+
# => ["OK", 1]
|
113
|
+
```
|
114
|
+
|
115
|
+
### Futures
|
116
|
+
|
117
|
+
Replies to commands in a pipeline can be accessed via the *futures* they
|
118
|
+
emit (since redis-rb 3.0). All calls inside a pipeline block return a
|
119
|
+
`Future` object, which responds to the `#value` method. When the
|
120
|
+
pipeline has succesfully executed, all futures are assigned their
|
121
|
+
respective replies and can be used.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
redis.pipelined do
|
125
|
+
@set = redis.set "foo", "bar"
|
126
|
+
@incr = redis.incr "baz"
|
127
|
+
end
|
128
|
+
|
129
|
+
@set.value
|
130
|
+
# => "OK"
|
131
|
+
|
132
|
+
@incr.value
|
133
|
+
# => 1
|
134
|
+
```
|
133
135
|
|
134
136
|
## Alternate drivers
|
135
137
|
|
136
|
-
Non-default connection drivers are only used when they are explicitly required.
|
137
138
|
By default, redis-rb uses Ruby's socket library to talk with Redis.
|
139
|
+
To use an alternative connection driver it should be specified as option
|
140
|
+
when instantiating the client object. These instructions are only valid
|
141
|
+
for **redis-rb 3.0**. For instructions on how to use alternate drivers from
|
142
|
+
**redis-rb 2.2**, please refer to an [older README][readme-2.2.2].
|
143
|
+
|
144
|
+
[readme-2.2.2]: https://github.com/redis/redis-rb/blob/v2.2.2/README.md
|
138
145
|
|
139
146
|
### hiredis
|
140
147
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
supported (by default). Use hiredis when you have large array replies (think
|
146
|
-
`LRANGE`, `SMEMBERS`, `ZRANGE`, etc.) and/or large pipelines of commands.
|
148
|
+
The hiredis driver uses the connection facility of hiredis-rb. In turn,
|
149
|
+
hiredis-rb is a binding to the official hiredis client library. It
|
150
|
+
optimizes for speed, at the cost of portability. Because it is a C
|
151
|
+
extension, JRuby is not supported (by default).
|
147
152
|
|
148
|
-
|
153
|
+
It is best to use hiredis when you have large replies (for example:
|
154
|
+
`LRANGE`, `SMEMBERS`, `ZRANGE`, etc.) and/or use big pipelines.
|
149
155
|
|
150
|
-
|
151
|
-
gem "redis", "~> 2.2.0", :require => ["redis/connection/hiredis", "redis"]
|
156
|
+
In your Gemfile, include hiredis:
|
152
157
|
|
153
|
-
|
158
|
+
```ruby
|
159
|
+
gem "redis", "~> 3.0.0.rc2"
|
160
|
+
gem "hiredis", "~> 0.4.5"
|
161
|
+
```
|
154
162
|
|
155
|
-
|
156
|
-
[em-synchrony](https://github.com/igrigorik/em-synchrony). Using the synchrony
|
157
|
-
backend from redis-rb is done by requiring `redis/connection/synchrony` before
|
158
|
-
requiring `redis`. This driver makes redis-rb work with EventMachine's
|
159
|
-
asynchronous I/O, while not changing the exposed API. The hiredis gem needs to
|
160
|
-
be available as well, because the synchrony driver uses hiredis for parsing the
|
161
|
-
Redis protocol.
|
163
|
+
When instantiating the client object, specify hiredis:
|
162
164
|
|
163
|
-
|
165
|
+
```ruby
|
166
|
+
redis = Redis.new(:driver => :hiredis)
|
167
|
+
```
|
164
168
|
|
165
|
-
|
166
|
-
gem "em-synchrony"
|
167
|
-
gem "redis", "~> 2.2.0", :require => ["redis/connection/synchrony", "redis"]
|
169
|
+
### synchrony
|
168
170
|
|
169
|
-
|
171
|
+
The synchrony driver adds support for [em-synchrony][em-synchrony].
|
172
|
+
This makes redis-rb work with EventMachine's asynchronous I/O, while not
|
173
|
+
changing the exposed API. The hiredis gem needs to be available as
|
174
|
+
well, because the synchrony driver uses hiredis for parsing the Redis
|
175
|
+
protocol.
|
170
176
|
|
171
|
-
|
177
|
+
[em-synchrony]: https://github.com/igrigorik/em-synchrony
|
172
178
|
|
173
|
-
|
174
|
-
* MRI 1.9.2 (drivers: Ruby, hiredis, em-synchrony)
|
175
|
-
* JRuby 1.6 (drivers: Ruby)
|
176
|
-
* Rubinius 1.2 (drivers: Ruby, hiredis)
|
179
|
+
In your Gemfile, include em-synchrony and hiredis:
|
177
180
|
|
178
|
-
|
181
|
+
```ruby
|
182
|
+
gem "redis", "~> 3.0.0.rc2"
|
183
|
+
gem "hiredis", "~> 0.4.5"
|
184
|
+
gem "em-synchrony"
|
185
|
+
```
|
179
186
|
|
180
|
-
|
181
|
-
read operation. This means socket timeouts don't work on 1.9 when using the
|
182
|
-
pure Ruby I/O code. Use hiredis when you want use socket timeouts on 1.9.
|
187
|
+
When instantiating the client object, specify hiredis:
|
183
188
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
+
```ruby
|
190
|
+
redis = Redis.new(:driver => :synchrony)
|
191
|
+
```
|
192
|
+
|
193
|
+
## Testing
|
189
194
|
|
190
|
-
|
195
|
+
This library is tested using [Travis][travis-home], where it is tested
|
196
|
+
against the following interpreters and drivers:
|
191
197
|
|
192
|
-
|
198
|
+
* MRI 1.8.7 (drivers: ruby, hiredis)
|
199
|
+
* MRI 1.9.2 (drivers: ruby, hiredis, synchrony)
|
200
|
+
* MRI 1.9.3 (drivers: ruby, hiredis, synchrony)
|
201
|
+
* JRuby 1.6 (1.8 mode) (drivers: ruby)
|
202
|
+
* JRuby 1.6 (1.9 mode) (drivers: ruby)
|
193
203
|
|
194
204
|
## Contributors
|
195
205
|
|
@@ -211,4 +221,5 @@ all contributors)
|
|
211
221
|
|
212
222
|
## Contributing
|
213
223
|
|
214
|
-
[Fork the project](
|
224
|
+
[Fork the project](https://github.com/redis/redis-rb) and send pull
|
225
|
+
requests. You can also ask for help at `#redis-rb` on Freenode.
|