@testdriverai/runner 7.9.11-test → 7.9.14-test
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.
- package/lib/ably-service.js +19 -3
- package/package.json +1 -1
package/lib/ably-service.js
CHANGED
|
@@ -164,6 +164,7 @@ class AblyService extends EventEmitter {
|
|
|
164
164
|
this._sessionChannel = null;
|
|
165
165
|
this._connected = false;
|
|
166
166
|
this._statsInterval = null;
|
|
167
|
+
this._closed = false; // set to true in close() to suppress post-close events
|
|
167
168
|
}
|
|
168
169
|
|
|
169
170
|
/**
|
|
@@ -367,7 +368,10 @@ class AblyService extends EventEmitter {
|
|
|
367
368
|
if (current === 'disconnected') {
|
|
368
369
|
this._connected = false;
|
|
369
370
|
this.emit('log', `Realtime connection: ${previous} → ${current}${reasonMsg ? ' — ' + reasonMsg : ''}${retryIn ? ' (retryIn=' + retryIn + 'ms)' : ''}`);
|
|
370
|
-
|
|
371
|
+
// Suppress auto-reconnect message when we've already initiated a clean close
|
|
372
|
+
if (!this._closed) {
|
|
373
|
+
this.emit('log', 'Ably disconnected — will auto-reconnect');
|
|
374
|
+
}
|
|
371
375
|
} else if (current === 'connected' && previous !== 'initialized') {
|
|
372
376
|
if (!this._connected) {
|
|
373
377
|
this._connected = true;
|
|
@@ -390,8 +394,8 @@ class AblyService extends EventEmitter {
|
|
|
390
394
|
this.emit('log', `Realtime connection: ${previous} → ${current}${reasonMsg ? ' — ' + reasonMsg : ''}`);
|
|
391
395
|
}
|
|
392
396
|
|
|
393
|
-
// Capture exceptions for bad states
|
|
394
|
-
if (current === 'failed' || current === 'suspended' || (current === 'disconnected' && reason)) {
|
|
397
|
+
// Capture exceptions for bad states — skip if we're in a clean close sequence
|
|
398
|
+
if (!this._closed && (current === 'failed' || current === 'suspended' || (current === 'disconnected' && reason))) {
|
|
395
399
|
Sentry.withScope((scope) => {
|
|
396
400
|
scope.setTag('ably.client', 'runner');
|
|
397
401
|
scope.setTag('ably.state', current);
|
|
@@ -579,6 +583,10 @@ class AblyService extends EventEmitter {
|
|
|
579
583
|
* so that missed commands are actually executed.
|
|
580
584
|
*/
|
|
581
585
|
async _recoverFromDiscontinuity() {
|
|
586
|
+
// Don't attempt recovery after an intentional close — subscriptions are
|
|
587
|
+
// nulled out in close() and the channel is being torn down
|
|
588
|
+
if (this._closed) return;
|
|
589
|
+
|
|
582
590
|
const subs = [
|
|
583
591
|
{ name: 'command', sub: this._commandSubscription, handler: this._onCommandMsg },
|
|
584
592
|
{ name: 'control', sub: this._controlSubscription, handler: this._onControlMsg },
|
|
@@ -668,6 +676,9 @@ class AblyService extends EventEmitter {
|
|
|
668
676
|
* Disconnect from Ably and clean up.
|
|
669
677
|
*/
|
|
670
678
|
async close() {
|
|
679
|
+
if (this._closed) return; // Prevent double-close
|
|
680
|
+
this._closed = true;
|
|
681
|
+
|
|
671
682
|
this.emit('log', 'Closing realtime service...');
|
|
672
683
|
|
|
673
684
|
this._stopReadySignal();
|
|
@@ -677,6 +688,11 @@ class AblyService extends EventEmitter {
|
|
|
677
688
|
this._statsInterval = null;
|
|
678
689
|
}
|
|
679
690
|
|
|
691
|
+
// Null out subscription refs so _recoverFromDiscontinuity won't replay
|
|
692
|
+
// messages on a channel that is about to be torn down
|
|
693
|
+
this._commandSubscription = null;
|
|
694
|
+
this._controlSubscription = null;
|
|
695
|
+
|
|
680
696
|
try {
|
|
681
697
|
if (this._sessionChannel) this._sessionChannel.detach();
|
|
682
698
|
} catch { }
|