@rails/actioncable 7.0.0-alpha2 → 7.0.0-rc1
Sign up to get free protection for your applications and to get access to all the features.
- package/app/assets/javascripts/action_cable.js +51 -2
- package/app/assets/javascripts/actioncable.esm.js +52 -3
- package/app/assets/javascripts/actioncable.js +51 -2
- package/package.json +3 -3
- package/src/connection.js +1 -0
- package/src/index.js +2 -0
- package/src/subscription_guarantor.js +50 -0
- package/src/subscriptions.js +18 -2
- package/CHANGELOG.md +0 -42
@@ -246,6 +246,7 @@
|
|
246
246
|
return this.monitor.recordPing();
|
247
247
|
|
248
248
|
case message_types.confirmation:
|
249
|
+
this.subscriptions.confirmSubscription(identifier);
|
249
250
|
return this.subscriptions.notify(identifier, "connected");
|
250
251
|
|
251
252
|
case message_types.rejection:
|
@@ -310,9 +311,46 @@
|
|
310
311
|
return this.consumer.subscriptions.remove(this);
|
311
312
|
}
|
312
313
|
}
|
314
|
+
class SubscriptionGuarantor {
|
315
|
+
constructor(subscriptions) {
|
316
|
+
this.subscriptions = subscriptions;
|
317
|
+
this.pendingSubscriptions = [];
|
318
|
+
}
|
319
|
+
guarantee(subscription) {
|
320
|
+
if (this.pendingSubscriptions.indexOf(subscription) == -1) {
|
321
|
+
logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
|
322
|
+
this.pendingSubscriptions.push(subscription);
|
323
|
+
} else {
|
324
|
+
logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
|
325
|
+
}
|
326
|
+
this.startGuaranteeing();
|
327
|
+
}
|
328
|
+
forget(subscription) {
|
329
|
+
logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
|
330
|
+
this.pendingSubscriptions = this.pendingSubscriptions.filter((s => s !== subscription));
|
331
|
+
}
|
332
|
+
startGuaranteeing() {
|
333
|
+
this.stopGuaranteeing();
|
334
|
+
this.retrySubscribing();
|
335
|
+
}
|
336
|
+
stopGuaranteeing() {
|
337
|
+
clearTimeout(this.retryTimeout);
|
338
|
+
}
|
339
|
+
retrySubscribing() {
|
340
|
+
this.retryTimeout = setTimeout((() => {
|
341
|
+
if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
|
342
|
+
this.pendingSubscriptions.map((subscription => {
|
343
|
+
logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
|
344
|
+
this.subscriptions.subscribe(subscription);
|
345
|
+
}));
|
346
|
+
}
|
347
|
+
}), 500);
|
348
|
+
}
|
349
|
+
}
|
313
350
|
class Subscriptions {
|
314
351
|
constructor(consumer) {
|
315
352
|
this.consumer = consumer;
|
353
|
+
this.guarantor = new SubscriptionGuarantor(this);
|
316
354
|
this.subscriptions = [];
|
317
355
|
}
|
318
356
|
create(channelName, mixin) {
|
@@ -327,7 +365,7 @@
|
|
327
365
|
this.subscriptions.push(subscription);
|
328
366
|
this.consumer.ensureActiveConnection();
|
329
367
|
this.notify(subscription, "initialized");
|
330
|
-
this.
|
368
|
+
this.subscribe(subscription);
|
331
369
|
return subscription;
|
332
370
|
}
|
333
371
|
remove(subscription) {
|
@@ -345,6 +383,7 @@
|
|
345
383
|
}));
|
346
384
|
}
|
347
385
|
forget(subscription) {
|
386
|
+
this.guarantor.forget(subscription);
|
348
387
|
this.subscriptions = this.subscriptions.filter((s => s !== subscription));
|
349
388
|
return subscription;
|
350
389
|
}
|
@@ -352,7 +391,7 @@
|
|
352
391
|
return this.subscriptions.filter((s => s.identifier === identifier));
|
353
392
|
}
|
354
393
|
reload() {
|
355
|
-
return this.subscriptions.map((subscription => this.
|
394
|
+
return this.subscriptions.map((subscription => this.subscribe(subscription)));
|
356
395
|
}
|
357
396
|
notifyAll(callbackName, ...args) {
|
358
397
|
return this.subscriptions.map((subscription => this.notify(subscription, callbackName, ...args)));
|
@@ -366,6 +405,15 @@
|
|
366
405
|
}
|
367
406
|
return subscriptions.map((subscription => typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined));
|
368
407
|
}
|
408
|
+
subscribe(subscription) {
|
409
|
+
if (this.sendCommand(subscription, "subscribe")) {
|
410
|
+
this.guarantor.guarantee(subscription);
|
411
|
+
}
|
412
|
+
}
|
413
|
+
confirmSubscription(identifier) {
|
414
|
+
logger.log(`Subscription confirmed ${identifier}`);
|
415
|
+
this.findAll(identifier).map((subscription => this.guarantor.forget(subscription)));
|
416
|
+
}
|
369
417
|
sendCommand(subscription, command) {
|
370
418
|
const {identifier: identifier} = subscription;
|
371
419
|
return this.consumer.send({
|
@@ -429,6 +477,7 @@
|
|
429
477
|
exports.Consumer = Consumer;
|
430
478
|
exports.INTERNAL = INTERNAL;
|
431
479
|
exports.Subscription = Subscription;
|
480
|
+
exports.SubscriptionGuarantor = SubscriptionGuarantor;
|
432
481
|
exports.Subscriptions = Subscriptions;
|
433
482
|
exports.adapters = adapters;
|
434
483
|
exports.createConsumer = createConsumer;
|
@@ -254,6 +254,7 @@ Connection.prototype.events = {
|
|
254
254
|
return this.monitor.recordPing();
|
255
255
|
|
256
256
|
case message_types.confirmation:
|
257
|
+
this.subscriptions.confirmSubscription(identifier);
|
257
258
|
return this.subscriptions.notify(identifier, "connected");
|
258
259
|
|
259
260
|
case message_types.rejection:
|
@@ -321,9 +322,47 @@ class Subscription {
|
|
321
322
|
}
|
322
323
|
}
|
323
324
|
|
325
|
+
class SubscriptionGuarantor {
|
326
|
+
constructor(subscriptions) {
|
327
|
+
this.subscriptions = subscriptions;
|
328
|
+
this.pendingSubscriptions = [];
|
329
|
+
}
|
330
|
+
guarantee(subscription) {
|
331
|
+
if (this.pendingSubscriptions.indexOf(subscription) == -1) {
|
332
|
+
logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
|
333
|
+
this.pendingSubscriptions.push(subscription);
|
334
|
+
} else {
|
335
|
+
logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
|
336
|
+
}
|
337
|
+
this.startGuaranteeing();
|
338
|
+
}
|
339
|
+
forget(subscription) {
|
340
|
+
logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
|
341
|
+
this.pendingSubscriptions = this.pendingSubscriptions.filter((s => s !== subscription));
|
342
|
+
}
|
343
|
+
startGuaranteeing() {
|
344
|
+
this.stopGuaranteeing();
|
345
|
+
this.retrySubscribing();
|
346
|
+
}
|
347
|
+
stopGuaranteeing() {
|
348
|
+
clearTimeout(this.retryTimeout);
|
349
|
+
}
|
350
|
+
retrySubscribing() {
|
351
|
+
this.retryTimeout = setTimeout((() => {
|
352
|
+
if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
|
353
|
+
this.pendingSubscriptions.map((subscription => {
|
354
|
+
logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
|
355
|
+
this.subscriptions.subscribe(subscription);
|
356
|
+
}));
|
357
|
+
}
|
358
|
+
}), 500);
|
359
|
+
}
|
360
|
+
}
|
361
|
+
|
324
362
|
class Subscriptions {
|
325
363
|
constructor(consumer) {
|
326
364
|
this.consumer = consumer;
|
365
|
+
this.guarantor = new SubscriptionGuarantor(this);
|
327
366
|
this.subscriptions = [];
|
328
367
|
}
|
329
368
|
create(channelName, mixin) {
|
@@ -338,7 +377,7 @@ class Subscriptions {
|
|
338
377
|
this.subscriptions.push(subscription);
|
339
378
|
this.consumer.ensureActiveConnection();
|
340
379
|
this.notify(subscription, "initialized");
|
341
|
-
this.
|
380
|
+
this.subscribe(subscription);
|
342
381
|
return subscription;
|
343
382
|
}
|
344
383
|
remove(subscription) {
|
@@ -356,6 +395,7 @@ class Subscriptions {
|
|
356
395
|
}));
|
357
396
|
}
|
358
397
|
forget(subscription) {
|
398
|
+
this.guarantor.forget(subscription);
|
359
399
|
this.subscriptions = this.subscriptions.filter((s => s !== subscription));
|
360
400
|
return subscription;
|
361
401
|
}
|
@@ -363,7 +403,7 @@ class Subscriptions {
|
|
363
403
|
return this.subscriptions.filter((s => s.identifier === identifier));
|
364
404
|
}
|
365
405
|
reload() {
|
366
|
-
return this.subscriptions.map((subscription => this.
|
406
|
+
return this.subscriptions.map((subscription => this.subscribe(subscription)));
|
367
407
|
}
|
368
408
|
notifyAll(callbackName, ...args) {
|
369
409
|
return this.subscriptions.map((subscription => this.notify(subscription, callbackName, ...args)));
|
@@ -377,6 +417,15 @@ class Subscriptions {
|
|
377
417
|
}
|
378
418
|
return subscriptions.map((subscription => typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined));
|
379
419
|
}
|
420
|
+
subscribe(subscription) {
|
421
|
+
if (this.sendCommand(subscription, "subscribe")) {
|
422
|
+
this.guarantor.guarantee(subscription);
|
423
|
+
}
|
424
|
+
}
|
425
|
+
confirmSubscription(identifier) {
|
426
|
+
logger.log(`Subscription confirmed ${identifier}`);
|
427
|
+
this.findAll(identifier).map((subscription => this.guarantor.forget(subscription)));
|
428
|
+
}
|
380
429
|
sendCommand(subscription, command) {
|
381
430
|
const {identifier: identifier} = subscription;
|
382
431
|
return this.consumer.send({
|
@@ -439,4 +488,4 @@ function getConfig(name) {
|
|
439
488
|
}
|
440
489
|
}
|
441
490
|
|
442
|
-
export { Connection, ConnectionMonitor, Consumer, INTERNAL, Subscription, Subscriptions, adapters, createConsumer, createWebSocketURL, getConfig, logger };
|
491
|
+
export { Connection, ConnectionMonitor, Consumer, INTERNAL, Subscription, SubscriptionGuarantor, Subscriptions, adapters, createConsumer, createWebSocketURL, getConfig, logger };
|
@@ -246,6 +246,7 @@
|
|
246
246
|
return this.monitor.recordPing();
|
247
247
|
|
248
248
|
case message_types.confirmation:
|
249
|
+
this.subscriptions.confirmSubscription(identifier);
|
249
250
|
return this.subscriptions.notify(identifier, "connected");
|
250
251
|
|
251
252
|
case message_types.rejection:
|
@@ -310,9 +311,46 @@
|
|
310
311
|
return this.consumer.subscriptions.remove(this);
|
311
312
|
}
|
312
313
|
}
|
314
|
+
class SubscriptionGuarantor {
|
315
|
+
constructor(subscriptions) {
|
316
|
+
this.subscriptions = subscriptions;
|
317
|
+
this.pendingSubscriptions = [];
|
318
|
+
}
|
319
|
+
guarantee(subscription) {
|
320
|
+
if (this.pendingSubscriptions.indexOf(subscription) == -1) {
|
321
|
+
logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
|
322
|
+
this.pendingSubscriptions.push(subscription);
|
323
|
+
} else {
|
324
|
+
logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
|
325
|
+
}
|
326
|
+
this.startGuaranteeing();
|
327
|
+
}
|
328
|
+
forget(subscription) {
|
329
|
+
logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
|
330
|
+
this.pendingSubscriptions = this.pendingSubscriptions.filter((s => s !== subscription));
|
331
|
+
}
|
332
|
+
startGuaranteeing() {
|
333
|
+
this.stopGuaranteeing();
|
334
|
+
this.retrySubscribing();
|
335
|
+
}
|
336
|
+
stopGuaranteeing() {
|
337
|
+
clearTimeout(this.retryTimeout);
|
338
|
+
}
|
339
|
+
retrySubscribing() {
|
340
|
+
this.retryTimeout = setTimeout((() => {
|
341
|
+
if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
|
342
|
+
this.pendingSubscriptions.map((subscription => {
|
343
|
+
logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
|
344
|
+
this.subscriptions.subscribe(subscription);
|
345
|
+
}));
|
346
|
+
}
|
347
|
+
}), 500);
|
348
|
+
}
|
349
|
+
}
|
313
350
|
class Subscriptions {
|
314
351
|
constructor(consumer) {
|
315
352
|
this.consumer = consumer;
|
353
|
+
this.guarantor = new SubscriptionGuarantor(this);
|
316
354
|
this.subscriptions = [];
|
317
355
|
}
|
318
356
|
create(channelName, mixin) {
|
@@ -327,7 +365,7 @@
|
|
327
365
|
this.subscriptions.push(subscription);
|
328
366
|
this.consumer.ensureActiveConnection();
|
329
367
|
this.notify(subscription, "initialized");
|
330
|
-
this.
|
368
|
+
this.subscribe(subscription);
|
331
369
|
return subscription;
|
332
370
|
}
|
333
371
|
remove(subscription) {
|
@@ -345,6 +383,7 @@
|
|
345
383
|
}));
|
346
384
|
}
|
347
385
|
forget(subscription) {
|
386
|
+
this.guarantor.forget(subscription);
|
348
387
|
this.subscriptions = this.subscriptions.filter((s => s !== subscription));
|
349
388
|
return subscription;
|
350
389
|
}
|
@@ -352,7 +391,7 @@
|
|
352
391
|
return this.subscriptions.filter((s => s.identifier === identifier));
|
353
392
|
}
|
354
393
|
reload() {
|
355
|
-
return this.subscriptions.map((subscription => this.
|
394
|
+
return this.subscriptions.map((subscription => this.subscribe(subscription)));
|
356
395
|
}
|
357
396
|
notifyAll(callbackName, ...args) {
|
358
397
|
return this.subscriptions.map((subscription => this.notify(subscription, callbackName, ...args)));
|
@@ -366,6 +405,15 @@
|
|
366
405
|
}
|
367
406
|
return subscriptions.map((subscription => typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined));
|
368
407
|
}
|
408
|
+
subscribe(subscription) {
|
409
|
+
if (this.sendCommand(subscription, "subscribe")) {
|
410
|
+
this.guarantor.guarantee(subscription);
|
411
|
+
}
|
412
|
+
}
|
413
|
+
confirmSubscription(identifier) {
|
414
|
+
logger.log(`Subscription confirmed ${identifier}`);
|
415
|
+
this.findAll(identifier).map((subscription => this.guarantor.forget(subscription)));
|
416
|
+
}
|
369
417
|
sendCommand(subscription, command) {
|
370
418
|
const {identifier: identifier} = subscription;
|
371
419
|
return this.consumer.send({
|
@@ -428,6 +476,7 @@
|
|
428
476
|
exports.Consumer = Consumer;
|
429
477
|
exports.INTERNAL = INTERNAL;
|
430
478
|
exports.Subscription = Subscription;
|
479
|
+
exports.SubscriptionGuarantor = SubscriptionGuarantor;
|
431
480
|
exports.Subscriptions = Subscriptions;
|
432
481
|
exports.adapters = adapters;
|
433
482
|
exports.createConsumer = createConsumer;
|
package/package.json
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
{
|
2
2
|
"name": "@rails/actioncable",
|
3
|
-
"version": "7.0.0-
|
3
|
+
"version": "7.0.0-rc1",
|
4
4
|
"description": "WebSocket framework for Ruby on Rails.",
|
5
|
-
"module": "app/
|
6
|
-
"main": "app/assets/javascripts/
|
5
|
+
"module": "app/assets/javascripts/actioncable.esm.js",
|
6
|
+
"main": "app/assets/javascripts/actioncable.js",
|
7
7
|
"files": [
|
8
8
|
"app/assets/javascripts/*.js",
|
9
9
|
"src/*.js"
|
package/src/connection.js
CHANGED
@@ -132,6 +132,7 @@ Connection.prototype.events = {
|
|
132
132
|
case message_types.ping:
|
133
133
|
return this.monitor.recordPing()
|
134
134
|
case message_types.confirmation:
|
135
|
+
this.subscriptions.confirmSubscription(identifier)
|
135
136
|
return this.subscriptions.notify(identifier, "connected")
|
136
137
|
case message_types.rejection:
|
137
138
|
return this.subscriptions.reject(identifier)
|
package/src/index.js
CHANGED
@@ -4,6 +4,7 @@ import Consumer, { createWebSocketURL } from "./consumer"
|
|
4
4
|
import INTERNAL from "./internal"
|
5
5
|
import Subscription from "./subscription"
|
6
6
|
import Subscriptions from "./subscriptions"
|
7
|
+
import SubscriptionGuarantor from "./subscription_guarantor"
|
7
8
|
import adapters from "./adapters"
|
8
9
|
import logger from "./logger"
|
9
10
|
|
@@ -14,6 +15,7 @@ export {
|
|
14
15
|
INTERNAL,
|
15
16
|
Subscription,
|
16
17
|
Subscriptions,
|
18
|
+
SubscriptionGuarantor,
|
17
19
|
adapters,
|
18
20
|
createWebSocketURL,
|
19
21
|
logger,
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import logger from "./logger"
|
2
|
+
|
3
|
+
// Responsible for ensuring channel subscribe command is confirmed, retrying until confirmation is received.
|
4
|
+
// Internal class, not intended for direct user manipulation.
|
5
|
+
|
6
|
+
class SubscriptionGuarantor {
|
7
|
+
constructor(subscriptions) {
|
8
|
+
this.subscriptions = subscriptions
|
9
|
+
this.pendingSubscriptions = []
|
10
|
+
}
|
11
|
+
|
12
|
+
guarantee(subscription) {
|
13
|
+
if(this.pendingSubscriptions.indexOf(subscription) == -1){
|
14
|
+
logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`)
|
15
|
+
this.pendingSubscriptions.push(subscription)
|
16
|
+
}
|
17
|
+
else {
|
18
|
+
logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`)
|
19
|
+
}
|
20
|
+
this.startGuaranteeing()
|
21
|
+
}
|
22
|
+
|
23
|
+
forget(subscription) {
|
24
|
+
logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`)
|
25
|
+
this.pendingSubscriptions = (this.pendingSubscriptions.filter((s) => s !== subscription))
|
26
|
+
}
|
27
|
+
|
28
|
+
startGuaranteeing() {
|
29
|
+
this.stopGuaranteeing()
|
30
|
+
this.retrySubscribing()
|
31
|
+
}
|
32
|
+
|
33
|
+
stopGuaranteeing() {
|
34
|
+
clearTimeout(this.retryTimeout)
|
35
|
+
}
|
36
|
+
|
37
|
+
retrySubscribing() {
|
38
|
+
this.retryTimeout = setTimeout(() => {
|
39
|
+
if (this.subscriptions && typeof(this.subscriptions.subscribe) === "function") {
|
40
|
+
this.pendingSubscriptions.map((subscription) => {
|
41
|
+
logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`)
|
42
|
+
this.subscriptions.subscribe(subscription)
|
43
|
+
})
|
44
|
+
}
|
45
|
+
}
|
46
|
+
, 500)
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
export default SubscriptionGuarantor
|
package/src/subscriptions.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
import Subscription from "./subscription"
|
2
|
+
import SubscriptionGuarantor from "./subscription_guarantor"
|
3
|
+
import logger from "./logger"
|
2
4
|
|
3
5
|
// Collection class for creating (and internally managing) channel subscriptions.
|
4
6
|
// The only method intended to be triggered by the user is ActionCable.Subscriptions#create,
|
@@ -13,6 +15,7 @@ import Subscription from "./subscription"
|
|
13
15
|
export default class Subscriptions {
|
14
16
|
constructor(consumer) {
|
15
17
|
this.consumer = consumer
|
18
|
+
this.guarantor = new SubscriptionGuarantor(this)
|
16
19
|
this.subscriptions = []
|
17
20
|
}
|
18
21
|
|
@@ -29,7 +32,7 @@ export default class Subscriptions {
|
|
29
32
|
this.subscriptions.push(subscription)
|
30
33
|
this.consumer.ensureActiveConnection()
|
31
34
|
this.notify(subscription, "initialized")
|
32
|
-
this.
|
35
|
+
this.subscribe(subscription)
|
33
36
|
return subscription
|
34
37
|
}
|
35
38
|
|
@@ -50,6 +53,7 @@ export default class Subscriptions {
|
|
50
53
|
}
|
51
54
|
|
52
55
|
forget(subscription) {
|
56
|
+
this.guarantor.forget(subscription)
|
53
57
|
this.subscriptions = (this.subscriptions.filter((s) => s !== subscription))
|
54
58
|
return subscription
|
55
59
|
}
|
@@ -60,7 +64,7 @@ export default class Subscriptions {
|
|
60
64
|
|
61
65
|
reload() {
|
62
66
|
return this.subscriptions.map((subscription) =>
|
63
|
-
this.
|
67
|
+
this.subscribe(subscription))
|
64
68
|
}
|
65
69
|
|
66
70
|
notifyAll(callbackName, ...args) {
|
@@ -80,6 +84,18 @@ export default class Subscriptions {
|
|
80
84
|
(typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined))
|
81
85
|
}
|
82
86
|
|
87
|
+
subscribe(subscription) {
|
88
|
+
if (this.sendCommand(subscription, "subscribe")) {
|
89
|
+
this.guarantor.guarantee(subscription)
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
confirmSubscription(identifier) {
|
94
|
+
logger.log(`Subscription confirmed ${identifier}`)
|
95
|
+
this.findAll(identifier).map((subscription) =>
|
96
|
+
this.guarantor.forget(subscription))
|
97
|
+
}
|
98
|
+
|
83
99
|
sendCommand(subscription, command) {
|
84
100
|
const {identifier} = subscription
|
85
101
|
return this.consumer.send({command, identifier})
|
package/CHANGELOG.md
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
## Rails 7.0.0.alpha2 (September 15, 2021) ##
|
2
|
-
|
3
|
-
* No changes.
|
4
|
-
|
5
|
-
|
6
|
-
## Rails 7.0.0.alpha1 (September 15, 2021) ##
|
7
|
-
|
8
|
-
* Compile ESM package that can be used directly in the browser as actioncable.esm.js.
|
9
|
-
|
10
|
-
*DHH*
|
11
|
-
|
12
|
-
* Move action_cable.js to actioncable.js to match naming convention used for other Rails frameworks, and use JS console to communicate the deprecation.
|
13
|
-
|
14
|
-
*DHH*
|
15
|
-
|
16
|
-
* Stop transpiling the UMD package generated as actioncable.js and drop the IE11 testing that relied on that.
|
17
|
-
|
18
|
-
*DHH*
|
19
|
-
|
20
|
-
* Truncate broadcast logging messages.
|
21
|
-
|
22
|
-
*J Smith*
|
23
|
-
|
24
|
-
* OpenSSL constants are now used for Digest computations.
|
25
|
-
|
26
|
-
*Dirkjan Bussink*
|
27
|
-
|
28
|
-
* The Action Cable client now includes safeguards to prevent a "thundering
|
29
|
-
herd" of client reconnects after server connectivity loss:
|
30
|
-
|
31
|
-
* The client will wait a random amount between 1x and 3x of the stale
|
32
|
-
threshold after the server's last ping before making the first
|
33
|
-
reconnection attempt.
|
34
|
-
* Subsequent reconnection attempts now use exponential backoff instead of
|
35
|
-
logarithmic backoff. To allow the delay between reconnection attempts to
|
36
|
-
increase slowly at first, the default exponentiation base is < 2.
|
37
|
-
* Random jitter is applied to each delay between reconnection attempts.
|
38
|
-
|
39
|
-
*Jonathan Hefner*
|
40
|
-
|
41
|
-
|
42
|
-
Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/actioncable/CHANGELOG.md) for previous changes.
|