redis 3.3.5 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.travis/Gemfile +3 -1
  3. data/.travis.yml +36 -52
  4. data/CHANGELOG.md +18 -4
  5. data/Gemfile +0 -1
  6. data/README.md +31 -75
  7. data/benchmarking/logging.rb +1 -1
  8. data/bors.toml +14 -0
  9. data/lib/redis/client.rb +12 -8
  10. data/lib/redis/connection/command_helper.rb +2 -8
  11. data/lib/redis/connection/hiredis.rb +2 -2
  12. data/lib/redis/connection/ruby.rb +8 -28
  13. data/lib/redis/connection/synchrony.rb +12 -4
  14. data/lib/redis/connection.rb +2 -2
  15. data/lib/redis/distributed.rb +19 -6
  16. data/lib/redis/hash_ring.rb +20 -64
  17. data/lib/redis/pipeline.rb +0 -6
  18. data/lib/redis/version.rb +1 -1
  19. data/lib/redis.rb +89 -40
  20. data/makefile +42 -0
  21. data/redis.gemspec +7 -9
  22. data/test/bitpos_test.rb +13 -19
  23. data/test/blocking_commands_test.rb +3 -5
  24. data/test/client_test.rb +1 -1
  25. data/test/command_map_test.rb +3 -5
  26. data/test/commands_on_hashes_test.rb +2 -4
  27. data/test/commands_on_hyper_log_log_test.rb +3 -5
  28. data/test/commands_on_lists_test.rb +2 -4
  29. data/test/commands_on_sets_test.rb +2 -4
  30. data/test/commands_on_sorted_sets_test.rb +17 -4
  31. data/test/commands_on_strings_test.rb +3 -5
  32. data/test/commands_on_value_types_test.rb +44 -6
  33. data/test/connection_handling_test.rb +5 -7
  34. data/test/distributed_blocking_commands_test.rb +2 -4
  35. data/test/distributed_commands_on_hashes_test.rb +2 -4
  36. data/test/distributed_commands_on_hyper_log_log_test.rb +2 -4
  37. data/test/distributed_commands_on_lists_test.rb +2 -4
  38. data/test/distributed_commands_on_sets_test.rb +27 -4
  39. data/test/distributed_commands_on_sorted_sets_test.rb +2 -4
  40. data/test/distributed_commands_on_strings_test.rb +20 -10
  41. data/test/distributed_commands_on_value_types_test.rb +2 -4
  42. data/test/distributed_commands_requiring_clustering_test.rb +1 -3
  43. data/test/distributed_connection_handling_test.rb +1 -3
  44. data/test/distributed_internals_test.rb +8 -19
  45. data/test/distributed_key_tags_test.rb +4 -6
  46. data/test/distributed_persistence_control_commands_test.rb +1 -3
  47. data/test/distributed_publish_subscribe_test.rb +1 -3
  48. data/test/distributed_remote_server_control_commands_test.rb +1 -3
  49. data/test/distributed_scripting_test.rb +1 -3
  50. data/test/distributed_sorting_test.rb +1 -3
  51. data/test/distributed_test.rb +12 -14
  52. data/test/distributed_transactions_test.rb +1 -3
  53. data/test/encoding_test.rb +4 -8
  54. data/test/error_replies_test.rb +2 -4
  55. data/test/fork_safety_test.rb +1 -6
  56. data/test/helper.rb +10 -41
  57. data/test/helper_test.rb +1 -3
  58. data/test/internals_test.rb +27 -55
  59. data/test/lint/strings.rb +6 -20
  60. data/test/lint/value_types.rb +8 -0
  61. data/test/persistence_control_commands_test.rb +1 -3
  62. data/test/pipelining_commands_test.rb +4 -8
  63. data/test/publish_subscribe_test.rb +1 -3
  64. data/test/remote_server_control_commands_test.rb +60 -3
  65. data/test/scanning_test.rb +1 -7
  66. data/test/scripting_test.rb +1 -3
  67. data/test/sentinel_command_test.rb +1 -3
  68. data/test/sentinel_test.rb +1 -3
  69. data/test/sorting_test.rb +1 -3
  70. data/test/ssl_test.rb +45 -49
  71. data/test/support/connection/hiredis.rb +1 -1
  72. data/test/support/connection/ruby.rb +1 -1
  73. data/test/support/connection/synchrony.rb +1 -1
  74. data/test/synchrony_driver.rb +6 -9
  75. data/test/thread_safety_test.rb +1 -3
  76. data/test/transactions_test.rb +1 -3
  77. data/test/unknown_commands_test.rb +1 -3
  78. data/test/url_param_test.rb +44 -46
  79. metadata +29 -15
  80. data/Rakefile +0 -87
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 729f56810aa501065e2fc203050363713c80ee37
4
- data.tar.gz: e7e13fb75618f794a2c742d73d6c8a72699d5e92
3
+ metadata.gz: 7e0d0ba2328aca583c0f487729779c2b10b12c7b
4
+ data.tar.gz: 4a411cfa3512bafe7c2c12ac8a02c02bc87065aa
5
5
  SHA512:
6
- metadata.gz: f87e76c751760b7f1feb7c859ea373c41ebf805c104c27e85177cb20a60d42b11c50db2d5a916fb7bfc78b82b13141770a851568aea922ccc1970f4e30ba1dea
7
- data.tar.gz: ac4cb236c9c9897d73ead9421e161cf1c7aac2a3c1f77c088b5c52c324cddccda6ab749441093cbcc94ea812e70232f9f9ac1c160a96fd1fbd46d87586d1d7fb
6
+ metadata.gz: 3af7dc63dc7bdc243da306817583db9b6989c21a0714c6652b4a443bfd9c46b2afba0707b028d708a74148bbeedd09d4ec207a0459b3559cb19b95f2f030bb07
7
+ data.tar.gz: 98d5aed456ebcd3ccdc50980879a3c14be4c8a1874c6febae95579d2fb3828bda2e82b05e62dc6a4966e178993d4a2a20dc3dedd9f8583cd731851eab2f8e164
data/.travis/Gemfile CHANGED
@@ -2,10 +2,12 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec :path => "../"
4
4
 
5
- case ENV["conn"]
5
+ case ENV["DRIVER"]
6
6
  when "hiredis"
7
7
  gem "hiredis"
8
8
  when "synchrony"
9
9
  gem "hiredis"
10
10
  gem "em-synchrony"
11
11
  end
12
+
13
+ gem 'test-unit', '>= 3.2.5'
data/.travis.yml CHANGED
@@ -1,87 +1,71 @@
1
1
  language: ruby
2
2
 
3
+ script: make test
4
+
3
5
  rvm:
4
- - 1.8.7
5
- - 1.9.3
6
- - 2.0
7
- - 2.1
8
- - 2.2
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
- - conn=ruby REDIS_BRANCH=3.0
25
- - conn=ruby REDIS_BRANCH=3.2
26
- - conn=hiredis REDIS_BRANCH=3.0
27
- - conn=hiredis REDIS_BRANCH=3.2
28
- - conn=synchrony REDIS_BRANCH=3.0
29
- - conn=synchrony REDIS_BRANCH=3.2
30
- - conn=ruby REDIS_BRANCH=unstable
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-18mode
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: conn=hiredis REDIS_BRANCH=3.0
48
- - rvm: jruby-19mode
43
+ env: DRIVER=hiredis REDIS_BRANCH=3.0
44
+ - rvm: jruby-9
49
45
  gemfile: .travis/Gemfile
50
- env: conn=hiredis REDIS_BRANCH=3.2
51
- - rvm: jruby-9.0.5.0
46
+ env: DRIVER=hiredis REDIS_BRANCH=3.2
47
+ - rvm: jruby-9
52
48
  gemfile: .travis/Gemfile
53
- env: conn=hiredis REDIS_BRANCH=3.0
54
- - rvm: jruby-9.0.5.0
49
+ env: DRIVER=hiredis REDIS_BRANCH=3.0
50
+ - rvm: jruby-9
55
51
  gemfile: .travis/Gemfile
56
- env: conn=hiredis REDIS_BRANCH=3.2
52
+ env: DRIVER=hiredis REDIS_BRANCH=3.2
57
53
 
58
54
  # synchrony
59
- - rvm: 1.8.7
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: conn=synchrony REDIS_BRANCH=3.0
74
- - rvm: jruby-19mode
57
+ env: DRIVER=synchrony REDIS_BRANCH=3.0
58
+ - rvm: jruby-9
75
59
  gemfile: .travis/Gemfile
76
- env: conn=synchrony REDIS_BRANCH=3.2
77
- - rvm: jruby-9.0.5.0
60
+ env: DRIVER=synchrony REDIS_BRANCH=3.2
61
+ - rvm: jruby-9
78
62
  gemfile: .travis/Gemfile
79
- env: conn=synchrony REDIS_BRANCH=3.0
80
- - rvm: jruby-9.0.5.0
63
+ env: DRIVER=synchrony REDIS_BRANCH=3.0
64
+ - rvm: jruby-9
81
65
  gemfile: .travis/Gemfile
82
- env: conn=synchrony REDIS_BRANCH=3.2
66
+ env: DRIVER=synchrony REDIS_BRANCH=3.2
83
67
  allow_failures:
84
- - rvm: rbx-2
68
+ - rvm: rbx-3
85
69
 
86
70
  notifications:
87
71
  irc:
data/CHANGELOG.md CHANGED
@@ -1,19 +1,33 @@
1
- # 3.3.5
1
+ # 4.0.1
2
2
 
3
- * Fixed Ruby 1.8 compatibility after backporting `Redis#connection`. See #719.
3
+ * `Redis::Distributed` now supports `mget` and `mapped_mget`. See #687.
4
4
 
5
- # 3.3.4
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
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  source 'https://rubygems.org'
3
2
 
4
3
  gemspec
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
- [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/
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
- To install **redis-rb**, run the following command:
27
-
28
- ```
29
- gem install redis
30
- ```
31
-
32
- Or if you are using **bundler**, add
9
+ Install with:
33
10
 
34
11
  ```
35
- gem 'redis', '~>3.2'
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(:host => "10.0.1.1", :port => 6380, :db => 15)
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(:url => "redis://:p4ssw0rd@10.0.1.1:6380/15")
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(:path => "/tmp/redis.sock")
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(:password => "mysecret")
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, and
100
- available on [rdoc.info][rdoc].
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 failovers by using [Redis
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 = [{:host => "127.0.0.1", :port => 26380},
114
- {:host => "127.0.0.1", :port => 26381}]
78
+ SENTINELS = [{ host: "127.0.0.1", port: 26380 },
79
+ { host: "127.0.0.1", port: 26381 }]
115
80
 
116
- redis = Redis.new(:url => "redis://mymaster", :sentinels => SENTINELS, :role => :master)
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 using [Travis][travis-home], where it is tested
378
- against the following interpreters and drivers:
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
- (ordered chronologically with more than 5 commits, see `git shortlog -sn` for
392
- all contributors)
393
-
394
- * Ezra Zygmuntowicz
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
@@ -54,7 +54,7 @@ benchmark "Default options (no logger)" do
54
54
  end
55
55
 
56
56
  logging_redises.each do |redis|
57
- logger = redis.client.logger
57
+ logger = redis._client.logger
58
58
 
59
59
  case logger
60
60
  when Logger
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
- require "redis/errors"
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
- def options
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
- require "redis/connection/#{driver}"
482
- driver = Connection.const_get(driver.capitalize)
483
- rescue LoadError, NameError
484
- raise RuntimeError, "Cannot load driver #{driver.inspect}"
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
- if defined?(Encoding::default_external)
34
- def encode(string)
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,5 +1,5 @@
1
- require "redis/connection/registry"
2
- require "redis/errors"
1
+ require_relative "registry"
2
+ require_relative "../errors"
3
3
  require "hiredis/connection"
4
4
  require "timeout"
5
5
 
@@ -1,6 +1,6 @@
1
- require "redis/connection/registry"
2
- require "redis/connection/command_helper"
3
- require "redis/errors"
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 *NBIO_READ_EXCEPTIONS
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 *NBIO_WRITE_EXCEPTIONS
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 *NBIO_WRITE_EXCEPTIONS
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 *NBIO_READ_EXCEPTIONS
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
- require "redis/connection/command_helper"
2
- require "redis/connection/registry"
3
- require "redis/errors"
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
- conn = EventMachine.connect_unix_domain(config[:path], RedisClient)
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
@@ -1,4 +1,4 @@
1
- require "redis/connection/registry"
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
- require "redis/connection/ruby" if Redis::Connection.drivers.empty?
9
+ require_relative "connection/ruby" if Redis::Connection.drivers.empty?
@@ -1,4 +1,4 @@
1
- require "redis/hash_ring"
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
- raise CannotDistribute, :mget
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
- raise CannotDistribute, :mapped_mget
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|