@testdriverai/runner 7.8.0-test.47 → 7.8.0-test.48
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 +40 -2
- package/package.json +1 -1
package/lib/ably-service.js
CHANGED
|
@@ -275,6 +275,9 @@ class AblyService extends EventEmitter {
|
|
|
275
275
|
|
|
276
276
|
this.emit('log', `Command received: ${type} (requestId=${requestId})`);
|
|
277
277
|
|
|
278
|
+
// Stop re-publishing runner.ready once we get the first command
|
|
279
|
+
this._stopReadySignal();
|
|
280
|
+
|
|
278
281
|
// Per-command timeout: use message.timeout if provided, else default 120s
|
|
279
282
|
// Prevents hanging forever if screenshot capture or S3 upload stalls
|
|
280
283
|
const commandTimeout = (message.timeout && message.timeout > 0)
|
|
@@ -415,8 +418,8 @@ class AblyService extends EventEmitter {
|
|
|
415
418
|
|
|
416
419
|
// Detect discontinuity: channel re-attached but message continuity was lost.
|
|
417
420
|
// Use historyBeforeSubscribe() on each subscription to recover missed messages.
|
|
418
|
-
if (current === 'attached' && stateChange.resumed === false && previous) {
|
|
419
|
-
this.emit('log', `Ably channel [session]: DISCONTINUITY (resumed=false)${reasonMsg ? ' — ' + reasonMsg : ''}`);
|
|
421
|
+
if (current === 'attached' && stateChange.resumed === false && previous === 'attached') {
|
|
422
|
+
this.emit('log', `Ably channel [session]: DISCONTINUITY (resumed=false)${reasonMsg ? ' — ' + reasonMsg : ''}`);
|
|
420
423
|
|
|
421
424
|
Sentry.withScope((scope) => {
|
|
422
425
|
scope.setTag('ably.client', 'runner');
|
|
@@ -473,6 +476,39 @@ class AblyService extends EventEmitter {
|
|
|
473
476
|
}
|
|
474
477
|
await this._sessionChannel.publish('control', readyPayload);
|
|
475
478
|
this.emit('log', 'Published runner.ready signal');
|
|
479
|
+
|
|
480
|
+
// Re-publish runner.ready every 3s for up to 60s.
|
|
481
|
+
// The SDK may connect after the first publish (race condition),
|
|
482
|
+
// and Ably channel history may not be enabled. Repeating ensures
|
|
483
|
+
// the SDK catches at least one live runner.ready message.
|
|
484
|
+
this._readyInterval = setInterval(async () => {
|
|
485
|
+
try {
|
|
486
|
+
readyPayload.timestamp = Date.now();
|
|
487
|
+
await this._sessionChannel.publish('control', readyPayload);
|
|
488
|
+
this.emit('log', 'Re-published runner.ready signal');
|
|
489
|
+
} catch (err) {
|
|
490
|
+
this.emit('log', `Failed to re-publish runner.ready: ${err.message}`);
|
|
491
|
+
}
|
|
492
|
+
}, 3000);
|
|
493
|
+
|
|
494
|
+
// Stop after 60s regardless
|
|
495
|
+
this._readyTimeout = setTimeout(() => {
|
|
496
|
+
this._stopReadySignal();
|
|
497
|
+
}, 60000);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Stop the repeated runner.ready signal (called on first command or after timeout).
|
|
502
|
+
*/
|
|
503
|
+
_stopReadySignal() {
|
|
504
|
+
if (this._readyInterval) {
|
|
505
|
+
clearInterval(this._readyInterval);
|
|
506
|
+
this._readyInterval = null;
|
|
507
|
+
}
|
|
508
|
+
if (this._readyTimeout) {
|
|
509
|
+
clearTimeout(this._readyTimeout);
|
|
510
|
+
this._readyTimeout = null;
|
|
511
|
+
}
|
|
476
512
|
}
|
|
477
513
|
|
|
478
514
|
/**
|
|
@@ -617,6 +653,8 @@ class AblyService extends EventEmitter {
|
|
|
617
653
|
async close() {
|
|
618
654
|
this.emit('log', 'Closing Ably service...');
|
|
619
655
|
|
|
656
|
+
this._stopReadySignal();
|
|
657
|
+
|
|
620
658
|
if (this._statsInterval) {
|
|
621
659
|
clearInterval(this._statsInterval);
|
|
622
660
|
this._statsInterval = null;
|