actioncable 7.0.3 → 7.0.6
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +54 -0
- data/README.md +1 -1
- data/lib/action_cable/engine.rb +1 -1
- data/lib/action_cable/gem_version.rb +1 -1
- data/lib/action_cable/subscription_adapter/redis.rb +98 -22
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93e4a2b2cddb15ebdbce60bcf1b41a9ed7c0d42c4a559415708cfb1cd8d1336b
|
4
|
+
data.tar.gz: c8d6623c5f44c0c283617b8ff3fca22ccb48b6331acfdf2e56071a44be65118a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/lib/action_cable/engine.rb
CHANGED
@@ -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
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "thread"
|
4
4
|
|
5
|
-
gem "redis", ">= 3", "<
|
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(
|
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
|
-
@
|
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
|
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
|
-
@
|
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
|
-
@
|
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
|
-
|
123
|
-
@
|
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 {
|
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 {
|
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
|
-
|
154
|
-
|
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 @
|
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
|
167
|
-
@
|
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
|
-
|
170
|
-
|
171
|
-
|
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
|
-
|
174
|
-
|
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.
|
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:
|
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.
|
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.
|
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.
|
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.
|
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.
|
146
|
-
documentation_uri: https://api.rubyonrails.org/v7.0.
|
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.
|
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.
|
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: []
|