actioncable 6.0.6.1 → 6.1.7.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +62 -181
- data/MIT-LICENSE +1 -1
- data/app/assets/javascripts/action_cable.js +60 -3
- data/lib/action_cable/channel/base.rb +3 -3
- data/lib/action_cable/channel/naming.rb +1 -1
- data/lib/action_cable/channel/streams.rb +29 -3
- data/lib/action_cable/channel/test_case.rb +6 -6
- data/lib/action_cable/connection/base.rb +2 -0
- data/lib/action_cable/connection/subscriptions.rb +1 -0
- data/lib/action_cable/connection/test_case.rb +2 -2
- data/lib/action_cable/engine.rb +1 -1
- data/lib/action_cable/gem_version.rb +3 -3
- data/lib/action_cable/helpers/action_cable_helper.rb +3 -3
- data/lib/action_cable/remote_connections.rb +1 -1
- data/lib/action_cable/server/base.rb +1 -1
- data/lib/action_cable/server/broadcasting.rb +1 -1
- data/lib/action_cable/server/worker.rb +1 -0
- data/lib/action_cable/server.rb +0 -1
- data/lib/action_cable/subscription_adapter/base.rb +4 -0
- data/lib/action_cable/subscription_adapter/postgresql.rb +2 -1
- data/lib/action_cable/subscription_adapter/redis.rb +1 -2
- data/lib/action_cable/test_helper.rb +4 -4
- data/lib/action_cable.rb +1 -1
- data/lib/rails/generators/channel/USAGE +2 -2
- data/lib/rails/generators/channel/templates/javascript/consumer.js.tt +1 -1
- metadata +22 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9eb88c84ff926e7ab47c12d491e78798b891fdf57095d1379866c15cbad83106
|
4
|
+
data.tar.gz: fbb54a006e030cfd1dd711f3e317942aaaae92a853cef920417852a48b7ecbb7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eee59b19157d761dad768c8f14195d85ffee31920c19edbf4ed16ceee23827a8365b1ba85057695042bae685191aff6f7d9b4de8994b3a6115711e3bd4391e66
|
7
|
+
data.tar.gz: b5a73ade374018bd881461d9ea287707bedfa08cb72b7d256cd32f2de84ba56390c86a996a3335502a75bca53bfbe2c7c04c70fb5519f9c4774cb0a09eb10320
|
data/CHANGELOG.md
CHANGED
@@ -1,299 +1,180 @@
|
|
1
|
-
## Rails 6.
|
1
|
+
## Rails 6.1.7.6 (August 22, 2023) ##
|
2
2
|
|
3
3
|
* No changes.
|
4
4
|
|
5
5
|
|
6
|
-
## Rails 6.
|
6
|
+
## Rails 6.1.7.5 (August 22, 2023) ##
|
7
7
|
|
8
8
|
* No changes.
|
9
9
|
|
10
10
|
|
11
|
-
## Rails 6.
|
11
|
+
## Rails 6.1.7.4 (June 26, 2023) ##
|
12
12
|
|
13
13
|
* No changes.
|
14
14
|
|
15
15
|
|
16
|
-
## Rails 6.
|
16
|
+
## Rails 6.1.7.3 (March 13, 2023) ##
|
17
17
|
|
18
18
|
* No changes.
|
19
19
|
|
20
20
|
|
21
|
-
## Rails 6.
|
21
|
+
## Rails 6.1.7.2 (January 24, 2023) ##
|
22
22
|
|
23
23
|
* No changes.
|
24
24
|
|
25
25
|
|
26
|
-
## Rails 6.
|
26
|
+
## Rails 6.1.7.1 (January 17, 2023) ##
|
27
27
|
|
28
28
|
* No changes.
|
29
29
|
|
30
30
|
|
31
|
-
## Rails 6.
|
31
|
+
## Rails 6.1.7 (September 09, 2022) ##
|
32
32
|
|
33
33
|
* No changes.
|
34
34
|
|
35
35
|
|
36
|
-
## Rails 6.
|
36
|
+
## Rails 6.1.6.1 (July 12, 2022) ##
|
37
37
|
|
38
38
|
* No changes.
|
39
39
|
|
40
40
|
|
41
|
-
## Rails 6.
|
41
|
+
## Rails 6.1.6 (May 09, 2022) ##
|
42
42
|
|
43
43
|
* No changes.
|
44
44
|
|
45
45
|
|
46
|
-
## Rails 6.
|
46
|
+
## Rails 6.1.5.1 (April 26, 2022) ##
|
47
47
|
|
48
48
|
* No changes.
|
49
49
|
|
50
50
|
|
51
|
-
## Rails 6.
|
52
|
-
|
53
|
-
* No changes.
|
51
|
+
## Rails 6.1.5 (March 09, 2022) ##
|
54
52
|
|
53
|
+
* The Action Cable client now ensures successful channel subscriptions:
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
*
|
55
|
+
* The client maintains a set of pending subscriptions until either
|
56
|
+
the server confirms the subscription or the channel is torn down.
|
57
|
+
* Rectifies the race condition where an unsubscribe is rapidly followed
|
58
|
+
by a subscribe (on the same channel identifier) and the requests are
|
59
|
+
handled out of order by the ActionCable server, thereby ignoring the
|
60
|
+
subscribe command.
|
59
61
|
|
62
|
+
*Daniel Spinosa*
|
60
63
|
|
61
|
-
|
64
|
+
* Truncate broadcast logging messages.
|
62
65
|
|
63
|
-
*
|
66
|
+
*J Smith*
|
64
67
|
|
65
68
|
|
66
|
-
## Rails 6.
|
69
|
+
## Rails 6.1.4.7 (March 08, 2022) ##
|
67
70
|
|
68
71
|
* No changes.
|
69
72
|
|
70
73
|
|
71
|
-
## Rails 6.
|
74
|
+
## Rails 6.1.4.6 (February 11, 2022) ##
|
72
75
|
|
73
76
|
* No changes.
|
74
77
|
|
75
78
|
|
76
|
-
## Rails 6.
|
79
|
+
## Rails 6.1.4.5 (February 11, 2022) ##
|
77
80
|
|
78
81
|
* No changes.
|
79
82
|
|
80
83
|
|
81
|
-
## Rails 6.
|
84
|
+
## Rails 6.1.4.4 (December 15, 2021) ##
|
82
85
|
|
83
86
|
* No changes.
|
84
87
|
|
85
88
|
|
86
|
-
## Rails 6.
|
89
|
+
## Rails 6.1.4.3 (December 14, 2021) ##
|
87
90
|
|
88
91
|
* No changes.
|
89
92
|
|
90
93
|
|
91
|
-
## Rails 6.
|
94
|
+
## Rails 6.1.4.2 (December 14, 2021) ##
|
92
95
|
|
93
96
|
* No changes.
|
94
97
|
|
95
98
|
|
96
|
-
## Rails 6.
|
99
|
+
## Rails 6.1.4.1 (August 19, 2021) ##
|
97
100
|
|
98
101
|
* No changes.
|
99
102
|
|
100
103
|
|
101
|
-
## Rails 6.
|
102
|
-
|
103
|
-
* No changes.
|
104
|
+
## Rails 6.1.4 (June 24, 2021) ##
|
104
105
|
|
106
|
+
* Fix `ArgumentError` with ruby 3.0 on `RemoteConnection#disconnect`.
|
105
107
|
|
106
|
-
|
108
|
+
*Vladislav*
|
107
109
|
|
108
|
-
* No changes.
|
109
110
|
|
110
|
-
|
111
|
-
## Rails 6.0.2.2 (March 19, 2020) ##
|
111
|
+
## Rails 6.1.3.2 (May 05, 2021) ##
|
112
112
|
|
113
113
|
* No changes.
|
114
114
|
|
115
115
|
|
116
|
-
## Rails 6.
|
116
|
+
## Rails 6.1.3.1 (March 26, 2021) ##
|
117
117
|
|
118
118
|
* No changes.
|
119
119
|
|
120
120
|
|
121
|
-
## Rails 6.
|
121
|
+
## Rails 6.1.3 (February 17, 2021) ##
|
122
122
|
|
123
123
|
* No changes.
|
124
124
|
|
125
125
|
|
126
|
-
## Rails 6.
|
126
|
+
## Rails 6.1.2.1 (February 10, 2021) ##
|
127
127
|
|
128
128
|
* No changes.
|
129
129
|
|
130
130
|
|
131
|
-
## Rails 6.
|
131
|
+
## Rails 6.1.2 (February 09, 2021) ##
|
132
132
|
|
133
133
|
* No changes.
|
134
134
|
|
135
135
|
|
136
|
-
## Rails 6.
|
136
|
+
## Rails 6.1.1 (January 07, 2021) ##
|
137
137
|
|
138
138
|
* No changes.
|
139
139
|
|
140
140
|
|
141
|
-
## Rails 6.
|
142
|
-
|
143
|
-
* No changes.
|
144
|
-
|
145
|
-
|
146
|
-
## Rails 6.0.0.beta3 (March 11, 2019) ##
|
147
|
-
|
148
|
-
* No changes.
|
141
|
+
## Rails 6.1.0 (December 09, 2020) ##
|
149
142
|
|
143
|
+
* `ActionCable::Connection::Base` now allows intercepting unhandled exceptions
|
144
|
+
with `rescue_from` before they are logged, which is useful for error reporting
|
145
|
+
tools and other integrations.
|
150
146
|
|
151
|
-
|
147
|
+
*Justin Talbott*
|
152
148
|
|
153
|
-
*
|
149
|
+
* Add `ActionCable::Channel#stream_or_reject_for` to stream if record is present, otherwise reject the connection
|
154
150
|
|
155
|
-
|
156
|
-
|
157
|
-
*Vladimir Dementyev*
|
158
|
-
|
159
|
-
* Allow passing custom configuration to `ActionCable::Server::Base`.
|
160
|
-
|
161
|
-
You can now create a standalone Action Cable server with a custom configuration
|
162
|
-
(e.g. to run it in isolation from the default one):
|
163
|
-
|
164
|
-
```ruby
|
165
|
-
config = ActionCable::Server::Configuration.new
|
166
|
-
config.cable = { adapter: "redis", channel_prefix: "custom_" }
|
167
|
-
|
168
|
-
CUSTOM_CABLE = ActionCable::Server::Base.new(config: config)
|
169
|
-
```
|
170
|
-
|
171
|
-
Then you can mount it in the `routes.rb` file:
|
172
|
-
|
173
|
-
```ruby
|
174
|
-
Rails.application.routes.draw do
|
175
|
-
mount CUSTOM_CABLE => "/custom_cable"
|
176
|
-
# ...
|
177
|
-
end
|
178
|
-
```
|
179
|
-
|
180
|
-
*Vladimir Dementyev*
|
181
|
-
|
182
|
-
* Add `:action_cable_connection` and `:action_cable_channel` load hooks.
|
183
|
-
|
184
|
-
You can use them to extend `ActionCable::Connection::Base` and `ActionCable::Channel::Base`
|
185
|
-
functionality:
|
186
|
-
|
187
|
-
```ruby
|
188
|
-
ActiveSupport.on_load(:action_cable_channel) do
|
189
|
-
# do something in the context of ActionCable::Channel::Base
|
190
|
-
end
|
191
|
-
```
|
151
|
+
*Atul Bhosale*
|
192
152
|
|
193
|
-
|
153
|
+
* Add `ActionCable::Channel#stop_stream_from` and `#stop_stream_for` to unsubscribe from a specific stream.
|
194
154
|
|
195
|
-
*
|
155
|
+
*Zhang Kang*
|
196
156
|
|
197
|
-
|
198
|
-
the `self.class.broadcast_to`.
|
157
|
+
* Add PostgreSQL subscription connection identificator.
|
199
158
|
|
200
|
-
|
159
|
+
Now you can distinguish Action Cable PostgreSQL subscription connections among others.
|
160
|
+
Also, you can set custom `id` in `cable.yml` configuration.
|
201
161
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
*Vladimir Dementyev*
|
212
|
-
|
213
|
-
|
214
|
-
## Rails 6.0.0.beta1 (January 18, 2019) ##
|
215
|
-
|
216
|
-
* [Rename npm package](https://github.com/rails/rails/pull/34905) from
|
217
|
-
[`actioncable`](https://www.npmjs.com/package/actioncable) to
|
218
|
-
[`@rails/actioncable`](https://www.npmjs.com/package/@rails/actioncable).
|
219
|
-
|
220
|
-
*Javan Makhmali*
|
221
|
-
|
222
|
-
* Merge [`action-cable-testing`](https://github.com/palkan/action-cable-testing) to Rails.
|
223
|
-
|
224
|
-
*Vladimir Dementyev*
|
225
|
-
|
226
|
-
* The JavaScript WebSocket client will no longer try to reconnect
|
227
|
-
when you call `reject_unauthorized_connection` on the connection.
|
228
|
-
|
229
|
-
*Mick Staugaard*
|
230
|
-
|
231
|
-
* `ActionCable.Connection#getState` now references the configurable
|
232
|
-
`ActionCable.adapters.WebSocket` property rather than the `WebSocket` global
|
233
|
-
variable, matching the behavior of `ActionCable.Connection#open`.
|
234
|
-
|
235
|
-
*Richard Macklin*
|
236
|
-
|
237
|
-
* The ActionCable javascript package has been converted from CoffeeScript
|
238
|
-
to ES2015, and we now publish the source code in the npm distribution.
|
239
|
-
|
240
|
-
This allows ActionCable users to depend on the javascript source code
|
241
|
-
rather than the compiled code, which can produce smaller javascript bundles.
|
242
|
-
|
243
|
-
This change includes some breaking changes to optional parts of the
|
244
|
-
ActionCable javascript API:
|
245
|
-
|
246
|
-
- Configuration of the WebSocket adapter and logger adapter have been moved
|
247
|
-
from properties of `ActionCable` to properties of `ActionCable.adapters`.
|
248
|
-
If you are currently configuring these adapters you will need to make
|
249
|
-
these changes when upgrading:
|
250
|
-
|
251
|
-
```diff
|
252
|
-
- ActionCable.WebSocket = MyWebSocket
|
253
|
-
+ ActionCable.adapters.WebSocket = MyWebSocket
|
254
|
-
```
|
255
|
-
```diff
|
256
|
-
- ActionCable.logger = myLogger
|
257
|
-
+ ActionCable.adapters.logger = myLogger
|
258
|
-
```
|
259
|
-
|
260
|
-
- The `ActionCable.startDebugging()` and `ActionCable.stopDebugging()`
|
261
|
-
methods have been removed and replaced with the property
|
262
|
-
`ActionCable.logger.enabled`. If you are currently using these methods you
|
263
|
-
will need to make these changes when upgrading:
|
264
|
-
|
265
|
-
```diff
|
266
|
-
- ActionCable.startDebugging()
|
267
|
-
+ ActionCable.logger.enabled = true
|
268
|
-
```
|
269
|
-
```diff
|
270
|
-
- ActionCable.stopDebugging()
|
271
|
-
+ ActionCable.logger.enabled = false
|
272
|
-
```
|
273
|
-
|
274
|
-
*Richard Macklin*
|
275
|
-
|
276
|
-
* Add `id` option to redis adapter so now you can distinguish
|
277
|
-
ActionCable's redis connections among others. Also, you can set
|
278
|
-
custom id in options.
|
279
|
-
|
280
|
-
Before:
|
281
|
-
```
|
282
|
-
$ redis-cli client list
|
283
|
-
id=669 addr=127.0.0.1:46442 fd=8 name= age=18 ...
|
284
|
-
```
|
285
|
-
|
286
|
-
After:
|
287
|
-
```
|
288
|
-
$ redis-cli client list
|
289
|
-
id=673 addr=127.0.0.1:46516 fd=8 name=ActionCable-PID-19413 age=2 ...
|
162
|
+
```sql
|
163
|
+
SELECT application_name FROM pg_stat_activity;
|
164
|
+
/*
|
165
|
+
application_name
|
166
|
+
------------------------
|
167
|
+
psql
|
168
|
+
ActionCable-PID-42
|
169
|
+
(2 rows)
|
170
|
+
*/
|
290
171
|
```
|
291
172
|
|
292
|
-
*
|
173
|
+
*Sergey Ponomarev*
|
293
174
|
|
294
|
-
*
|
175
|
+
* Subscription confirmations and rejections are now logged at the `DEBUG` level instead of `INFO`.
|
295
176
|
|
296
|
-
*
|
177
|
+
*DHH*
|
297
178
|
|
298
179
|
|
299
|
-
Please check [
|
180
|
+
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/actioncable/CHANGELOG.md) for previous changes.
|
data/MIT-LICENSE
CHANGED
@@ -135,7 +135,7 @@
|
|
135
135
|
if (document.visibilityState === "visible") {
|
136
136
|
setTimeout(function() {
|
137
137
|
if (_this2.connectionIsStale() || !_this2.connection.isOpen()) {
|
138
|
-
logger.log("ConnectionMonitor reopening stale connection on visibilitychange.
|
138
|
+
logger.log("ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = " + document.visibilityState);
|
139
139
|
_this2.connection.reopen();
|
140
140
|
}
|
141
141
|
}, 200);
|
@@ -291,6 +291,7 @@
|
|
291
291
|
return this.monitor.recordPing();
|
292
292
|
|
293
293
|
case message_types.confirmation:
|
294
|
+
this.subscriptions.confirmSubscription(identifier);
|
294
295
|
return this.subscriptions.notify(identifier, "connected");
|
295
296
|
|
296
297
|
case message_types.rejection:
|
@@ -360,10 +361,52 @@
|
|
360
361
|
};
|
361
362
|
return Subscription;
|
362
363
|
}();
|
364
|
+
var SubscriptionGuarantor = function() {
|
365
|
+
function SubscriptionGuarantor(subscriptions) {
|
366
|
+
classCallCheck(this, SubscriptionGuarantor);
|
367
|
+
this.subscriptions = subscriptions;
|
368
|
+
this.pendingSubscriptions = [];
|
369
|
+
}
|
370
|
+
SubscriptionGuarantor.prototype.guarantee = function guarantee(subscription) {
|
371
|
+
if (this.pendingSubscriptions.indexOf(subscription) == -1) {
|
372
|
+
logger.log("SubscriptionGuarantor guaranteeing " + subscription.identifier);
|
373
|
+
this.pendingSubscriptions.push(subscription);
|
374
|
+
} else {
|
375
|
+
logger.log("SubscriptionGuarantor already guaranteeing " + subscription.identifier);
|
376
|
+
}
|
377
|
+
this.startGuaranteeing();
|
378
|
+
};
|
379
|
+
SubscriptionGuarantor.prototype.forget = function forget(subscription) {
|
380
|
+
logger.log("SubscriptionGuarantor forgetting " + subscription.identifier);
|
381
|
+
this.pendingSubscriptions = this.pendingSubscriptions.filter(function(s) {
|
382
|
+
return s !== subscription;
|
383
|
+
});
|
384
|
+
};
|
385
|
+
SubscriptionGuarantor.prototype.startGuaranteeing = function startGuaranteeing() {
|
386
|
+
this.stopGuaranteeing();
|
387
|
+
this.retrySubscribing();
|
388
|
+
};
|
389
|
+
SubscriptionGuarantor.prototype.stopGuaranteeing = function stopGuaranteeing() {
|
390
|
+
clearTimeout(this.retryTimeout);
|
391
|
+
};
|
392
|
+
SubscriptionGuarantor.prototype.retrySubscribing = function retrySubscribing() {
|
393
|
+
var _this = this;
|
394
|
+
this.retryTimeout = setTimeout(function() {
|
395
|
+
if (_this.subscriptions && typeof _this.subscriptions.subscribe === "function") {
|
396
|
+
_this.pendingSubscriptions.map(function(subscription) {
|
397
|
+
logger.log("SubscriptionGuarantor resubscribing " + subscription.identifier);
|
398
|
+
_this.subscriptions.subscribe(subscription);
|
399
|
+
});
|
400
|
+
}
|
401
|
+
}, 500);
|
402
|
+
};
|
403
|
+
return SubscriptionGuarantor;
|
404
|
+
}();
|
363
405
|
var Subscriptions = function() {
|
364
406
|
function Subscriptions(consumer) {
|
365
407
|
classCallCheck(this, Subscriptions);
|
366
408
|
this.consumer = consumer;
|
409
|
+
this.guarantor = new SubscriptionGuarantor(this);
|
367
410
|
this.subscriptions = [];
|
368
411
|
}
|
369
412
|
Subscriptions.prototype.create = function create(channelName, mixin) {
|
@@ -378,7 +421,7 @@
|
|
378
421
|
this.subscriptions.push(subscription);
|
379
422
|
this.consumer.ensureActiveConnection();
|
380
423
|
this.notify(subscription, "initialized");
|
381
|
-
this.
|
424
|
+
this.subscribe(subscription);
|
382
425
|
return subscription;
|
383
426
|
};
|
384
427
|
Subscriptions.prototype.remove = function remove(subscription) {
|
@@ -397,6 +440,7 @@
|
|
397
440
|
});
|
398
441
|
};
|
399
442
|
Subscriptions.prototype.forget = function forget(subscription) {
|
443
|
+
this.guarantor.forget(subscription);
|
400
444
|
this.subscriptions = this.subscriptions.filter(function(s) {
|
401
445
|
return s !== subscription;
|
402
446
|
});
|
@@ -410,7 +454,7 @@
|
|
410
454
|
Subscriptions.prototype.reload = function reload() {
|
411
455
|
var _this2 = this;
|
412
456
|
return this.subscriptions.map(function(subscription) {
|
413
|
-
return _this2.
|
457
|
+
return _this2.subscribe(subscription);
|
414
458
|
});
|
415
459
|
};
|
416
460
|
Subscriptions.prototype.notifyAll = function notifyAll(callbackName) {
|
@@ -436,6 +480,18 @@
|
|
436
480
|
return typeof subscription[callbackName] === "function" ? subscription[callbackName].apply(subscription, args) : undefined;
|
437
481
|
});
|
438
482
|
};
|
483
|
+
Subscriptions.prototype.subscribe = function subscribe(subscription) {
|
484
|
+
if (this.sendCommand(subscription, "subscribe")) {
|
485
|
+
this.guarantor.guarantee(subscription);
|
486
|
+
}
|
487
|
+
};
|
488
|
+
Subscriptions.prototype.confirmSubscription = function confirmSubscription(identifier) {
|
489
|
+
var _this4 = this;
|
490
|
+
logger.log("Subscription confirmed " + identifier);
|
491
|
+
this.findAll(identifier).map(function(subscription) {
|
492
|
+
return _this4.guarantor.forget(subscription);
|
493
|
+
});
|
494
|
+
};
|
439
495
|
Subscriptions.prototype.sendCommand = function sendCommand(subscription, command) {
|
440
496
|
var identifier = subscription.identifier;
|
441
497
|
return this.consumer.send({
|
@@ -506,6 +562,7 @@
|
|
506
562
|
exports.INTERNAL = INTERNAL;
|
507
563
|
exports.Subscription = Subscription;
|
508
564
|
exports.Subscriptions = Subscriptions;
|
565
|
+
exports.SubscriptionGuarantor = SubscriptionGuarantor;
|
509
566
|
exports.adapters = adapters;
|
510
567
|
exports.createWebSocketURL = createWebSocketURL;
|
511
568
|
exports.logger = logger;
|
@@ -194,7 +194,7 @@ module ActionCable
|
|
194
194
|
end
|
195
195
|
|
196
196
|
private
|
197
|
-
# Called once a consumer has become a subscriber of the channel. Usually the place to
|
197
|
+
# Called once a consumer has become a subscriber of the channel. Usually the place to set up any streams
|
198
198
|
# you want this channel to be sending to the subscriber.
|
199
199
|
def subscribed # :doc:
|
200
200
|
# Override in subclasses
|
@@ -283,7 +283,7 @@ module ActionCable
|
|
283
283
|
|
284
284
|
def transmit_subscription_confirmation
|
285
285
|
unless subscription_confirmation_sent?
|
286
|
-
logger.
|
286
|
+
logger.debug "#{self.class.name} is transmitting the subscription confirmation"
|
287
287
|
|
288
288
|
ActiveSupport::Notifications.instrument("transmit_subscription_confirmation.action_cable", channel_class: self.class.name) do
|
289
289
|
connection.transmit identifier: @identifier, type: ActionCable::INTERNAL[:message_types][:confirmation]
|
@@ -298,7 +298,7 @@ module ActionCable
|
|
298
298
|
end
|
299
299
|
|
300
300
|
def transmit_subscription_rejection
|
301
|
-
logger.
|
301
|
+
logger.debug "#{self.class.name} is transmitting the subscription rejection"
|
302
302
|
|
303
303
|
ActiveSupport::Notifications.instrument("transmit_subscription_rejection.action_cable", channel_class: self.class.name) do
|
304
304
|
connection.transmit identifier: @identifier, type: ActionCable::INTERNAL[:message_types][:rejection]
|
@@ -14,7 +14,7 @@ module ActionCable
|
|
14
14
|
# Chats::AppearancesChannel.channel_name # => 'chats:appearances'
|
15
15
|
# FooChats::BarAppearancesChannel.channel_name # => 'foo_chats:bar_appearances'
|
16
16
|
def channel_name
|
17
|
-
@channel_name ||= name.
|
17
|
+
@channel_name ||= name.delete_suffix("Channel").gsub("::", ":").underscore
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -25,7 +25,7 @@ module ActionCable
|
|
25
25
|
#
|
26
26
|
# An example broadcasting for this channel looks like so:
|
27
27
|
#
|
28
|
-
# ActionCable.server.broadcast "comments_for_45", author: 'DHH', content: 'Rails is just swell'
|
28
|
+
# ActionCable.server.broadcast "comments_for_45", { author: 'DHH', content: 'Rails is just swell' }
|
29
29
|
#
|
30
30
|
# If you have a stream that is related to a model, then the broadcasting used can be generated from the model and channel.
|
31
31
|
# The following example would subscribe to a broadcasting like <tt>comments:Z2lkOi8vVGVzdEFwcC9Qb3N0LzE</tt>.
|
@@ -82,7 +82,7 @@ module ActionCable
|
|
82
82
|
# Build a stream handler by wrapping the user-provided callback with
|
83
83
|
# a decoder or defaulting to a JSON-decoding retransmitter.
|
84
84
|
handler = worker_pool_stream_handler(broadcasting, callback || block, coder: coder)
|
85
|
-
streams
|
85
|
+
streams[broadcasting] = handler
|
86
86
|
|
87
87
|
connection.server.event_loop.post do
|
88
88
|
pubsub.subscribe(broadcasting, handler, lambda do
|
@@ -102,6 +102,20 @@ module ActionCable
|
|
102
102
|
stream_from(broadcasting_for(model), callback || block, coder: coder)
|
103
103
|
end
|
104
104
|
|
105
|
+
# Unsubscribes streams from the named <tt>broadcasting</tt>.
|
106
|
+
def stop_stream_from(broadcasting)
|
107
|
+
callback = streams.delete(broadcasting)
|
108
|
+
if callback
|
109
|
+
pubsub.unsubscribe(broadcasting, callback)
|
110
|
+
logger.info "#{self.class.name} stopped streaming from #{broadcasting}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Unsubscribes streams for the <tt>model</tt>.
|
115
|
+
def stop_stream_for(model)
|
116
|
+
stop_stream_from(broadcasting_for(model))
|
117
|
+
end
|
118
|
+
|
105
119
|
# Unsubscribes all streams associated with this channel from the pubsub queue.
|
106
120
|
def stop_all_streams
|
107
121
|
streams.each do |broadcasting, callback|
|
@@ -110,11 +124,23 @@ module ActionCable
|
|
110
124
|
end.clear
|
111
125
|
end
|
112
126
|
|
127
|
+
# Calls stream_for if record is present, otherwise calls reject.
|
128
|
+
# This method is intended to be called when you're looking
|
129
|
+
# for a record based on a parameter, if its found it will start
|
130
|
+
# streaming. If the record is nil then it will reject the connection.
|
131
|
+
def stream_or_reject_for(record)
|
132
|
+
if record
|
133
|
+
stream_for record
|
134
|
+
else
|
135
|
+
reject
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
113
139
|
private
|
114
140
|
delegate :pubsub, to: :connection
|
115
141
|
|
116
142
|
def streams
|
117
|
-
@_streams ||=
|
143
|
+
@_streams ||= {}
|
118
144
|
end
|
119
145
|
|
120
146
|
# Always wrap the outermost handler to invoke the user handler on the
|
@@ -15,9 +15,9 @@ module ActionCable
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
# Stub
|
19
|
-
# Add public aliases for
|
20
|
-
#
|
18
|
+
# Stub +stream_from+ to track streams for the channel.
|
19
|
+
# Add public aliases for +subscription_confirmation_sent?+ and
|
20
|
+
# +subscription_rejected?+.
|
21
21
|
module ChannelStub
|
22
22
|
def confirmed?
|
23
23
|
subscription_confirmation_sent?
|
@@ -123,7 +123,7 @@ module ActionCable
|
|
123
123
|
# <b>connection</b>::
|
124
124
|
# An ActionCable::Channel::ConnectionStub, representing the current HTTP connection.
|
125
125
|
# <b>subscription</b>::
|
126
|
-
# An instance of the current channel, created when you call
|
126
|
+
# An instance of the current channel, created when you call +subscribe+.
|
127
127
|
# <b>transmissions</b>::
|
128
128
|
# A list of all messages that have been transmitted into the channel.
|
129
129
|
#
|
@@ -159,7 +159,7 @@ module ActionCable
|
|
159
159
|
# def test_speak
|
160
160
|
# subscribe room_id: rooms(:chat).id
|
161
161
|
#
|
162
|
-
#
|
162
|
+
# assert_broadcast_on(rooms(:chat), text: "Hello, Rails!") do
|
163
163
|
# perform :speak, message: "Hello, Rails!"
|
164
164
|
# end
|
165
165
|
# end
|
@@ -209,7 +209,7 @@ module ActionCable
|
|
209
209
|
end
|
210
210
|
end
|
211
211
|
|
212
|
-
#
|
212
|
+
# Set up test connection with the specified identifiers:
|
213
213
|
#
|
214
214
|
# class ApplicationCable < ActionCable::Connection::Base
|
215
215
|
# identified_by :user, :token
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "action_dispatch"
|
4
|
+
require "active_support/rescuable"
|
4
5
|
|
5
6
|
module ActionCable
|
6
7
|
module Connection
|
@@ -46,6 +47,7 @@ module ActionCable
|
|
46
47
|
include Identification
|
47
48
|
include InternalChannel
|
48
49
|
include Authorization
|
50
|
+
include ActiveSupport::Rescuable
|
49
51
|
|
50
52
|
attr_reader :server, :env, :subscriptions, :logger, :worker_pool, :protocol
|
51
53
|
delegate :event_loop, :pubsub, to: :server
|
@@ -21,6 +21,7 @@ module ActionCable
|
|
21
21
|
logger.error "Received unrecognized command in #{data.inspect}"
|
22
22
|
end
|
23
23
|
rescue Exception => e
|
24
|
+
@connection.rescue_with_handler(e)
|
24
25
|
logger.error "Could not execute command from (#{data.inspect}) [#{e.class} - #{e.message}]: #{e.backtrace.first(5).join(" | ")}"
|
25
26
|
end
|
26
27
|
|
@@ -85,7 +85,7 @@ module ActionCable
|
|
85
85
|
# end
|
86
86
|
# end
|
87
87
|
#
|
88
|
-
# +connect+ accepts additional information the HTTP request with the
|
88
|
+
# +connect+ accepts additional information about the HTTP request with the
|
89
89
|
# +params+, +headers+, +session+ and Rack +env+ options.
|
90
90
|
#
|
91
91
|
# def test_connect_with_headers_and_query_string
|
@@ -101,7 +101,7 @@ module ActionCable
|
|
101
101
|
# assert_equal "1", connection.user.id
|
102
102
|
# end
|
103
103
|
#
|
104
|
-
# You can also
|
104
|
+
# You can also set up the correct cookies before the connection request:
|
105
105
|
#
|
106
106
|
# def test_connect_with_cookies
|
107
107
|
# # Plain cookies:
|
data/lib/action_cable/engine.rb
CHANGED
@@ -30,7 +30,7 @@ module ActionCable
|
|
30
30
|
|
31
31
|
ActiveSupport.on_load(:action_cable) do
|
32
32
|
if (config_path = Pathname.new(app.config.paths["config/cable"].first)).exist?
|
33
|
-
self.cable = Rails.application.config_for(config_path).with_indifferent_access
|
33
|
+
self.cable = Rails.application.config_for(config_path).to_h.with_indifferent_access
|
34
34
|
end
|
35
35
|
|
36
36
|
previous_connection_class = connection_class
|
@@ -12,11 +12,11 @@ module ActionCable
|
|
12
12
|
# </head>
|
13
13
|
#
|
14
14
|
# This is then used by Action Cable to determine the URL of your WebSocket server.
|
15
|
-
# Your
|
15
|
+
# Your JavaScript can then connect to the server without needing to specify the
|
16
16
|
# URL directly:
|
17
17
|
#
|
18
|
-
#
|
19
|
-
#
|
18
|
+
# window.Cable = require("@rails/actioncable")
|
19
|
+
# window.App = {}
|
20
20
|
# App.cable = Cable.createConsumer()
|
21
21
|
#
|
22
22
|
# Make sure to specify the correct server location in each of your environment
|
@@ -45,7 +45,7 @@ module ActionCable
|
|
45
45
|
|
46
46
|
# Uses the internal channel to disconnect the connection.
|
47
47
|
def disconnect
|
48
|
-
server.broadcast internal_channel, type: "disconnect"
|
48
|
+
server.broadcast internal_channel, { type: "disconnect" }
|
49
49
|
end
|
50
50
|
|
51
51
|
# Returns all the identifiers that were applied to this connection.
|
@@ -27,7 +27,7 @@ module ActionCable
|
|
27
27
|
@remote_connections = @event_loop = @worker_pool = @pubsub = nil
|
28
28
|
end
|
29
29
|
|
30
|
-
# Called by Rack to
|
30
|
+
# Called by Rack to set up the server.
|
31
31
|
def call(env)
|
32
32
|
setup_heartbeat_timer
|
33
33
|
config.connection_class.call.new(self, env).process
|
@@ -40,7 +40,7 @@ module ActionCable
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def broadcast(message)
|
43
|
-
server.logger.debug "[ActionCable] Broadcasting to #{broadcasting}: #{message.inspect}"
|
43
|
+
server.logger.debug { "[ActionCable] Broadcasting to #{broadcasting}: #{message.inspect.truncate(300)}" }
|
44
44
|
|
45
45
|
payload = { broadcasting: broadcasting, message: message, coder: coder }
|
46
46
|
ActiveSupport::Notifications.instrument("broadcast.action_cable", payload) do
|
data/lib/action_cable/server.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
gem "pg", "
|
3
|
+
gem "pg", "~> 1.1"
|
4
4
|
require "pg"
|
5
5
|
require "thread"
|
6
6
|
require "digest/sha1"
|
@@ -42,6 +42,7 @@ module ActionCable
|
|
42
42
|
pg_conn = ar_conn.raw_connection
|
43
43
|
|
44
44
|
verify!(pg_conn)
|
45
|
+
pg_conn.exec("SET application_name = #{pg_conn.escape_identifier(identifier)}")
|
45
46
|
yield pg_conn
|
46
47
|
ensure
|
47
48
|
ar_conn.disconnect!
|
@@ -15,7 +15,6 @@ module ActionCable
|
|
15
15
|
# Overwrite this factory method for Redis connections if you want to use a different Redis library than the redis gem.
|
16
16
|
# This is needed, for example, when using Makara proxies for distributed Redis.
|
17
17
|
cattr_accessor :redis_connector, default: ->(config) do
|
18
|
-
config[:id] ||= "ActionCable-PID-#{$$}"
|
19
18
|
::Redis.new(config.except(:adapter, :channel_prefix))
|
20
19
|
end
|
21
20
|
|
@@ -57,7 +56,7 @@ module ActionCable
|
|
57
56
|
end
|
58
57
|
|
59
58
|
def redis_connection
|
60
|
-
self.class.redis_connector.call(@server.config.cable)
|
59
|
+
self.class.redis_connector.call(@server.config.cable.merge(id: identifier))
|
61
60
|
end
|
62
61
|
|
63
62
|
class Listener < SubscriberMap
|
@@ -42,10 +42,10 @@ module ActionCable
|
|
42
42
|
# end
|
43
43
|
# end
|
44
44
|
#
|
45
|
-
def assert_broadcasts(stream, number)
|
45
|
+
def assert_broadcasts(stream, number, &block)
|
46
46
|
if block_given?
|
47
47
|
original_count = broadcasts_size(stream)
|
48
|
-
|
48
|
+
assert_nothing_raised(&block)
|
49
49
|
new_count = broadcasts_size(stream)
|
50
50
|
actual_count = new_count - original_count
|
51
51
|
else
|
@@ -94,7 +94,7 @@ module ActionCable
|
|
94
94
|
# end
|
95
95
|
# end
|
96
96
|
#
|
97
|
-
def assert_broadcast_on(stream, data)
|
97
|
+
def assert_broadcast_on(stream, data, &block)
|
98
98
|
# Encode to JSON and back–we want to use this value to compare
|
99
99
|
# with decoded JSON.
|
100
100
|
# Comparing JSON strings doesn't work due to the order if the keys.
|
@@ -106,7 +106,7 @@ module ActionCable
|
|
106
106
|
old_messages = new_messages
|
107
107
|
clear_messages(stream)
|
108
108
|
|
109
|
-
|
109
|
+
assert_nothing_raised(&block)
|
110
110
|
new_messages = broadcasts(stream)
|
111
111
|
clear_messages(stream)
|
112
112
|
|
data/lib/action_cable.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2015-
|
4
|
+
# Copyright (c) 2015-2022 Basecamp, LLC
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -1,11 +1,11 @@
|
|
1
1
|
Description:
|
2
2
|
============
|
3
|
-
|
3
|
+
Generates a new cable channel for the server (in Ruby) and client (in JavaScript).
|
4
4
|
Pass the channel name, either CamelCased or under_scored, and an optional list of channel actions as arguments.
|
5
5
|
|
6
6
|
Example:
|
7
7
|
========
|
8
|
-
rails generate channel Chat speak
|
8
|
+
bin/rails generate channel Chat speak
|
9
9
|
|
10
10
|
creates a Chat channel class, test and JavaScript asset:
|
11
11
|
Channel: app/channels/chat_channel.rb
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// Action Cable provides the framework to deal with WebSockets in Rails.
|
2
|
-
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
|
2
|
+
// You can generate new channels where WebSocket features live using the `bin/rails generate channel` command.
|
3
3
|
|
4
4
|
import { createConsumer } from "@rails/actioncable"
|
5
5
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actioncable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.1.7.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pratik Naik
|
@@ -9,22 +9,36 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-08-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 6.1.7.6
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 6.1.7.6
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: actionpack
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
17
31
|
requirements:
|
18
32
|
- - '='
|
19
33
|
- !ruby/object:Gem::Version
|
20
|
-
version: 6.
|
34
|
+
version: 6.1.7.6
|
21
35
|
type: :runtime
|
22
36
|
prerelease: false
|
23
37
|
version_requirements: !ruby/object:Gem::Requirement
|
24
38
|
requirements:
|
25
39
|
- - '='
|
26
40
|
- !ruby/object:Gem::Version
|
27
|
-
version: 6.
|
41
|
+
version: 6.1.7.6
|
28
42
|
- !ruby/object:Gem::Dependency
|
29
43
|
name: nio4r
|
30
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,10 +140,10 @@ licenses:
|
|
126
140
|
- MIT
|
127
141
|
metadata:
|
128
142
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
129
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.
|
130
|
-
documentation_uri: https://api.rubyonrails.org/v6.
|
143
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.1.7.6/actioncable/CHANGELOG.md
|
144
|
+
documentation_uri: https://api.rubyonrails.org/v6.1.7.6/
|
131
145
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
132
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.
|
146
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.1.7.6/actioncable
|
133
147
|
rubygems_mfa_required: 'true'
|
134
148
|
post_install_message:
|
135
149
|
rdoc_options: []
|
@@ -146,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
160
|
- !ruby/object:Gem::Version
|
147
161
|
version: '0'
|
148
162
|
requirements: []
|
149
|
-
rubygems_version: 3.
|
163
|
+
rubygems_version: 3.3.3
|
150
164
|
signing_key:
|
151
165
|
specification_version: 4
|
152
166
|
summary: WebSocket framework for Rails.
|