redis 3.3.5 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis/Gemfile +3 -1
- data/.travis.yml +36 -52
- data/CHANGELOG.md +18 -4
- data/Gemfile +0 -1
- data/README.md +31 -75
- data/benchmarking/logging.rb +1 -1
- data/bors.toml +14 -0
- data/lib/redis/client.rb +12 -8
- data/lib/redis/connection/command_helper.rb +2 -8
- data/lib/redis/connection/hiredis.rb +2 -2
- data/lib/redis/connection/ruby.rb +8 -28
- data/lib/redis/connection/synchrony.rb +12 -4
- data/lib/redis/connection.rb +2 -2
- data/lib/redis/distributed.rb +19 -6
- data/lib/redis/hash_ring.rb +20 -64
- data/lib/redis/pipeline.rb +0 -6
- data/lib/redis/version.rb +1 -1
- data/lib/redis.rb +89 -40
- data/makefile +42 -0
- data/redis.gemspec +7 -9
- data/test/bitpos_test.rb +13 -19
- data/test/blocking_commands_test.rb +3 -5
- data/test/client_test.rb +1 -1
- data/test/command_map_test.rb +3 -5
- data/test/commands_on_hashes_test.rb +2 -4
- data/test/commands_on_hyper_log_log_test.rb +3 -5
- data/test/commands_on_lists_test.rb +2 -4
- data/test/commands_on_sets_test.rb +2 -4
- data/test/commands_on_sorted_sets_test.rb +17 -4
- data/test/commands_on_strings_test.rb +3 -5
- data/test/commands_on_value_types_test.rb +44 -6
- data/test/connection_handling_test.rb +5 -7
- data/test/distributed_blocking_commands_test.rb +2 -4
- data/test/distributed_commands_on_hashes_test.rb +2 -4
- data/test/distributed_commands_on_hyper_log_log_test.rb +2 -4
- data/test/distributed_commands_on_lists_test.rb +2 -4
- data/test/distributed_commands_on_sets_test.rb +27 -4
- data/test/distributed_commands_on_sorted_sets_test.rb +2 -4
- data/test/distributed_commands_on_strings_test.rb +20 -10
- data/test/distributed_commands_on_value_types_test.rb +2 -4
- data/test/distributed_commands_requiring_clustering_test.rb +1 -3
- data/test/distributed_connection_handling_test.rb +1 -3
- data/test/distributed_internals_test.rb +8 -19
- data/test/distributed_key_tags_test.rb +4 -6
- data/test/distributed_persistence_control_commands_test.rb +1 -3
- data/test/distributed_publish_subscribe_test.rb +1 -3
- data/test/distributed_remote_server_control_commands_test.rb +1 -3
- data/test/distributed_scripting_test.rb +1 -3
- data/test/distributed_sorting_test.rb +1 -3
- data/test/distributed_test.rb +12 -14
- data/test/distributed_transactions_test.rb +1 -3
- data/test/encoding_test.rb +4 -8
- data/test/error_replies_test.rb +2 -4
- data/test/fork_safety_test.rb +1 -6
- data/test/helper.rb +10 -41
- data/test/helper_test.rb +1 -3
- data/test/internals_test.rb +27 -55
- data/test/lint/strings.rb +6 -20
- data/test/lint/value_types.rb +8 -0
- data/test/persistence_control_commands_test.rb +1 -3
- data/test/pipelining_commands_test.rb +4 -8
- data/test/publish_subscribe_test.rb +1 -3
- data/test/remote_server_control_commands_test.rb +60 -3
- data/test/scanning_test.rb +1 -7
- data/test/scripting_test.rb +1 -3
- data/test/sentinel_command_test.rb +1 -3
- data/test/sentinel_test.rb +1 -3
- data/test/sorting_test.rb +1 -3
- data/test/ssl_test.rb +45 -49
- data/test/support/connection/hiredis.rb +1 -1
- data/test/support/connection/ruby.rb +1 -1
- data/test/support/connection/synchrony.rb +1 -1
- data/test/synchrony_driver.rb +6 -9
- data/test/thread_safety_test.rb +1 -3
- data/test/transactions_test.rb +1 -3
- data/test/unknown_commands_test.rb +1 -3
- data/test/url_param_test.rb +44 -46
- metadata +29 -15
- data/Rakefile +0 -87
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e0d0ba2328aca583c0f487729779c2b10b12c7b
|
4
|
+
data.tar.gz: 4a411cfa3512bafe7c2c12ac8a02c02bc87065aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3af7dc63dc7bdc243da306817583db9b6989c21a0714c6652b4a443bfd9c46b2afba0707b028d708a74148bbeedd09d4ec207a0459b3559cb19b95f2f030bb07
|
7
|
+
data.tar.gz: 98d5aed456ebcd3ccdc50980879a3c14be4c8a1874c6febae95579d2fb3828bda2e82b05e62dc6a4966e178993d4a2a20dc3dedd9f8583cd731851eab2f8e164
|
data/.travis/Gemfile
CHANGED
data/.travis.yml
CHANGED
@@ -1,87 +1,71 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
|
+
script: make test
|
4
|
+
|
3
5
|
rvm:
|
4
|
-
-
|
5
|
-
-
|
6
|
-
- 2.
|
7
|
-
-
|
8
|
-
-
|
9
|
-
- 2.3.0
|
10
|
-
- jruby-18mode
|
11
|
-
- jruby-19mode
|
12
|
-
- jruby-9.0.5.0
|
13
|
-
- rbx-2
|
6
|
+
- 2.2.2
|
7
|
+
- 2.3.3
|
8
|
+
- 2.4.1
|
9
|
+
- jruby-9
|
10
|
+
- rbx-3
|
14
11
|
|
15
12
|
gemfile: ".travis/Gemfile"
|
16
13
|
|
17
14
|
sudo: false
|
18
15
|
|
16
|
+
before_script:
|
17
|
+
- if (ruby -e "exit RUBY_VERSION.to_f >= 2.4"); then export RUBYOPT="--enable-frozen-string-literal"; fi; echo $RUBYOPT
|
18
|
+
|
19
19
|
env:
|
20
20
|
global:
|
21
21
|
- VERBOSE=true
|
22
22
|
- TIMEOUT=1
|
23
23
|
matrix:
|
24
|
-
-
|
25
|
-
-
|
26
|
-
-
|
27
|
-
-
|
28
|
-
-
|
29
|
-
-
|
30
|
-
-
|
24
|
+
- DRIVER=ruby REDIS_BRANCH=3.0
|
25
|
+
- DRIVER=ruby REDIS_BRANCH=3.2
|
26
|
+
- DRIVER=hiredis REDIS_BRANCH=3.0
|
27
|
+
- DRIVER=hiredis REDIS_BRANCH=3.2
|
28
|
+
- DRIVER=synchrony REDIS_BRANCH=3.0
|
29
|
+
- DRIVER=synchrony REDIS_BRANCH=3.2
|
30
|
+
- DRIVER=ruby REDIS_BRANCH=unstable
|
31
31
|
|
32
32
|
branches:
|
33
33
|
only:
|
34
|
+
- staging
|
35
|
+
- trying
|
34
36
|
- master
|
35
37
|
|
36
38
|
matrix:
|
37
39
|
exclude:
|
38
40
|
# hiredis
|
39
|
-
- rvm: jruby-
|
40
|
-
gemfile: .travis/Gemfile
|
41
|
-
env: conn=hiredis REDIS_BRANCH=3.0
|
42
|
-
- rvm: jruby-18mode
|
43
|
-
gemfile: .travis/Gemfile
|
44
|
-
env: conn=hiredis REDIS_BRANCH=3.2
|
45
|
-
- rvm: jruby-19mode
|
41
|
+
- rvm: jruby-9
|
46
42
|
gemfile: .travis/Gemfile
|
47
|
-
env:
|
48
|
-
- rvm: jruby-
|
43
|
+
env: DRIVER=hiredis REDIS_BRANCH=3.0
|
44
|
+
- rvm: jruby-9
|
49
45
|
gemfile: .travis/Gemfile
|
50
|
-
env:
|
51
|
-
- rvm: jruby-9
|
46
|
+
env: DRIVER=hiredis REDIS_BRANCH=3.2
|
47
|
+
- rvm: jruby-9
|
52
48
|
gemfile: .travis/Gemfile
|
53
|
-
env:
|
54
|
-
- rvm: jruby-9
|
49
|
+
env: DRIVER=hiredis REDIS_BRANCH=3.0
|
50
|
+
- rvm: jruby-9
|
55
51
|
gemfile: .travis/Gemfile
|
56
|
-
env:
|
52
|
+
env: DRIVER=hiredis REDIS_BRANCH=3.2
|
57
53
|
|
58
54
|
# synchrony
|
59
|
-
- rvm:
|
60
|
-
gemfile: .travis/Gemfile
|
61
|
-
env: conn=synchrony REDIS_BRANCH=3.0
|
62
|
-
- rvm: 1.8.7
|
63
|
-
gemfile: .travis/Gemfile
|
64
|
-
env: conn=synchrony REDIS_BRANCH=3.2
|
65
|
-
- rvm: jruby-18mode
|
66
|
-
gemfile: .travis/Gemfile
|
67
|
-
env: conn=synchrony REDIS_BRANCH=3.0
|
68
|
-
- rvm: jruby-18mode
|
69
|
-
gemfile: .travis/Gemfile
|
70
|
-
env: conn=synchrony REDIS_BRANCH=3.2
|
71
|
-
- rvm: jruby-19mode
|
55
|
+
- rvm: jruby-9
|
72
56
|
gemfile: .travis/Gemfile
|
73
|
-
env:
|
74
|
-
- rvm: jruby-
|
57
|
+
env: DRIVER=synchrony REDIS_BRANCH=3.0
|
58
|
+
- rvm: jruby-9
|
75
59
|
gemfile: .travis/Gemfile
|
76
|
-
env:
|
77
|
-
- rvm: jruby-9
|
60
|
+
env: DRIVER=synchrony REDIS_BRANCH=3.2
|
61
|
+
- rvm: jruby-9
|
78
62
|
gemfile: .travis/Gemfile
|
79
|
-
env:
|
80
|
-
- rvm: jruby-9
|
63
|
+
env: DRIVER=synchrony REDIS_BRANCH=3.0
|
64
|
+
- rvm: jruby-9
|
81
65
|
gemfile: .travis/Gemfile
|
82
|
-
env:
|
66
|
+
env: DRIVER=synchrony REDIS_BRANCH=3.2
|
83
67
|
allow_failures:
|
84
|
-
- rvm: rbx-
|
68
|
+
- rvm: rbx-3
|
85
69
|
|
86
70
|
notifications:
|
87
71
|
irc:
|
data/CHANGELOG.md
CHANGED
@@ -1,19 +1,33 @@
|
|
1
|
-
#
|
1
|
+
# 4.0.1
|
2
2
|
|
3
|
-
*
|
3
|
+
* `Redis::Distributed` now supports `mget` and `mapped_mget`. See #687.
|
4
4
|
|
5
|
-
#
|
5
|
+
* `Redis::Distributed` now supports `sscan` and `sscan_each`. See #572.
|
6
6
|
|
7
7
|
* `Redis#connection` returns a hash with connection information.
|
8
8
|
You shouldn't need to call `Redis#_client`, ever.
|
9
9
|
|
10
|
+
* `Redis#flushdb` and `Redis#flushall` now support the `:async` option. See #706.
|
11
|
+
|
12
|
+
|
13
|
+
# 4.0
|
14
|
+
|
15
|
+
* Removed `Redis.connect`. Use `Redis.new`.
|
16
|
+
|
17
|
+
* Removed `Redis#[]` and `Redis#[]=` aliases.
|
18
|
+
|
19
|
+
* Added support for `CLIENT` commands. The lower-level client can be
|
20
|
+
accessed via `Redis#_client`.
|
21
|
+
|
22
|
+
* Dropped official support for Ruby < 2.2.2.
|
23
|
+
|
10
24
|
# 3.3.3
|
11
25
|
|
12
26
|
* Improved timeout handling after dropping Timeout module.
|
13
27
|
|
14
28
|
# 3.3.2
|
15
29
|
|
16
|
-
* Added support for SPOP with COUNT. See #628.
|
30
|
+
* Added support for `SPOP` with COUNT. See #628.
|
17
31
|
|
18
32
|
* Fixed connection glitches when using SSL. See #644.
|
19
33
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,46 +1,17 @@
|
|
1
1
|
# redis-rb [![Build Status][travis-image]][travis-link] [![Inline docs][inchpages-image]][inchpages-link]
|
2
2
|
|
3
|
-
[
|
4
|
-
|
5
|
-
[travis-home]: http://travis-ci.org/
|
6
|
-
[inchpages-image]: http://inch-ci.org/github/redis/redis-rb.png
|
7
|
-
[inchpages-link]: http://inch-ci.org/github/redis/redis-rb
|
3
|
+
A Ruby client that tries to match [Redis][redis-home]' API one-to-one, while still
|
4
|
+
providing an idiomatic interface.
|
8
5
|
|
9
|
-
A Ruby client library for [Redis][redis-home].
|
10
|
-
|
11
|
-
[redis-home]: http://redis.io
|
12
|
-
|
13
|
-
A Ruby client that tries to match Redis' API one-to-one, while still
|
14
|
-
providing an idiomatic interface. It features thread-safety, client-side
|
15
|
-
sharding, pipelining, and an obsession for performance.
|
16
|
-
|
17
|
-
## Upgrading from 2.x to 3.0
|
18
|
-
|
19
|
-
Please refer to the [CHANGELOG][changelog-3.0.0] for a summary of the
|
20
|
-
most important changes, as well as a full list of changes.
|
21
|
-
|
22
|
-
[changelog-3.0.0]: https://github.com/redis/redis-rb/blob/master/CHANGELOG.md#300
|
23
6
|
|
24
7
|
## Getting started
|
25
8
|
|
26
|
-
|
27
|
-
|
28
|
-
```
|
29
|
-
gem install redis
|
30
|
-
```
|
31
|
-
|
32
|
-
Or if you are using **bundler**, add
|
9
|
+
Install with:
|
33
10
|
|
34
11
|
```
|
35
|
-
|
12
|
+
$ gem install redis
|
36
13
|
```
|
37
14
|
|
38
|
-
to your `Gemfile`, and run `bundle install`
|
39
|
-
|
40
|
-
As of version 2.0 this client only targets Redis version 2.0 and higher.
|
41
|
-
You can use an older version of this client if you need to interface
|
42
|
-
with a Redis instance older than 2.0, but this is no longer supported.
|
43
|
-
|
44
15
|
You can connect to Redis by instantiating the `Redis` class:
|
45
16
|
|
46
17
|
```ruby
|
@@ -54,17 +25,15 @@ listening on `localhost`, port 6379. If you need to connect to a remote
|
|
54
25
|
server or a different port, try:
|
55
26
|
|
56
27
|
```ruby
|
57
|
-
redis = Redis.new(:
|
28
|
+
redis = Redis.new(host: "10.0.1.1", port: 6380, db: 15)
|
58
29
|
```
|
59
30
|
|
60
31
|
You can also specify connection options as a [`redis://` URL][redis-url]:
|
61
32
|
|
62
33
|
```ruby
|
63
|
-
redis = Redis.new(:
|
34
|
+
redis = Redis.new(url: "redis://:p4ssw0rd@10.0.1.1:6380/15")
|
64
35
|
```
|
65
36
|
|
66
|
-
[redis-url]: http://www.iana.org/assignments/uri-schemes/prov/redis
|
67
|
-
|
68
37
|
By default, the client will try to read the `REDIS_URL` environment variable
|
69
38
|
and use that as URL to connect to. The above statement is therefore equivalent
|
70
39
|
to setting this environment variable and calling `Redis.new` without arguments.
|
@@ -72,13 +41,13 @@ to setting this environment variable and calling `Redis.new` without arguments.
|
|
72
41
|
To connect to Redis listening on a Unix socket, try:
|
73
42
|
|
74
43
|
```ruby
|
75
|
-
redis = Redis.new(:
|
44
|
+
redis = Redis.new(path: "/tmp/redis.sock")
|
76
45
|
```
|
77
46
|
|
78
47
|
To connect to a password protected Redis instance, use:
|
79
48
|
|
80
49
|
```ruby
|
81
|
-
redis = Redis.new(:
|
50
|
+
redis = Redis.new(password: "mysecret")
|
82
51
|
```
|
83
52
|
|
84
53
|
The Redis class exports methods that are named identical to the commands
|
@@ -86,8 +55,6 @@ they execute. The arguments these methods accept are often identical to
|
|
86
55
|
the arguments specified on the [Redis website][redis-commands]. For
|
87
56
|
instance, the `SET` and `GET` commands can be called like this:
|
88
57
|
|
89
|
-
[redis-commands]: http://redis.io/commands
|
90
|
-
|
91
58
|
```ruby
|
92
59
|
redis.set("mykey", "hello world")
|
93
60
|
# => "OK"
|
@@ -96,24 +63,22 @@ redis.get("mykey")
|
|
96
63
|
# => "hello world"
|
97
64
|
```
|
98
65
|
|
99
|
-
All commands, their arguments and return values are documented
|
100
|
-
available on [
|
101
|
-
|
102
|
-
[rdoc]: http://rdoc.info/github/redis/redis-rb/
|
66
|
+
All commands, their arguments, and return values are documented and
|
67
|
+
available on [RubyDoc.info][rubydoc].
|
103
68
|
|
104
69
|
## Sentinel support
|
105
70
|
|
106
|
-
The client is able to perform automatic
|
71
|
+
The client is able to perform automatic failover by using [Redis
|
107
72
|
Sentinel](http://redis.io/topics/sentinel). Make sure to run Redis 2.8+
|
108
73
|
if you want to use this feature.
|
109
74
|
|
110
75
|
To connect using Sentinel, use:
|
111
76
|
|
112
77
|
```ruby
|
113
|
-
SENTINELS = [{:
|
114
|
-
{:
|
78
|
+
SENTINELS = [{ host: "127.0.0.1", port: 26380 },
|
79
|
+
{ host: "127.0.0.1", port: 26381 }]
|
115
80
|
|
116
|
-
redis = Redis.new(:
|
81
|
+
redis = Redis.new(url: "redis://mymaster", sentinels: SENTINELS, role: :master)
|
117
82
|
```
|
118
83
|
|
119
84
|
* The master name identifies a group of Redis instances composed of a master
|
@@ -374,37 +339,28 @@ redis = Redis.new(:driver => :synchrony)
|
|
374
339
|
|
375
340
|
## Testing
|
376
341
|
|
377
|
-
This library is tested
|
378
|
-
|
379
|
-
|
380
|
-
* MRI 1.8.7 (drivers: ruby, hiredis)
|
381
|
-
* MRI 1.9.3 (drivers: ruby, hiredis, synchrony)
|
382
|
-
* MRI 2.0 (drivers: ruby, hiredis, synchrony)
|
383
|
-
* MRI 2.1 (drivers: ruby, hiredis, synchrony)
|
384
|
-
* MRI 2.2 (drivers: ruby, hiredis, synchrony)
|
385
|
-
* MRI 2.3 (drivers: ruby, hiredis, synchrony)
|
386
|
-
* JRuby 1.7 (1.8 mode) (drivers: ruby)
|
387
|
-
* JRuby 1.7 (1.9 mode) (drivers: ruby)
|
342
|
+
This library is tested against recent Ruby and Redis versions.
|
343
|
+
Check [Travis][travis-link] for the exact versions supported.
|
388
344
|
|
389
345
|
## Contributors
|
390
346
|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
* Taylor Weibley
|
396
|
-
* Matthew Clark
|
397
|
-
* Brian McKinney
|
398
|
-
* Luca Guidi
|
399
|
-
* Salvatore Sanfilippo
|
400
|
-
* Chris Wanstrath
|
401
|
-
* Damian Janowski
|
402
|
-
* Michel Martens
|
403
|
-
* Nick Quaranto
|
404
|
-
* Pieter Noordhuis
|
405
|
-
* Ilya Grigorik
|
347
|
+
Several people contributed to redis-rb, but we would like to especially
|
348
|
+
mention Ezra Zygmuntowicz. Ezra introduced the Ruby community to many
|
349
|
+
new cool technologies, like Redis. He wrote the first version of this
|
350
|
+
client and evangelized Redis in Rubyland. Thank you, Ezra.
|
406
351
|
|
407
352
|
## Contributing
|
408
353
|
|
409
354
|
[Fork the project](https://github.com/redis/redis-rb) and send pull
|
410
355
|
requests. You can also ask for help at `#redis-rb` on Freenode.
|
356
|
+
|
357
|
+
|
358
|
+
[inchpages-image]: https://inch-ci.org/github/redis/redis-rb.svg
|
359
|
+
[inchpages-link]: https://inch-ci.org/github/redis/redis-rb
|
360
|
+
[redis-commands]: https://redis.io/commands
|
361
|
+
[redis-home]: https://redis.io
|
362
|
+
[redis-url]: http://www.iana.org/assignments/uri-schemes/prov/redis
|
363
|
+
[travis-home]: https://travis-ci.org/
|
364
|
+
[travis-image]: https://secure.travis-ci.org/redis/redis-rb.svg?branch=master
|
365
|
+
[travis-link]: https://travis-ci.org/redis/redis-rb
|
366
|
+
[rubydoc]: http://www.rubydoc.info/gems/redis
|
data/benchmarking/logging.rb
CHANGED
data/bors.toml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Gate on Travis CI
|
2
|
+
status = ["continuous-integration/travis-ci/push"]
|
3
|
+
|
4
|
+
# Set bors's timeout to 6 hours
|
5
|
+
#
|
6
|
+
# bors's timeout should always be twice a long as the test suite takes.
|
7
|
+
# This is to allow Travis to fast-fail a test; if one of the builders
|
8
|
+
# immediately reports a failure, then bors will move on to the next batch,
|
9
|
+
# leaving the slower builders to work through the already-doomed run and
|
10
|
+
# the next one.
|
11
|
+
#
|
12
|
+
# At the time it was written, a run had taken 3 hours.
|
13
|
+
# bors's default timeout is 4 hours.
|
14
|
+
timeout_sec = 14400
|
data/lib/redis/client.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative "errors"
|
2
2
|
require "socket"
|
3
3
|
require "cgi"
|
4
4
|
|
@@ -21,9 +21,7 @@ class Redis
|
|
21
21
|
:inherit_socket => false
|
22
22
|
}
|
23
23
|
|
24
|
-
|
25
|
-
Marshal.load(Marshal.dump(@options))
|
26
|
-
end
|
24
|
+
attr_reader :options
|
27
25
|
|
28
26
|
def scheme
|
29
27
|
@options[:scheme]
|
@@ -340,6 +338,7 @@ class Redis
|
|
340
338
|
Errno::EHOSTDOWN,
|
341
339
|
Errno::EHOSTUNREACH,
|
342
340
|
Errno::ENETUNREACH,
|
341
|
+
Errno::ENOENT,
|
343
342
|
Errno::ETIMEDOUT
|
344
343
|
|
345
344
|
raise CannotConnectError, "Error connecting to Redis on #{location} (#{$!.class})"
|
@@ -478,11 +477,16 @@ class Redis
|
|
478
477
|
|
479
478
|
if driver.kind_of?(String)
|
480
479
|
begin
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
480
|
+
require_relative "connection/#{driver}"
|
481
|
+
rescue LoadError, NameError => e
|
482
|
+
begin
|
483
|
+
require "connection/#{driver}"
|
484
|
+
rescue LoadError, NameError => e
|
485
|
+
raise RuntimeError, "Cannot load driver #{driver.inspect}: #{e.message}"
|
486
|
+
end
|
485
487
|
end
|
488
|
+
|
489
|
+
driver = Connection.const_get(driver.capitalize)
|
486
490
|
end
|
487
491
|
|
488
492
|
driver
|
@@ -30,14 +30,8 @@ class Redis
|
|
30
30
|
|
31
31
|
protected
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
string.force_encoding(Encoding::default_external)
|
36
|
-
end
|
37
|
-
else
|
38
|
-
def encode(string)
|
39
|
-
string
|
40
|
-
end
|
33
|
+
def encode(string)
|
34
|
+
string.force_encoding(Encoding.default_external)
|
41
35
|
end
|
42
36
|
end
|
43
37
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative "registry"
|
2
|
+
require_relative "command_helper"
|
3
|
+
require_relative "../errors"
|
4
4
|
require "socket"
|
5
5
|
require "timeout"
|
6
6
|
|
@@ -10,36 +10,17 @@ rescue LoadError
|
|
10
10
|
# Not all systems have OpenSSL support
|
11
11
|
end
|
12
12
|
|
13
|
-
if RUBY_VERSION < "1.9.3"
|
14
|
-
class String
|
15
|
-
# Ruby 1.8.7 does not have byteslice, but it handles encodings differently anyway.
|
16
|
-
# We can simply slice the string, which is a byte array there.
|
17
|
-
def byteslice(*args)
|
18
|
-
slice(*args)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
13
|
class Redis
|
24
14
|
module Connection
|
25
15
|
module SocketMixin
|
26
16
|
|
27
17
|
CRLF = "\r\n".freeze
|
28
18
|
|
29
|
-
# Exceptions raised during non-blocking I/O ops that require retrying the op
|
30
|
-
if RUBY_VERSION >= "1.9.3"
|
31
|
-
NBIO_READ_EXCEPTIONS = [IO::WaitReadable]
|
32
|
-
NBIO_WRITE_EXCEPTIONS = [IO::WaitWritable]
|
33
|
-
else
|
34
|
-
NBIO_READ_EXCEPTIONS = [Errno::EWOULDBLOCK, Errno::EAGAIN]
|
35
|
-
NBIO_WRITE_EXCEPTIONS = [Errno::EWOULDBLOCK, Errno::EAGAIN]
|
36
|
-
end
|
37
|
-
|
38
19
|
def initialize(*args)
|
39
20
|
super(*args)
|
40
21
|
|
41
22
|
@timeout = @write_timeout = nil
|
42
|
-
@buffer = ""
|
23
|
+
@buffer = "".dup
|
43
24
|
end
|
44
25
|
|
45
26
|
def timeout=(timeout)
|
@@ -83,13 +64,13 @@ class Redis
|
|
83
64
|
begin
|
84
65
|
read_nonblock(nbytes)
|
85
66
|
|
86
|
-
rescue
|
67
|
+
rescue IO::WaitReadable
|
87
68
|
if IO.select([self], nil, nil, @timeout)
|
88
69
|
retry
|
89
70
|
else
|
90
71
|
raise Redis::TimeoutError
|
91
72
|
end
|
92
|
-
rescue
|
73
|
+
rescue IO::WaitWritable
|
93
74
|
if IO.select(nil, [self], nil, @timeout)
|
94
75
|
retry
|
95
76
|
else
|
@@ -105,13 +86,13 @@ class Redis
|
|
105
86
|
begin
|
106
87
|
write_nonblock(data)
|
107
88
|
|
108
|
-
rescue
|
89
|
+
rescue IO::WaitWritable
|
109
90
|
if IO.select(nil, [self], nil, @write_timeout)
|
110
91
|
retry
|
111
92
|
else
|
112
93
|
raise Redis::TimeoutError
|
113
94
|
end
|
114
|
-
rescue
|
95
|
+
rescue IO::WaitReadable
|
115
96
|
if IO.select([self], nil, nil, @write_timeout)
|
116
97
|
retry
|
117
98
|
else
|
@@ -307,7 +288,6 @@ class Redis
|
|
307
288
|
raise ArgumentError, "SSL incompatible with unix sockets" if config[:ssl]
|
308
289
|
sock = UNIXSocket.connect(config[:path], config[:connect_timeout])
|
309
290
|
elsif config[:scheme] == "rediss" || config[:ssl]
|
310
|
-
raise ArgumentError, "This library does not support SSL on Ruby < 1.9" if RUBY_VERSION < "1.9.3"
|
311
291
|
sock = SSLSocket.connect(config[:host], config[:port], config[:connect_timeout], config[:ssl_params])
|
312
292
|
else
|
313
293
|
sock = TCPSocket.connect(config[:host], config[:port], config[:connect_timeout])
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative "command_helper"
|
2
|
+
require_relative "registry"
|
3
|
+
require_relative "../errors"
|
4
4
|
require "em-synchrony"
|
5
5
|
require "hiredis/reader"
|
6
6
|
|
@@ -72,7 +72,15 @@ class Redis
|
|
72
72
|
|
73
73
|
def self.connect(config)
|
74
74
|
if config[:scheme] == "unix"
|
75
|
-
|
75
|
+
begin
|
76
|
+
conn = EventMachine.connect_unix_domain(config[:path], RedisClient)
|
77
|
+
rescue RuntimeError => e
|
78
|
+
if e.message == "no connection"
|
79
|
+
raise Errno::ECONNREFUSED
|
80
|
+
else
|
81
|
+
raise e
|
82
|
+
end
|
83
|
+
end
|
76
84
|
elsif config[:scheme] == "rediss" || config[:ssl]
|
77
85
|
raise NotImplementedError, "SSL not supported by synchrony driver"
|
78
86
|
else
|
data/lib/redis/connection.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative "connection/registry"
|
2
2
|
|
3
3
|
# If a connection driver was required before this file, the array
|
4
4
|
# Redis::Connection.drivers will contain one or more classes. The last driver
|
@@ -6,4 +6,4 @@ require "redis/connection/registry"
|
|
6
6
|
# the plain Ruby driver as our default. Another driver can be required at a
|
7
7
|
# later point in time, causing it to be the last element of the #drivers array
|
8
8
|
# and therefore be chosen by default.
|
9
|
-
|
9
|
+
require_relative "connection/ruby" if Redis::Connection.drivers.empty?
|
data/lib/redis/distributed.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative "hash_ring"
|
2
2
|
|
3
3
|
class Redis
|
4
4
|
class Distributed
|
@@ -144,8 +144,8 @@ class Redis
|
|
144
144
|
end
|
145
145
|
|
146
146
|
# Create a key using the serialized value, previously obtained using DUMP.
|
147
|
-
def restore(key, ttl, serialized_value)
|
148
|
-
node_for(key).restore(key, ttl, serialized_value)
|
147
|
+
def restore(key, ttl, serialized_value, options = {})
|
148
|
+
node_for(key).restore(key, ttl, serialized_value, options)
|
149
149
|
end
|
150
150
|
|
151
151
|
# Transfer a key from the connected instance to another instance.
|
@@ -277,13 +277,16 @@ class Redis
|
|
277
277
|
node_for(key).get(key)
|
278
278
|
end
|
279
279
|
|
280
|
-
# Get the values of all the given keys.
|
280
|
+
# Get the values of all the given keys as an Array.
|
281
281
|
def mget(*keys)
|
282
|
-
|
282
|
+
mapped_mget(*keys).values_at(*keys)
|
283
283
|
end
|
284
284
|
|
285
|
+
# Get the values of all the given keys as a Hash.
|
285
286
|
def mapped_mget(*keys)
|
286
|
-
|
287
|
+
keys.group_by { |k| node_for k }.inject({}) do |results, (node, subkeys)|
|
288
|
+
results.merge! node.mapped_mget(*subkeys)
|
289
|
+
end
|
287
290
|
end
|
288
291
|
|
289
292
|
# Overwrite part of a string at key starting at the specified offset.
|
@@ -509,6 +512,16 @@ class Redis
|
|
509
512
|
node_for(key).smembers(key)
|
510
513
|
end
|
511
514
|
|
515
|
+
# Scan a set
|
516
|
+
def sscan(key, cursor, options={})
|
517
|
+
node_for(key).sscan(key, cursor, options)
|
518
|
+
end
|
519
|
+
|
520
|
+
# Scan a set and return an enumerator
|
521
|
+
def sscan_each(key, options={}, &block)
|
522
|
+
node_for(key).sscan_each(key, options, &block)
|
523
|
+
end
|
524
|
+
|
512
525
|
# Subtract multiple sets.
|
513
526
|
def sdiff(*keys)
|
514
527
|
ensure_same_node(:sdiff, keys) do |node|
|