redis 3.3.5 → 4.0.3

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.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis/Gemfile +8 -1
  4. data/.travis.yml +34 -62
  5. data/CHANGELOG.md +45 -2
  6. data/Gemfile +5 -1
  7. data/README.md +32 -76
  8. data/benchmarking/logging.rb +1 -1
  9. data/bin/build +71 -0
  10. data/bors.toml +14 -0
  11. data/lib/redis/client.rb +38 -20
  12. data/lib/redis/cluster/command.rb +81 -0
  13. data/lib/redis/cluster/command_loader.rb +32 -0
  14. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  15. data/lib/redis/cluster/node.rb +104 -0
  16. data/lib/redis/cluster/node_key.rb +35 -0
  17. data/lib/redis/cluster/node_loader.rb +35 -0
  18. data/lib/redis/cluster/option.rb +76 -0
  19. data/lib/redis/cluster/slot.rb +69 -0
  20. data/lib/redis/cluster/slot_loader.rb +47 -0
  21. data/lib/redis/cluster.rb +285 -0
  22. data/lib/redis/connection/command_helper.rb +2 -8
  23. data/lib/redis/connection/hiredis.rb +2 -2
  24. data/lib/redis/connection/ruby.rb +13 -30
  25. data/lib/redis/connection/synchrony.rb +12 -4
  26. data/lib/redis/connection.rb +2 -2
  27. data/lib/redis/distributed.rb +29 -8
  28. data/lib/redis/errors.rb +46 -0
  29. data/lib/redis/hash_ring.rb +20 -64
  30. data/lib/redis/pipeline.rb +9 -7
  31. data/lib/redis/version.rb +1 -1
  32. data/lib/redis.rb +287 -52
  33. data/makefile +74 -0
  34. data/redis.gemspec +9 -10
  35. data/test/bitpos_test.rb +13 -19
  36. data/test/blocking_commands_test.rb +3 -5
  37. data/test/client_test.rb +18 -1
  38. data/test/cluster_abnormal_state_test.rb +38 -0
  39. data/test/cluster_blocking_commands_test.rb +15 -0
  40. data/test/cluster_client_internals_test.rb +77 -0
  41. data/test/cluster_client_key_hash_tags_test.rb +88 -0
  42. data/test/cluster_client_options_test.rb +147 -0
  43. data/test/cluster_client_pipelining_test.rb +59 -0
  44. data/test/cluster_client_replicas_test.rb +36 -0
  45. data/test/cluster_client_slots_test.rb +94 -0
  46. data/test/cluster_client_transactions_test.rb +71 -0
  47. data/test/cluster_commands_on_cluster_test.rb +165 -0
  48. data/test/cluster_commands_on_connection_test.rb +40 -0
  49. data/test/cluster_commands_on_geo_test.rb +74 -0
  50. data/test/cluster_commands_on_hashes_test.rb +11 -0
  51. data/test/cluster_commands_on_hyper_log_log_test.rb +17 -0
  52. data/test/cluster_commands_on_keys_test.rb +134 -0
  53. data/test/cluster_commands_on_lists_test.rb +15 -0
  54. data/test/cluster_commands_on_pub_sub_test.rb +101 -0
  55. data/test/cluster_commands_on_scripting_test.rb +56 -0
  56. data/test/cluster_commands_on_server_test.rb +221 -0
  57. data/test/cluster_commands_on_sets_test.rb +39 -0
  58. data/test/cluster_commands_on_sorted_sets_test.rb +35 -0
  59. data/test/cluster_commands_on_streams_test.rb +196 -0
  60. data/test/cluster_commands_on_strings_test.rb +15 -0
  61. data/test/cluster_commands_on_transactions_test.rb +41 -0
  62. data/test/cluster_commands_on_value_types_test.rb +14 -0
  63. data/test/command_map_test.rb +3 -5
  64. data/test/commands_on_geo_test.rb +116 -0
  65. data/test/commands_on_hashes_test.rb +2 -16
  66. data/test/commands_on_hyper_log_log_test.rb +3 -17
  67. data/test/commands_on_lists_test.rb +2 -15
  68. data/test/commands_on_sets_test.rb +2 -72
  69. data/test/commands_on_sorted_sets_test.rb +2 -132
  70. data/test/commands_on_strings_test.rb +2 -96
  71. data/test/commands_on_value_types_test.rb +80 -6
  72. data/test/connection_handling_test.rb +5 -7
  73. data/test/distributed_blocking_commands_test.rb +10 -4
  74. data/test/distributed_commands_on_hashes_test.rb +16 -5
  75. data/test/distributed_commands_on_hyper_log_log_test.rb +8 -15
  76. data/test/distributed_commands_on_lists_test.rb +4 -7
  77. data/test/distributed_commands_on_sets_test.rb +58 -36
  78. data/test/distributed_commands_on_sorted_sets_test.rb +51 -10
  79. data/test/distributed_commands_on_strings_test.rb +30 -10
  80. data/test/distributed_commands_on_value_types_test.rb +38 -4
  81. data/test/distributed_commands_requiring_clustering_test.rb +1 -3
  82. data/test/distributed_connection_handling_test.rb +1 -3
  83. data/test/distributed_internals_test.rb +8 -19
  84. data/test/distributed_key_tags_test.rb +4 -6
  85. data/test/distributed_persistence_control_commands_test.rb +1 -3
  86. data/test/distributed_publish_subscribe_test.rb +1 -3
  87. data/test/distributed_remote_server_control_commands_test.rb +1 -3
  88. data/test/distributed_scripting_test.rb +1 -3
  89. data/test/distributed_sorting_test.rb +1 -3
  90. data/test/distributed_test.rb +12 -14
  91. data/test/distributed_transactions_test.rb +1 -3
  92. data/test/encoding_test.rb +4 -8
  93. data/test/error_replies_test.rb +2 -4
  94. data/test/fork_safety_test.rb +1 -6
  95. data/test/helper.rb +179 -66
  96. data/test/helper_test.rb +1 -3
  97. data/test/internals_test.rb +47 -56
  98. data/test/lint/blocking_commands.rb +40 -16
  99. data/test/lint/hashes.rb +41 -0
  100. data/test/lint/hyper_log_log.rb +15 -1
  101. data/test/lint/lists.rb +16 -0
  102. data/test/lint/sets.rb +142 -0
  103. data/test/lint/sorted_sets.rb +183 -2
  104. data/test/lint/strings.rb +108 -20
  105. data/test/lint/value_types.rb +8 -0
  106. data/test/persistence_control_commands_test.rb +1 -3
  107. data/test/pipelining_commands_test.rb +12 -8
  108. data/test/publish_subscribe_test.rb +1 -3
  109. data/test/remote_server_control_commands_test.rb +60 -3
  110. data/test/scanning_test.rb +1 -7
  111. data/test/scripting_test.rb +1 -3
  112. data/test/sentinel_command_test.rb +1 -3
  113. data/test/sentinel_test.rb +1 -3
  114. data/test/sorting_test.rb +1 -3
  115. data/test/ssl_test.rb +45 -49
  116. data/test/support/cluster/orchestrator.rb +199 -0
  117. data/test/support/connection/hiredis.rb +1 -1
  118. data/test/support/connection/ruby.rb +1 -1
  119. data/test/support/connection/synchrony.rb +1 -1
  120. data/test/support/redis_mock.rb +1 -1
  121. data/test/synchrony_driver.rb +6 -9
  122. data/test/thread_safety_test.rb +1 -3
  123. data/test/transactions_test.rb +11 -3
  124. data/test/unknown_commands_test.rb +1 -3
  125. data/test/url_param_test.rb +44 -46
  126. metadata +109 -16
  127. 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: 1ec178932a6874e8ac7a4f6cfa4390c8223367ec
4
+ data.tar.gz: 986e6c5d1729b9ec8f7d66900e5d9ad9437e29f9
5
5
  SHA512:
6
- metadata.gz: f87e76c751760b7f1feb7c859ea373c41ebf805c104c27e85177cb20a60d42b11c50db2d5a916fb7bfc78b82b13141770a851568aea922ccc1970f4e30ba1dea
7
- data.tar.gz: ac4cb236c9c9897d73ead9421e161cf1c7aac2a3c1f77c088b5c52c324cddccda6ab749441093cbcc94ea812e70232f9f9ac1c160a96fd1fbd46d87586d1d7fb
6
+ metadata.gz: 14db8cb42f08014ebd942c39b5f119a68a8ec50fec046572bb3afc7708634589311b9bea0d4153bfd1d7cb1c46a94a00d77613872b2cb8c10c33f132755cd62d
7
+ data.tar.gz: efe0db683450fcb30b6d23b8c9448d6925b5c5d95b847f9563405a61cc7e667bbf8aea22642dcc9d8a1b716dc9c8cb55c562c86a08223e020991f69eff7df7f7
data/.gitignore CHANGED
@@ -5,6 +5,7 @@ Gemfile.lock
5
5
  /tmp/
6
6
  /.idea
7
7
  /.yardoc
8
+ /.bundle
8
9
  /coverage/*
9
10
  /doc/
10
11
  /examples/sentinel/sentinel.conf
@@ -14,3 +15,5 @@ Gemfile.lock
14
15
  /redis/*
15
16
  /test/db
16
17
  /test/test.conf
18
+ appendonly.aof
19
+ temp-rewriteaof-*.aof
data/.travis/Gemfile CHANGED
@@ -2,10 +2,17 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec :path => "../"
4
4
 
5
- case ENV["conn"]
5
+ # Using jruby-openssl 0.10.0, we get NPEs in jruby tests: https://github.com/redis/redis-rb/issues/756
6
+ platform :jruby do
7
+ gem 'jruby-openssl', '<0.10.0'
8
+ end
9
+
10
+ case ENV["DRIVER"]
6
11
  when "hiredis"
7
12
  gem "hiredis"
8
13
  when "synchrony"
9
14
  gem "hiredis"
10
15
  gem "em-synchrony"
11
16
  end
17
+
18
+ gem 'test-unit', '>= 3.2.5'
data/.travis.yml CHANGED
@@ -1,87 +1,59 @@
1
1
  language: ruby
2
+ cache:
3
+ directories:
4
+ - tmp/cache
5
+ before_install:
6
+ - gem update --system 2.6.14
7
+ - gem --version
8
+
9
+ script: make
2
10
 
3
11
  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
12
+ - 2.2.2
13
+ - 2.3.3
14
+ - 2.4.1
15
+ - 2.5.0
16
+ - jruby-9.1.17.0
14
17
 
15
18
  gemfile: ".travis/Gemfile"
16
19
 
17
20
  sudo: false
18
21
 
22
+ before_script:
23
+ - if (ruby -e "exit RUBY_VERSION.to_f >= 2.4"); then export RUBYOPT="--enable-frozen-string-literal"; fi; echo $RUBYOPT
24
+
19
25
  env:
20
26
  global:
21
27
  - VERBOSE=true
22
- - TIMEOUT=1
28
+ - TIMEOUT=9
23
29
  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
30
+ - DRIVER=ruby REDIS_BRANCH=3.0
31
+ - DRIVER=ruby REDIS_BRANCH=3.2
32
+ - DRIVER=hiredis REDIS_BRANCH=3.0
33
+ - DRIVER=hiredis REDIS_BRANCH=3.2
34
+ - DRIVER=synchrony REDIS_BRANCH=3.0
35
+ - DRIVER=synchrony REDIS_BRANCH=3.2
36
+ - DRIVER=ruby REDIS_BRANCH=4.0
31
37
 
32
38
  branches:
33
39
  only:
40
+ - staging
41
+ - trying
34
42
  - master
35
43
 
36
44
  matrix:
37
45
  exclude:
38
46
  # 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
46
- gemfile: .travis/Gemfile
47
- env: conn=hiredis REDIS_BRANCH=3.0
48
- - rvm: jruby-19mode
49
- gemfile: .travis/Gemfile
50
- env: conn=hiredis REDIS_BRANCH=3.2
51
- - rvm: jruby-9.0.5.0
52
- gemfile: .travis/Gemfile
53
- env: conn=hiredis REDIS_BRANCH=3.0
54
- - rvm: jruby-9.0.5.0
55
- gemfile: .travis/Gemfile
56
- env: conn=hiredis REDIS_BRANCH=3.2
47
+ - rvm: jruby-9.1.17.0
48
+ env: DRIVER=hiredis REDIS_BRANCH=3.0
49
+ - rvm: jruby-9.1.17.0
50
+ env: DRIVER=hiredis REDIS_BRANCH=3.2
57
51
 
58
52
  # 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
72
- gemfile: .travis/Gemfile
73
- env: conn=synchrony REDIS_BRANCH=3.0
74
- - rvm: jruby-19mode
75
- gemfile: .travis/Gemfile
76
- env: conn=synchrony REDIS_BRANCH=3.2
77
- - rvm: jruby-9.0.5.0
78
- gemfile: .travis/Gemfile
79
- env: conn=synchrony REDIS_BRANCH=3.0
80
- - rvm: jruby-9.0.5.0
81
- gemfile: .travis/Gemfile
82
- env: conn=synchrony REDIS_BRANCH=3.2
83
- allow_failures:
84
- - rvm: rbx-2
53
+ - rvm: jruby-9.1.17.0
54
+ env: DRIVER=synchrony REDIS_BRANCH=3.0
55
+ - rvm: jruby-9.1.17.0
56
+ env: DRIVER=synchrony REDIS_BRANCH=3.2
85
57
 
86
58
  notifications:
87
59
  irc:
data/CHANGELOG.md CHANGED
@@ -1,8 +1,51 @@
1
+ # 4.0.3
2
+
3
+ * Fix raising command error for first command in pipeline. See #788.
4
+ * Fix the gemspec to stop exposing a `build` executable. See #785.
5
+ * Add `:reconnect_delay` and `:reconnect_delay_max` options. See #778.
6
+
7
+ # 4.0.2
8
+
9
+ * Added `Redis#unlink`. See #766.
10
+
11
+ * `Redis.new` now accept a custom connector via `:connector`. See #591.
12
+
13
+ * `Redis#multi` no longer perform empty transactions. See #747.
14
+
15
+ * `Redis#hdel` now accepts hash keys as multiple arguments like `#del`. See #755.
16
+
17
+ * Allow to skip SSL verification. See #745.
18
+
19
+ * Add Geo commands: `geoadd`, `geohash`, `georadius`, `georadiusbymember`, `geopos`, `geodist`. See #730.
20
+
21
+ # 4.0.1
22
+
23
+ * `Redis::Distributed` now supports `mget` and `mapped_mget`. See #687.
24
+
25
+ * `Redis::Distributed` now supports `sscan` and `sscan_each`. See #572.
26
+
27
+ * `Redis#connection` returns a hash with connection information.
28
+ You shouldn't need to call `Redis#_client`, ever.
29
+
30
+ * `Redis#flushdb` and `Redis#flushall` now support the `:async` option. See #706.
31
+
32
+
33
+ # 4.0
34
+
35
+ * Removed `Redis.connect`. Use `Redis.new`.
36
+
37
+ * Removed `Redis#[]` and `Redis#[]=` aliases.
38
+
39
+ * Added support for `CLIENT` commands. The lower-level client can be
40
+ accessed via `Redis#_client`.
41
+
42
+ * Dropped official support for Ruby < 2.2.2.
43
+
1
44
  # 3.3.5
2
45
 
3
46
  * Fixed Ruby 1.8 compatibility after backporting `Redis#connection`. See #719.
4
47
 
5
- # 3.3.4
48
+ # 3.3.4 (yanked)
6
49
 
7
50
  * `Redis#connection` returns a hash with connection information.
8
51
  You shouldn't need to call `Redis#_client`, ever.
@@ -13,7 +56,7 @@
13
56
 
14
57
  # 3.3.2
15
58
 
16
- * Added support for SPOP with COUNT. See #628.
59
+ * Added support for `SPOP` with COUNT. See #628.
17
60
 
18
61
  * Fixed connection glitches when using SSL. See #644.
19
62
 
data/Gemfile CHANGED
@@ -1,4 +1,8 @@
1
- # encoding: utf-8
2
1
  source 'https://rubygems.org'
3
2
 
4
3
  gemspec
4
+
5
+ # Using jruby-openssl 0.10.0, we get NPEs in jruby tests: https://github.com/redis/redis-rb/issues/756
6
+ platform :jruby do
7
+ gem 'jruby-openssl', '<0.10.0'
8
+ end
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
@@ -211,7 +176,7 @@ it can't connect to the server a `Redis::CannotConnectError` error will be raise
211
176
  ```ruby
212
177
  begin
213
178
  redis.ping
214
- rescue Exception => e
179
+ rescue StandardError => e
215
180
  e.inspect
216
181
  # => #<Redis::CannotConnectError: Timed out connecting to Redis on 10.0.1.1:6380>
217
182
 
@@ -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/bin/build ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ TARBALL = ARGV[0]
4
+
5
+ require 'digest/sha1'
6
+ require 'fileutils'
7
+
8
+ class Builder
9
+ def initialize(redis_branch, tmp_dir)
10
+ @redis_branch = redis_branch
11
+ @tmp_dir = tmp_dir
12
+ @build_dir = File.join(@tmp_dir, "cache", "redis-#{redis_branch}")
13
+ end
14
+
15
+ def run
16
+ download_tarball
17
+ if old_checkum != checksum
18
+ build
19
+ update_checksum
20
+ end
21
+ 0
22
+ end
23
+
24
+ def download_tarball
25
+ command!('wget', tarball_url, '-O', tarball_path)
26
+ end
27
+
28
+ def tarball_path
29
+ File.join(@tmp_dir, "redis-#{@redis_branch}.tar.gz")
30
+ end
31
+
32
+ def tarball_url
33
+ "https://github.com/antirez/redis/archive/#{@redis_branch}.tar.gz"
34
+ end
35
+
36
+ def build
37
+ FileUtils.rm_rf(@build_dir)
38
+ FileUtils.mkdir_p(@build_dir)
39
+ command!('tar', 'xf', tarball_path, '-C', File.expand_path('../', @build_dir))
40
+ Dir.chdir(@build_dir) do
41
+ command!('make')
42
+ end
43
+ end
44
+
45
+ def update_checksum
46
+ File.write(checksum_path, checksum)
47
+ end
48
+
49
+ def old_checkum
50
+ File.read(checksum_path)
51
+ rescue Errno::ENOENT
52
+ nil
53
+ end
54
+
55
+ def checksum_path
56
+ File.join(@build_dir, 'build.checksum')
57
+ end
58
+
59
+ def checksum
60
+ @checksum ||= Digest::SHA1.file(tarball_path).hexdigest
61
+ end
62
+
63
+ def command!(*args)
64
+ puts "$ #{args.join(' ')}"
65
+ unless system(*args)
66
+ raise "Command failed with status #{$?.exitstatus}"
67
+ end
68
+ end
69
+ end
70
+
71
+ exit Builder.new(ARGV[0], ARGV[1]).run
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
 
@@ -18,12 +18,12 @@ class Redis
18
18
  :id => nil,
19
19
  :tcp_keepalive => 0,
20
20
  :reconnect_attempts => 1,
21
+ :reconnect_delay => 0,
22
+ :reconnect_delay_max => 0.5,
21
23
  :inherit_socket => false
22
24
  }
23
25
 
24
- def options
25
- Marshal.load(Marshal.dump(@options))
26
- end
26
+ attr_reader :options
27
27
 
28
28
  def scheme
29
29
  @options[:scheme]
@@ -86,11 +86,14 @@ class Redis
86
86
 
87
87
  @pending_reads = 0
88
88
 
89
- if options.include?(:sentinels)
90
- @connector = Connector::Sentinel.new(@options)
91
- else
92
- @connector = Connector.new(@options)
93
- end
89
+ @connector =
90
+ if options.include?(:sentinels)
91
+ Connector::Sentinel.new(@options)
92
+ elsif options.include?(:connector) && options[:connector].respond_to?(:new)
93
+ options.delete(:connector).new(@options)
94
+ else
95
+ Connector.new(@options)
96
+ end
94
97
  end
95
98
 
96
99
  def connect
@@ -152,9 +155,12 @@ class Redis
152
155
  end
153
156
 
154
157
  def call_pipeline(pipeline)
158
+ commands = pipeline.commands
159
+ return [] if commands.empty?
160
+
155
161
  with_reconnect pipeline.with_reconnect? do
156
162
  begin
157
- pipeline.finish(call_pipelined(pipeline.commands)).tap do
163
+ pipeline.finish(call_pipelined(commands)).tap do
158
164
  self.db = pipeline.db if pipeline.db
159
165
  end
160
166
  rescue ConnectionError => e
@@ -185,13 +191,10 @@ class Redis
185
191
  exception = nil
186
192
 
187
193
  process(commands) do
188
- result[0] = read
189
-
190
- @reconnect = false
191
-
192
- (commands.size - 1).times do |i|
194
+ commands.size.times do |i|
193
195
  reply = read
194
- result[i + 1] = reply
196
+ result[i] = reply
197
+ @reconnect = false
195
198
  exception = reply if exception.nil? && reply.is_a?(CommandError)
196
199
  end
197
200
  end
@@ -336,10 +339,12 @@ class Redis
336
339
  @connection = @options[:driver].connect(@options)
337
340
  @pending_reads = 0
338
341
  rescue TimeoutError,
342
+ SocketError,
339
343
  Errno::ECONNREFUSED,
340
344
  Errno::EHOSTDOWN,
341
345
  Errno::EHOSTUNREACH,
342
346
  Errno::ENETUNREACH,
347
+ Errno::ENOENT,
343
348
  Errno::ETIMEDOUT
344
349
 
345
350
  raise CannotConnectError, "Error connecting to Redis on #{location} (#{$!.class})"
@@ -369,6 +374,10 @@ class Redis
369
374
  disconnect
370
375
 
371
376
  if attempts <= @options[:reconnect_attempts] && @reconnect
377
+ sleep_t = [(@options[:reconnect_delay] * 2**(attempts-1)),
378
+ @options[:reconnect_delay_max]].min
379
+
380
+ Kernel.sleep(sleep_t)
372
381
  retry
373
382
  else
374
383
  raise
@@ -445,6 +454,10 @@ class Redis
445
454
  options[:read_timeout] = Float(options[:read_timeout])
446
455
  options[:write_timeout] = Float(options[:write_timeout])
447
456
 
457
+ options[:reconnect_attempts] = options[:reconnect_attempts].to_i
458
+ options[:reconnect_delay] = options[:reconnect_delay].to_f
459
+ options[:reconnect_delay_max] = options[:reconnect_delay_max].to_f
460
+
448
461
  options[:db] = options[:db].to_i
449
462
  options[:driver] = _parse_driver(options[:driver]) || Connection.drivers.last
450
463
 
@@ -478,11 +491,16 @@ class Redis
478
491
 
479
492
  if driver.kind_of?(String)
480
493
  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}"
494
+ require_relative "connection/#{driver}"
495
+ rescue LoadError, NameError => e
496
+ begin
497
+ require "connection/#{driver}"
498
+ rescue LoadError, NameError => e
499
+ raise RuntimeError, "Cannot load driver #{driver.inspect}: #{e.message}"
500
+ end
485
501
  end
502
+
503
+ driver = Connection.const_get(driver.capitalize)
486
504
  end
487
505
 
488
506
  driver