redis 3.3.5 → 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +132 -2
  3. data/README.md +144 -79
  4. data/lib/redis.rb +1174 -405
  5. data/lib/redis/client.rb +150 -90
  6. data/lib/redis/cluster.rb +295 -0
  7. data/lib/redis/cluster/command.rb +81 -0
  8. data/lib/redis/cluster/command_loader.rb +34 -0
  9. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  10. data/lib/redis/cluster/node.rb +107 -0
  11. data/lib/redis/cluster/node_key.rb +31 -0
  12. data/lib/redis/cluster/node_loader.rb +37 -0
  13. data/lib/redis/cluster/option.rb +93 -0
  14. data/lib/redis/cluster/slot.rb +86 -0
  15. data/lib/redis/cluster/slot_loader.rb +49 -0
  16. data/lib/redis/connection.rb +4 -2
  17. data/lib/redis/connection/command_helper.rb +5 -10
  18. data/lib/redis/connection/hiredis.rb +6 -5
  19. data/lib/redis/connection/registry.rb +2 -1
  20. data/lib/redis/connection/ruby.rb +126 -128
  21. data/lib/redis/connection/synchrony.rb +21 -8
  22. data/lib/redis/distributed.rb +147 -72
  23. data/lib/redis/errors.rb +48 -0
  24. data/lib/redis/hash_ring.rb +30 -73
  25. data/lib/redis/pipeline.rb +55 -15
  26. data/lib/redis/subscribe.rb +11 -12
  27. data/lib/redis/version.rb +3 -1
  28. metadata +49 -202
  29. data/.gitignore +0 -16
  30. data/.travis.yml +0 -89
  31. data/.travis/Gemfile +0 -11
  32. data/.yardopts +0 -3
  33. data/Gemfile +0 -4
  34. data/Rakefile +0 -87
  35. data/benchmarking/logging.rb +0 -71
  36. data/benchmarking/pipeline.rb +0 -51
  37. data/benchmarking/speed.rb +0 -21
  38. data/benchmarking/suite.rb +0 -24
  39. data/benchmarking/worker.rb +0 -71
  40. data/examples/basic.rb +0 -15
  41. data/examples/consistency.rb +0 -114
  42. data/examples/dist_redis.rb +0 -43
  43. data/examples/incr-decr.rb +0 -17
  44. data/examples/list.rb +0 -26
  45. data/examples/pubsub.rb +0 -37
  46. data/examples/sentinel.rb +0 -41
  47. data/examples/sentinel/sentinel.conf +0 -9
  48. data/examples/sentinel/start +0 -49
  49. data/examples/sets.rb +0 -36
  50. data/examples/unicorn/config.ru +0 -3
  51. data/examples/unicorn/unicorn.rb +0 -20
  52. data/redis.gemspec +0 -44
  53. data/test/bitpos_test.rb +0 -69
  54. data/test/blocking_commands_test.rb +0 -42
  55. data/test/client_test.rb +0 -59
  56. data/test/command_map_test.rb +0 -30
  57. data/test/commands_on_hashes_test.rb +0 -21
  58. data/test/commands_on_hyper_log_log_test.rb +0 -21
  59. data/test/commands_on_lists_test.rb +0 -20
  60. data/test/commands_on_sets_test.rb +0 -77
  61. data/test/commands_on_sorted_sets_test.rb +0 -137
  62. data/test/commands_on_strings_test.rb +0 -101
  63. data/test/commands_on_value_types_test.rb +0 -133
  64. data/test/connection_handling_test.rb +0 -277
  65. data/test/connection_test.rb +0 -57
  66. data/test/db/.gitkeep +0 -0
  67. data/test/distributed_blocking_commands_test.rb +0 -46
  68. data/test/distributed_commands_on_hashes_test.rb +0 -10
  69. data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
  70. data/test/distributed_commands_on_lists_test.rb +0 -22
  71. data/test/distributed_commands_on_sets_test.rb +0 -83
  72. data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
  73. data/test/distributed_commands_on_strings_test.rb +0 -59
  74. data/test/distributed_commands_on_value_types_test.rb +0 -95
  75. data/test/distributed_commands_requiring_clustering_test.rb +0 -164
  76. data/test/distributed_connection_handling_test.rb +0 -23
  77. data/test/distributed_internals_test.rb +0 -79
  78. data/test/distributed_key_tags_test.rb +0 -52
  79. data/test/distributed_persistence_control_commands_test.rb +0 -26
  80. data/test/distributed_publish_subscribe_test.rb +0 -92
  81. data/test/distributed_remote_server_control_commands_test.rb +0 -66
  82. data/test/distributed_scripting_test.rb +0 -102
  83. data/test/distributed_sorting_test.rb +0 -20
  84. data/test/distributed_test.rb +0 -58
  85. data/test/distributed_transactions_test.rb +0 -32
  86. data/test/encoding_test.rb +0 -18
  87. data/test/error_replies_test.rb +0 -59
  88. data/test/fork_safety_test.rb +0 -65
  89. data/test/helper.rb +0 -232
  90. data/test/helper_test.rb +0 -24
  91. data/test/internals_test.rb +0 -417
  92. data/test/lint/blocking_commands.rb +0 -150
  93. data/test/lint/hashes.rb +0 -162
  94. data/test/lint/hyper_log_log.rb +0 -60
  95. data/test/lint/lists.rb +0 -143
  96. data/test/lint/sets.rb +0 -140
  97. data/test/lint/sorted_sets.rb +0 -316
  98. data/test/lint/strings.rb +0 -260
  99. data/test/lint/value_types.rb +0 -122
  100. data/test/persistence_control_commands_test.rb +0 -26
  101. data/test/pipelining_commands_test.rb +0 -242
  102. data/test/publish_subscribe_test.rb +0 -282
  103. data/test/remote_server_control_commands_test.rb +0 -118
  104. data/test/scanning_test.rb +0 -413
  105. data/test/scripting_test.rb +0 -78
  106. data/test/sentinel_command_test.rb +0 -80
  107. data/test/sentinel_test.rb +0 -255
  108. data/test/sorting_test.rb +0 -59
  109. data/test/ssl_test.rb +0 -73
  110. data/test/support/connection/hiredis.rb +0 -1
  111. data/test/support/connection/ruby.rb +0 -1
  112. data/test/support/connection/synchrony.rb +0 -17
  113. data/test/support/redis_mock.rb +0 -130
  114. data/test/support/ssl/gen_certs.sh +0 -31
  115. data/test/support/ssl/trusted-ca.crt +0 -25
  116. data/test/support/ssl/trusted-ca.key +0 -27
  117. data/test/support/ssl/trusted-cert.crt +0 -81
  118. data/test/support/ssl/trusted-cert.key +0 -28
  119. data/test/support/ssl/untrusted-ca.crt +0 -26
  120. data/test/support/ssl/untrusted-ca.key +0 -27
  121. data/test/support/ssl/untrusted-cert.crt +0 -82
  122. data/test/support/ssl/untrusted-cert.key +0 -28
  123. data/test/support/wire/synchrony.rb +0 -24
  124. data/test/support/wire/thread.rb +0 -5
  125. data/test/synchrony_driver.rb +0 -88
  126. data/test/test.conf.erb +0 -9
  127. data/test/thread_safety_test.rb +0 -62
  128. data/test/transactions_test.rb +0 -264
  129. data/test/unknown_commands_test.rb +0 -14
  130. data/test/url_param_test.rb +0 -138
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 729f56810aa501065e2fc203050363713c80ee37
4
- data.tar.gz: e7e13fb75618f794a2c742d73d6c8a72699d5e92
2
+ SHA256:
3
+ metadata.gz: 416a2f007042c19453c13361aa4440a507e47fb32c28adc68e7c574c6651f5b4
4
+ data.tar.gz: 1a845f2af649d64f8b274962c9d5d10e6eb5d046474b6e44288676432fe8a98b
5
5
  SHA512:
6
- metadata.gz: f87e76c751760b7f1feb7c859ea373c41ebf805c104c27e85177cb20a60d42b11c50db2d5a916fb7bfc78b82b13141770a851568aea922ccc1970f4e30ba1dea
7
- data.tar.gz: ac4cb236c9c9897d73ead9421e161cf1c7aac2a3c1f77c088b5c52c324cddccda6ab749441093cbcc94ea812e70232f9f9ac1c160a96fd1fbd46d87586d1d7fb
6
+ metadata.gz: 3766992242ae284ca474bc8564c6760de88e635a8c3bc3c80da08062d698cc891bf00455b5d98768709ecc766f8ad305fe03cc5806f03fda3ebb93049e0a1cce
7
+ data.tar.gz: f440c984ec58ff091a6a696952239cb04cf145752b485543e5da7215a327b40be4391b3fe6ca67753f84ec43913b9d90ec0b6f812e1696890a7c17cbf3aa3630
data/CHANGELOG.md CHANGED
@@ -1,8 +1,138 @@
1
+ # Unreleased
2
+
3
+ # 4.3.1
4
+
5
+ * Fix password authentication against redis server 5 and older.
6
+
7
+ # 4.3.0
8
+
9
+ * Add the TYPE argument to scan and scan_each. See #985.
10
+ * Support AUTH command for ACL. See #967.
11
+
12
+ # 4.2.5
13
+
14
+ * Optimize the ruby connector write buffering. See #964.
15
+
16
+ # 4.2.4
17
+
18
+ * Fix bytesize calculations in the ruby connector, and work on a copy of the buffer. Fix #961, #962.
19
+
20
+ # 4.2.3
21
+
22
+ * Use io/wait instead of IO.select in the ruby connector. See #960.
23
+ * Use exception free non blocking IOs in the ruby connector. See #926.
24
+ * Prevent corruption of the client when an interrupt happen during inside a pipeline block. See #945.
25
+
26
+ # 4.2.2
27
+
28
+ * Fix `WATCH` support for `Redis::Distributed`. See #941.
29
+ * Fix handling of empty stream responses. See #905, #929.
30
+
31
+ # 4.2.1
32
+
33
+ * Fix `exists?` returning an actual boolean when called with multiple keys. See #918.
34
+ * Setting `Redis.exists_returns_integer = false` disables warning message about new behaviour. See #920.
35
+
36
+ # 4.2.0
37
+
38
+ * Convert commands to accept keyword arguments rather than option hashes. This both help catching typos, and reduce needless allocations.
39
+ * Deprecate the synchrony driver. It will be removed in 5.0 and hopefully maintained as a separate gem. See #915.
40
+ * Make `Redis#exists` variadic, will return an Integer if called with multiple keys.
41
+ * Add `Redis#exists?` to get a Boolean if any of the keys exists.
42
+ * `Redis#exists` when called with a single key will warn that future versions will return an Integer.
43
+ Set `Redis.exists_returns_integer = true` to opt-in to the new behavior.
44
+ * Support `keepttl` ooption in `set`. See #913.
45
+ * Optimized initialization of Redis::Cluster. See #912.
46
+ * Accept sentinel options even with string key. See #599.
47
+ * Verify TLS connections by default. See #900.
48
+ * Make `Redis#hset` variadic. It now returns an integer, not a boolean. See #910.
49
+
50
+ # 4.1.4
51
+
52
+ * Alias `Redis#disconnect` as `#close`. See #901.
53
+ * Handle clusters with multiple slot ranges. See #894.
54
+ * Fix password authentication to a redis cluster. See #889.
55
+ * Handle recursive MOVED responses. See #882.
56
+ * Increase buffer size in the ruby connector. See #880.
57
+ * Fix thread safety of `Redis.queue`. See #878.
58
+ * Deprecate `Redis::Future#==` as it's likely to be a mistake. See #876.
59
+ * Support `KEEPTTL` option for SET command. See #913.
60
+
61
+ # 4.1.3
62
+
63
+ * Fix the client hanging forever when connecting with SSL to a non-SSL server. See #835.
64
+
65
+ # 4.1.2
66
+
67
+ * Fix several authentication problems with sentinel. See #850 and #856.
68
+ * Explicitly drop Ruby 2.2 support.
69
+
70
+
71
+ # 4.1.1
72
+
73
+ * Fix error handling in multi blocks. See #754.
74
+ * Fix geoadd to accept arrays like georadius and georadiusbymember. See #841.
75
+ * Fix georadius command failing when long == lat. See #841.
76
+ * Fix timeout error in xread block: 0. See #837.
77
+ * Fix incompatibility issue with redis-objects. See #834.
78
+ * Properly handle Errno::EADDRNOTAVAIL on connect.
79
+ * Fix password authentication to sentinel instances. See #813.
80
+
81
+ # 4.1.0
82
+
83
+ * Add Redis Cluster support. See #716.
84
+ * Add streams support. See #799 and #811.
85
+ * Add ZPOP* support. See #812.
86
+ * Fix issues with integer-like objects as BPOP timeout
87
+
88
+ # 4.0.3
89
+
90
+ * Fix raising command error for first command in pipeline. See #788.
91
+ * Fix the gemspec to stop exposing a `build` executable. See #785.
92
+ * Add `:reconnect_delay` and `:reconnect_delay_max` options. See #778.
93
+
94
+ # 4.0.2
95
+
96
+ * Added `Redis#unlink`. See #766.
97
+
98
+ * `Redis.new` now accept a custom connector via `:connector`. See #591.
99
+
100
+ * `Redis#multi` no longer perform empty transactions. See #747.
101
+
102
+ * `Redis#hdel` now accepts hash keys as multiple arguments like `#del`. See #755.
103
+
104
+ * Allow to skip SSL verification. See #745.
105
+
106
+ * Add Geo commands: `geoadd`, `geohash`, `georadius`, `georadiusbymember`, `geopos`, `geodist`. See #730.
107
+
108
+ # 4.0.1
109
+
110
+ * `Redis::Distributed` now supports `mget` and `mapped_mget`. See #687.
111
+
112
+ * `Redis::Distributed` now supports `sscan` and `sscan_each`. See #572.
113
+
114
+ * `Redis#connection` returns a hash with connection information.
115
+ You shouldn't need to call `Redis#_client`, ever.
116
+
117
+ * `Redis#flushdb` and `Redis#flushall` now support the `:async` option. See #706.
118
+
119
+
120
+ # 4.0
121
+
122
+ * Removed `Redis.connect`. Use `Redis.new`.
123
+
124
+ * Removed `Redis#[]` and `Redis#[]=` aliases.
125
+
126
+ * Added support for `CLIENT` commands. The lower-level client can be
127
+ accessed via `Redis#_client`.
128
+
129
+ * Dropped official support for Ruby < 2.2.2.
130
+
1
131
  # 3.3.5
2
132
 
3
133
  * Fixed Ruby 1.8 compatibility after backporting `Redis#connection`. See #719.
4
134
 
5
- # 3.3.4
135
+ # 3.3.4 (yanked)
6
136
 
7
137
  * `Redis#connection` returns a hash with connection information.
8
138
  You shouldn't need to call `Redis#_client`, ever.
@@ -13,7 +143,7 @@
13
143
 
14
144
  # 3.3.2
15
145
 
16
- * Added support for SPOP with COUNT. See #628.
146
+ * Added support for `SPOP` with COUNT. See #628.
17
147
 
18
148
  * Fixed connection glitches when using SSL. See #644.
19
149
 
data/README.md CHANGED
@@ -1,46 +1,18 @@
1
- # redis-rb [![Build Status][travis-image]][travis-link] [![Inline docs][inchpages-image]][inchpages-link]
1
+ # redis-rb [![Build Status][gh-actions-image]][gh-actions-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
6
+ See [RubyDoc.info][rubydoc] for the API docs of the latest published gem.
23
7
 
24
8
  ## Getting started
25
9
 
26
- To install **redis-rb**, run the following command:
10
+ Install with:
27
11
 
28
12
  ```
29
- gem install redis
13
+ $ gem install redis
30
14
  ```
31
15
 
32
- Or if you are using **bundler**, add
33
-
34
- ```
35
- gem 'redis', '~>3.2'
36
- ```
37
-
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
16
  You can connect to Redis by instantiating the `Redis` class:
45
17
 
46
18
  ```ruby
@@ -54,16 +26,17 @@ listening on `localhost`, port 6379. If you need to connect to a remote
54
26
  server or a different port, try:
55
27
 
56
28
  ```ruby
57
- redis = Redis.new(:host => "10.0.1.1", :port => 6380, :db => 15)
29
+ redis = Redis.new(host: "10.0.1.1", port: 6380, db: 15)
58
30
  ```
59
31
 
60
32
  You can also specify connection options as a [`redis://` URL][redis-url]:
61
33
 
62
34
  ```ruby
63
- redis = Redis.new(:url => "redis://:p4ssw0rd@10.0.1.1:6380/15")
35
+ redis = Redis.new(url: "redis://:p4ssw0rd@10.0.1.1:6380/15")
64
36
  ```
65
37
 
66
- [redis-url]: http://www.iana.org/assignments/uri-schemes/prov/redis
38
+ The client expects passwords with special chracters to be URL-encoded (i.e.
39
+ `CGI.escape(password)`).
67
40
 
68
41
  By default, the client will try to read the `REDIS_URL` environment variable
69
42
  and use that as URL to connect to. The above statement is therefore equivalent
@@ -72,13 +45,19 @@ to setting this environment variable and calling `Redis.new` without arguments.
72
45
  To connect to Redis listening on a Unix socket, try:
73
46
 
74
47
  ```ruby
75
- redis = Redis.new(:path => "/tmp/redis.sock")
48
+ redis = Redis.new(path: "/tmp/redis.sock")
76
49
  ```
77
50
 
78
51
  To connect to a password protected Redis instance, use:
79
52
 
80
53
  ```ruby
81
- redis = Redis.new(:password => "mysecret")
54
+ redis = Redis.new(password: "mysecret")
55
+ ```
56
+
57
+ To connect a Redis instance using [ACL](https://redis.io/topics/acl), use:
58
+
59
+ ```ruby
60
+ redis = Redis.new(username: 'myname', password: 'mysecret')
82
61
  ```
83
62
 
84
63
  The Redis class exports methods that are named identical to the commands
@@ -86,8 +65,6 @@ they execute. The arguments these methods accept are often identical to
86
65
  the arguments specified on the [Redis website][redis-commands]. For
87
66
  instance, the `SET` and `GET` commands can be called like this:
88
67
 
89
- [redis-commands]: http://redis.io/commands
90
-
91
68
  ```ruby
92
69
  redis.set("mykey", "hello world")
93
70
  # => "OK"
@@ -96,24 +73,22 @@ redis.get("mykey")
96
73
  # => "hello world"
97
74
  ```
98
75
 
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/
76
+ All commands, their arguments, and return values are documented and
77
+ available on [RubyDoc.info][rubydoc].
103
78
 
104
79
  ## Sentinel support
105
80
 
106
- The client is able to perform automatic failovers by using [Redis
81
+ The client is able to perform automatic failover by using [Redis
107
82
  Sentinel](http://redis.io/topics/sentinel). Make sure to run Redis 2.8+
108
83
  if you want to use this feature.
109
84
 
110
85
  To connect using Sentinel, use:
111
86
 
112
87
  ```ruby
113
- SENTINELS = [{:host => "127.0.0.1", :port => 26380},
114
- {:host => "127.0.0.1", :port => 26381}]
88
+ SENTINELS = [{ host: "127.0.0.1", port: 26380 },
89
+ { host: "127.0.0.1", port: 26381 }]
115
90
 
116
- redis = Redis.new(:url => "redis://mymaster", :sentinels => SENTINELS, :role => :master)
91
+ redis = Redis.new(url: "redis://mymaster", sentinels: SENTINELS, role: :master)
117
92
  ```
118
93
 
119
94
  * The master name identifies a group of Redis instances composed of a master
@@ -130,10 +105,60 @@ but a few so that if one is down the client will try the next one. The client
130
105
  is able to remember the last Sentinel that was able to reply correctly and will
131
106
  use it for the next requests.
132
107
 
108
+ If you want to [authenticate](https://redis.io/topics/sentinel#configuring-sentinel-instances-with-authentication) Sentinel itself, you must specify the `password` option per instance.
109
+
110
+ ```ruby
111
+ SENTINELS = [{ host: '127.0.0.1', port: 26380, password: 'mysecret' },
112
+ { host: '127.0.0.1', port: 26381, password: 'mysecret' }]
113
+
114
+ redis = Redis.new(host: 'mymaster', sentinels: SENTINELS, role: :master)
115
+ ```
116
+
117
+ ## Cluster support
118
+
119
+ `redis-rb` supports [clustering](https://redis.io/topics/cluster-spec).
120
+
121
+ ```ruby
122
+ # Nodes can be passed to the client as an array of connection URLs.
123
+ nodes = (7000..7005).map { |port| "redis://127.0.0.1:#{port}" }
124
+ redis = Redis.new(cluster: nodes)
125
+
126
+ # You can also specify the options as a Hash. The options are the same as for a single server connection.
127
+ (7000..7005).map { |port| { host: '127.0.0.1', port: port } }
128
+ ```
129
+
130
+ You can also specify only a subset of the nodes, and the client will discover the missing ones using the [CLUSTER NODES](https://redis.io/commands/cluster-nodes) command.
131
+
132
+ ```ruby
133
+ Redis.new(cluster: %w[redis://127.0.0.1:7000])
134
+ ```
135
+
136
+ If you want [the connection to be able to read from any replica](https://redis.io/commands/readonly), you must pass the `replica: true`. Note that this connection won't be usable to write keys.
137
+
138
+ ```ruby
139
+ Redis.new(cluster: nodes, replica: true)
140
+ ```
141
+
142
+ The calling code is responsible for [avoiding cross slot commands](https://redis.io/topics/cluster-spec#keys-distribution-model).
143
+
144
+ ```ruby
145
+ redis = Redis.new(cluster: %w[redis://127.0.0.1:7000])
146
+
147
+ redis.mget('key1', 'key2')
148
+ #=> Redis::CommandError (CROSSSLOT Keys in request don't hash to the same slot)
149
+
150
+ redis.mget('{key}1', '{key}2')
151
+ #=> [nil, nil]
152
+ ```
153
+
154
+ * The client automatically reconnects after a failover occurred, but the caller is responsible for handling errors while it is happening.
155
+ * The client support permanent node failures, and will reroute requests to promoted slaves.
156
+ * The client supports `MOVED` and `ASK` redirections transparently.
157
+
133
158
  ## Storing objects
134
159
 
135
- Redis only stores strings as values. If you want to store an object, you
136
- can use a serialization mechanism such as JSON:
160
+ Redis "string" types can be used to store serialized Ruby objects, for
161
+ example with JSON:
137
162
 
138
163
  ```ruby
139
164
  require "json"
@@ -211,7 +236,7 @@ it can't connect to the server a `Redis::CannotConnectError` error will be raise
211
236
  ```ruby
212
237
  begin
213
238
  redis.ping
214
- rescue Exception => e
239
+ rescue StandardError => e
215
240
  e.inspect
216
241
  # => #<Redis::CannotConnectError: Timed out connecting to Redis on 10.0.1.1:6380>
217
242
 
@@ -246,6 +271,7 @@ All timeout values are specified in seconds.
246
271
  When using pub/sub, you can subscribe to a channel using a timeout as well:
247
272
 
248
273
  ```ruby
274
+ redis = Redis.new(reconnect_attempts: 0)
249
275
  redis.subscribe_with_timeout(5, "news") do |on|
250
276
  on.message do |channel, message|
251
277
  # ...
@@ -255,6 +281,51 @@ end
255
281
 
256
282
  If no message is received after 5 seconds, the client will unsubscribe.
257
283
 
284
+ ## Reconnections
285
+
286
+ The client allows you to configure how many `reconnect_attempts` it should
287
+ complete before declaring a connection as failed. Furthermore, you may want
288
+ to control the maximum duration between reconnection attempts with
289
+ `reconnect_delay` and `reconnect_delay_max`.
290
+
291
+ ```ruby
292
+ Redis.new(
293
+ :reconnect_attempts => 10,
294
+ :reconnect_delay => 1.5,
295
+ :reconnect_delay_max => 10.0,
296
+ )
297
+ ```
298
+
299
+ The delay values are specified in seconds. With the above configuration, the
300
+ client would attempt 10 reconnections, exponentially increasing the duration
301
+ between each attempt but it never waits longer than `reconnect_delay_max`.
302
+
303
+ This is the retry algorithm:
304
+
305
+ ```ruby
306
+ attempt_wait_time = [(reconnect_delay * 2**(attempt-1)), reconnect_delay_max].min
307
+ ```
308
+
309
+ **By default**, this gem will only **retry a connection once** and then fail, but with the
310
+ above configuration the reconnection attempt would look like this:
311
+
312
+ #|Attempt wait time|Total wait time
313
+ :-:|:-:|:-:
314
+ 1|1.5s|1.5s
315
+ 2|3.0s|4.5s
316
+ 3|6.0s|10.5s
317
+ 4|10.0s|20.5s
318
+ 5|10.0s|30.5s
319
+ 6|10.0s|40.5s
320
+ 7|10.0s|50.5s
321
+ 8|10.0s|60.5s
322
+ 9|10.0s|70.5s
323
+ 10|10.0s|80.5s
324
+
325
+ So if the reconnection attempt #10 succeeds 70 seconds have elapsed trying
326
+ to reconnect, this is likely fine in long-running background processes, but if
327
+ you use Redis to drive your website you might want to have a lower
328
+ `reconnect_delay_max` or have less `reconnect_attempts`.
258
329
 
259
330
  ## SSL/TLS Support
260
331
 
@@ -262,7 +333,7 @@ This library supports natively terminating client side SSL/TLS connections
262
333
  when talking to Redis via a server-side proxy such as [stunnel], [hitch],
263
334
  or [ghostunnel].
264
335
 
265
- To enable SSL support, pass the `:ssl => :true` option when configuring the
336
+ To enable SSL support, pass the `:ssl => true` option when configuring the
266
337
  Redis client, or pass in `:url => "rediss://..."` (like HTTPS for Redis).
267
338
  You will also need to pass in an `:ssl_params => { ... }` hash used to
268
339
  configure the `OpenSSL::SSL::SSLContext` object used for the connection:
@@ -374,37 +445,31 @@ redis = Redis.new(:driver => :synchrony)
374
445
 
375
446
  ## Testing
376
447
 
377
- This library is tested using [Travis][travis-home], where it is tested
378
- against the following interpreters and drivers:
448
+ This library is tested against recent Ruby and Redis versions.
449
+ Check [Github Actions][gh-actions-link] for the exact versions supported.
379
450
 
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)
451
+ ## See Also
452
+
453
+ - [async-redis](https://github.com/socketry/async-redis) — An [async](https://github.com/socketry/async) compatible Redis client.
388
454
 
389
455
  ## Contributors
390
456
 
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
457
+ Several people contributed to redis-rb, but we would like to especially
458
+ mention Ezra Zygmuntowicz. Ezra introduced the Ruby community to many
459
+ new cool technologies, like Redis. He wrote the first version of this
460
+ client and evangelized Redis in Rubyland. Thank you, Ezra.
406
461
 
407
462
  ## Contributing
408
463
 
409
464
  [Fork the project](https://github.com/redis/redis-rb) and send pull
410
- requests. You can also ask for help at `#redis-rb` on Freenode.
465
+ requests.
466
+
467
+
468
+ [inchpages-image]: https://inch-ci.org/github/redis/redis-rb.svg
469
+ [inchpages-link]: https://inch-ci.org/github/redis/redis-rb
470
+ [redis-commands]: https://redis.io/commands
471
+ [redis-home]: https://redis.io
472
+ [redis-url]: http://www.iana.org/assignments/uri-schemes/prov/redis
473
+ [gh-actions-image]: https://github.com/redis/redis-rb/workflows/Test/badge.svg
474
+ [gh-actions-link]: https://github.com/redis/redis-rb/actions
475
+ [rubydoc]: http://www.rubydoc.info/gems/redis