actioncable 7.0.3 → 7.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7294e8477c23e63558167989d2cde088da65d58289884a00940cfc83d7ed8549
4
- data.tar.gz: 4d68105c0c252e959c9a47d336cf9877c88eaf22bf0af4b48f5dc8b15edc4aec
3
+ metadata.gz: 93e4a2b2cddb15ebdbce60bcf1b41a9ed7c0d42c4a559415708cfb1cd8d1336b
4
+ data.tar.gz: c8d6623c5f44c0c283617b8ff3fca22ccb48b6331acfdf2e56071a44be65118a
5
5
  SHA512:
6
- metadata.gz: f622a763302ed4d2c2da4128ff9eb8ebf3ce7e132123939e1d437989cdfe27f04f33e8cd910940f65872ae3396b4a43d1c3ad2c19c48741503587256d1ee4f59
7
- data.tar.gz: 2118b822316ae38d38bbb93e50241e3e60ffd72be33f027ac3645920d26cd7584c0e69999d84be32c02abe1f7db0791967f19710e5ac2c2938bfb1daa483b029
6
+ metadata.gz: 60bd3dff9ae1fdf2ed1065957dad4af7f7441c6fb3f3f0461bd97585b54f7397b46ad660be82fac4b9d783b753f608689859ee547ec9735d8a68b0a64e5b4e55
7
+ data.tar.gz: bfeb76fd0365ea64a539d249ea6f2e31ac509acad1e9f74bd569a488fd0e6066c9e58f15c9f4764b3d46624f30a75460a8e728293e50ea856c7dcd705b40911d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,57 @@
1
+ ## Rails 7.0.6 (June 29, 2023) ##
2
+
3
+ * Fix Action Cable Redis configuration with sentinels.
4
+
5
+ *Dmitriy Ivliev*
6
+
7
+
8
+ ## Rails 7.0.5.1 (June 26, 2023) ##
9
+
10
+ * No changes.
11
+
12
+
13
+ ## Rails 7.0.5 (May 24, 2023) ##
14
+
15
+ * Restore Action Cable Redis pub/sub listener on connection failure.
16
+
17
+ *Vladimir Dementyev*
18
+
19
+
20
+ ## Rails 7.0.4.3 (March 13, 2023) ##
21
+
22
+ * No changes.
23
+
24
+
25
+ ## Rails 7.0.4.2 (January 24, 2023) ##
26
+
27
+ * No changes.
28
+
29
+
30
+ ## Rails 7.0.4.1 (January 17, 2023) ##
31
+
32
+ * No changes.
33
+
34
+
35
+ ## Rails 7.0.4 (September 09, 2022) ##
36
+
37
+ * The Redis adapter is now compatible with redis-rb 5.0
38
+
39
+ Compatibility with redis-rb 3.x was dropped.
40
+
41
+ *Jean Boussier*
42
+
43
+ * The Action Cable server is now mounted with `anchor: true`.
44
+
45
+ This means that routes that also start with `/cable` will no longer clash with Action Cable.
46
+
47
+ *Alex Ghiculescu*
48
+
49
+
50
+ ## Rails 7.0.3.1 (July 12, 2022) ##
51
+
52
+ * No changes.
53
+
54
+
1
55
  ## Rails 7.0.3 (May 09, 2022) ##
2
56
 
3
57
  * No changes.
data/README.md CHANGED
@@ -15,7 +15,7 @@ API documentation is at:
15
15
 
16
16
  * https://api.rubyonrails.org
17
17
 
18
- Bug reports for the Ruby on Rails project can be filed here:
18
+ Bug reports for the Ruby on \Rails project can be filed here:
19
19
 
20
20
  * https://github.com/rails/rails/issues
21
21
 
@@ -54,7 +54,7 @@ module ActionCable
54
54
  config = app.config
55
55
  unless config.action_cable.mount_path.nil?
56
56
  app.routes.prepend do
57
- mount ActionCable.server => config.action_cable.mount_path, internal: true
57
+ mount ActionCable.server => config.action_cable.mount_path, internal: true, anchor: true
58
58
  end
59
59
  end
60
60
  end
@@ -9,7 +9,7 @@ module ActionCable
9
9
  module VERSION
10
10
  MAJOR = 7
11
11
  MINOR = 0
12
- TINY = 3
12
+ TINY = 6
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "thread"
4
4
 
5
- gem "redis", ">= 3", "< 5"
5
+ gem "redis", ">= 3", "< 6"
6
6
  require "redis"
7
7
 
8
8
  require "active_support/core_ext/hash/except"
@@ -46,7 +46,7 @@ module ActionCable
46
46
 
47
47
  private
48
48
  def listener
49
- @listener || @server.mutex.synchronize { @listener ||= Listener.new(self, @server.event_loop) }
49
+ @listener || @server.mutex.synchronize { @listener ||= Listener.new(self, config_options, @server.event_loop) }
50
50
  end
51
51
 
52
52
  def redis_connection_for_broadcasts
@@ -56,11 +56,15 @@ module ActionCable
56
56
  end
57
57
 
58
58
  def redis_connection
59
- self.class.redis_connector.call(@server.config.cable.merge(id: identifier))
59
+ self.class.redis_connector.call(config_options)
60
+ end
61
+
62
+ def config_options
63
+ @config_options ||= @server.config.cable.deep_symbolize_keys.merge(id: identifier)
60
64
  end
61
65
 
62
66
  class Listener < SubscriberMap
63
- def initialize(adapter, event_loop)
67
+ def initialize(adapter, config_options, event_loop)
64
68
  super()
65
69
 
66
70
  @adapter = adapter
@@ -69,7 +73,12 @@ module ActionCable
69
73
  @subscribe_callbacks = Hash.new { |h, k| h[k] = [] }
70
74
  @subscription_lock = Mutex.new
71
75
 
72
- @raw_client = nil
76
+ @reconnect_attempt = 0
77
+ # Use the same config as used by Redis conn
78
+ @reconnect_attempts = config_options.fetch(:reconnect_attempts, 1)
79
+ @reconnect_attempts = Array.new(@reconnect_attempts, 0) if @reconnect_attempts.is_a?(Integer)
80
+
81
+ @subscribed_client = nil
73
82
 
74
83
  @when_connected = []
75
84
 
@@ -78,13 +87,14 @@ module ActionCable
78
87
 
79
88
  def listen(conn)
80
89
  conn.without_reconnect do
81
- original_client = conn.respond_to?(:_client) ? conn._client : conn.client
90
+ original_client = extract_subscribed_client(conn)
82
91
 
83
92
  conn.subscribe("_action_cable_internal") do |on|
84
93
  on.subscribe do |chan, count|
85
94
  @subscription_lock.synchronize do
86
95
  if count == 1
87
- @raw_client = original_client
96
+ @reconnect_attempt = 0
97
+ @subscribed_client = original_client
88
98
 
89
99
  until @when_connected.empty?
90
100
  @when_connected.shift.call
@@ -106,7 +116,7 @@ module ActionCable
106
116
  on.unsubscribe do |chan, count|
107
117
  if count == 0
108
118
  @subscription_lock.synchronize do
109
- @raw_client = nil
119
+ @subscribed_client = nil
110
120
  end
111
121
  end
112
122
  end
@@ -119,8 +129,8 @@ module ActionCable
119
129
  return if @thread.nil?
120
130
 
121
131
  when_connected do
122
- send_command("unsubscribe")
123
- @raw_client = nil
132
+ @subscribed_client.unsubscribe
133
+ @subscribed_client = nil
124
134
  end
125
135
  end
126
136
 
@@ -131,13 +141,13 @@ module ActionCable
131
141
  @subscription_lock.synchronize do
132
142
  ensure_listener_running
133
143
  @subscribe_callbacks[channel] << on_success
134
- when_connected { send_command("subscribe", channel) }
144
+ when_connected { @subscribed_client.subscribe(channel) }
135
145
  end
136
146
  end
137
147
 
138
148
  def remove_channel(channel)
139
149
  @subscription_lock.synchronize do
140
- when_connected { send_command("unsubscribe", channel) }
150
+ when_connected { @subscribed_client.unsubscribe(channel) }
141
151
  end
142
152
  end
143
153
 
@@ -150,28 +160,94 @@ module ActionCable
150
160
  @thread ||= Thread.new do
151
161
  Thread.current.abort_on_exception = true
152
162
 
153
- conn = @adapter.redis_connection_for_subscriptions
154
- listen conn
163
+ begin
164
+ conn = @adapter.redis_connection_for_subscriptions
165
+ listen conn
166
+ rescue ConnectionError
167
+ reset
168
+ if retry_connecting?
169
+ when_connected { resubscribe }
170
+ retry
171
+ end
172
+ end
155
173
  end
156
174
  end
157
175
 
158
176
  def when_connected(&block)
159
- if @raw_client
177
+ if @subscribed_client
160
178
  block.call
161
179
  else
162
180
  @when_connected << block
163
181
  end
164
182
  end
165
183
 
166
- def send_command(*command)
167
- @raw_client.write(command)
184
+ def retry_connecting?
185
+ @reconnect_attempt += 1
186
+
187
+ return false if @reconnect_attempt > @reconnect_attempts.size
188
+
189
+ sleep_t = @reconnect_attempts[@reconnect_attempt - 1]
190
+
191
+ sleep(sleep_t) if sleep_t > 0
192
+
193
+ true
194
+ end
195
+
196
+ def resubscribe
197
+ channels = @sync.synchronize do
198
+ @subscribers.keys
199
+ end
200
+ @subscribed_client.subscribe(*channels) unless channels.empty?
201
+ end
202
+
203
+ def reset
204
+ @subscription_lock.synchronize do
205
+ @subscribed_client = nil
206
+ @subscribe_callbacks.clear
207
+ @when_connected.clear
208
+ end
209
+ end
210
+
211
+ if ::Redis::VERSION < "5"
212
+ ConnectionError = ::Redis::ConnectionError
213
+
214
+ class SubscribedClient
215
+ def initialize(raw_client)
216
+ @raw_client = raw_client
217
+ end
218
+
219
+ def subscribe(*channel)
220
+ send_command("subscribe", *channel)
221
+ end
222
+
223
+ def unsubscribe(*channel)
224
+ send_command("unsubscribe", *channel)
225
+ end
168
226
 
169
- very_raw_connection =
170
- @raw_client.connection.instance_variable_defined?(:@connection) &&
171
- @raw_client.connection.instance_variable_get(:@connection)
227
+ private
228
+ def send_command(*command)
229
+ @raw_client.write(command)
230
+
231
+ very_raw_connection =
232
+ @raw_client.connection.instance_variable_defined?(:@connection) &&
233
+ @raw_client.connection.instance_variable_get(:@connection)
234
+
235
+ if very_raw_connection && very_raw_connection.respond_to?(:flush)
236
+ very_raw_connection.flush
237
+ end
238
+ nil
239
+ end
240
+ end
241
+
242
+ def extract_subscribed_client(conn)
243
+ raw_client = conn.respond_to?(:_client) ? conn._client : conn.client
244
+ SubscribedClient.new(raw_client)
245
+ end
246
+ else
247
+ ConnectionError = RedisClient::ConnectionError
172
248
 
173
- if very_raw_connection && very_raw_connection.respond_to?(:flush)
174
- very_raw_connection.flush
249
+ def extract_subscribed_client(conn)
250
+ conn
175
251
  end
176
252
  end
177
253
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actioncable
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.3
4
+ version: 7.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pratik Naik
8
8
  - David Heinemeier Hansson
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-05-09 00:00:00.000000000 Z
12
+ date: 2023-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -17,28 +17,28 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 7.0.3
20
+ version: 7.0.6
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 7.0.3
27
+ version: 7.0.6
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: actionpack
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - '='
33
33
  - !ruby/object:Gem::Version
34
- version: 7.0.3
34
+ version: 7.0.6
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - '='
40
40
  - !ruby/object:Gem::Version
41
- version: 7.0.3
41
+ version: 7.0.6
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: nio4r
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -142,12 +142,12 @@ licenses:
142
142
  - MIT
143
143
  metadata:
144
144
  bug_tracker_uri: https://github.com/rails/rails/issues
145
- changelog_uri: https://github.com/rails/rails/blob/v7.0.3/actioncable/CHANGELOG.md
146
- documentation_uri: https://api.rubyonrails.org/v7.0.3/
145
+ changelog_uri: https://github.com/rails/rails/blob/v7.0.6/actioncable/CHANGELOG.md
146
+ documentation_uri: https://api.rubyonrails.org/v7.0.6/
147
147
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
148
- source_code_uri: https://github.com/rails/rails/tree/v7.0.3/actioncable
148
+ source_code_uri: https://github.com/rails/rails/tree/v7.0.6/actioncable
149
149
  rubygems_mfa_required: 'true'
150
- post_install_message:
150
+ post_install_message:
151
151
  rdoc_options: []
152
152
  require_paths:
153
153
  - lib
@@ -162,8 +162,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
162
  - !ruby/object:Gem::Version
163
163
  version: '0'
164
164
  requirements: []
165
- rubygems_version: 3.3.7
166
- signing_key:
165
+ rubygems_version: 3.4.13
166
+ signing_key:
167
167
  specification_version: 4
168
168
  summary: WebSocket framework for Rails.
169
169
  test_files: []