@testdriverai/mcp 7.8.0-test.42 → 7.8.0-test.44
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/agent/lib/sandbox.js +52 -2
- package/package.json +1 -1
package/agent/lib/sandbox.js
CHANGED
|
@@ -29,6 +29,7 @@ const createSandbox = function (emitter, analytics, sessionInstance) {
|
|
|
29
29
|
this._lastConnectParams = null;
|
|
30
30
|
this._teamId = null;
|
|
31
31
|
this._sandboxId = null;
|
|
32
|
+
this._disconnectedAt = null; // tracks when Ably connection dropped (for timeout extension on reconnect)
|
|
32
33
|
|
|
33
34
|
// Rate limiting state for Ably publishes (Ably limits to 50 msg/sec per connection)
|
|
34
35
|
this._publishLastTime = 0;
|
|
@@ -260,11 +261,32 @@ const createSandbox = function (emitter, analytics, sessionInstance) {
|
|
|
260
261
|
|
|
261
262
|
this._ably.connection.on("disconnected", function () {
|
|
262
263
|
logger.log("[ably] Connection: disconnected - will auto-reconnect");
|
|
264
|
+
self._disconnectedAt = Date.now();
|
|
263
265
|
});
|
|
264
266
|
|
|
265
267
|
this._ably.connection.on("connected", function () {
|
|
266
268
|
// Log reconnection so the user knows the blip was recovered
|
|
267
269
|
logger.log("[ably] Connection: reconnected");
|
|
270
|
+
// Extend any pending command timeouts by the disconnection duration so
|
|
271
|
+
// commands whose timer was counting down while the connection was down
|
|
272
|
+
// don't get incorrectly timed out.
|
|
273
|
+
if (self._disconnectedAt) {
|
|
274
|
+
var disconnectionDurationMs = Date.now() - self._disconnectedAt;
|
|
275
|
+
self._disconnectedAt = null;
|
|
276
|
+
var pendingIds = Object.keys(self.ps);
|
|
277
|
+
if (pendingIds.length > 0) {
|
|
278
|
+
logger.log(
|
|
279
|
+
'[ably] Extending ' + pendingIds.length + ' pending timeout(s) by ' +
|
|
280
|
+
disconnectionDurationMs + 'ms after disconnection'
|
|
281
|
+
);
|
|
282
|
+
for (var i = 0; i < pendingIds.length; i++) {
|
|
283
|
+
var entry = self.ps[pendingIds[i]];
|
|
284
|
+
if (entry && typeof entry.extendTimeout === 'function') {
|
|
285
|
+
entry.extendTimeout(disconnectionDurationMs);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
268
290
|
});
|
|
269
291
|
|
|
270
292
|
this._ably.connection.on("suspended", function () {
|
|
@@ -829,7 +851,12 @@ const createSandbox = function (emitter, analytics, sessionInstance) {
|
|
|
829
851
|
|
|
830
852
|
var requestId = message.requestId;
|
|
831
853
|
|
|
832
|
-
|
|
854
|
+
// timeoutId and timeoutExpiresAt are declared as vars so they can be
|
|
855
|
+
// updated by extendTimeout() (closure mutation).
|
|
856
|
+
var timeoutId;
|
|
857
|
+
var timeoutExpiresAt;
|
|
858
|
+
|
|
859
|
+
var timeoutFn = function () {
|
|
833
860
|
if (self.ps[requestId]) {
|
|
834
861
|
var pendingIds = Object.keys(self.ps);
|
|
835
862
|
var pendingSummary = pendingIds.map(function (rid) {
|
|
@@ -855,7 +882,10 @@ const createSandbox = function (emitter, analytics, sessionInstance) {
|
|
|
855
882
|
),
|
|
856
883
|
);
|
|
857
884
|
}
|
|
858
|
-
}
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
timeoutId = setTimeout(timeoutFn, timeout);
|
|
888
|
+
timeoutExpiresAt = Date.now() + timeout;
|
|
859
889
|
if (timeoutId.unref) timeoutId.unref();
|
|
860
890
|
|
|
861
891
|
this.ps[requestId] = {
|
|
@@ -868,6 +898,26 @@ const createSandbox = function (emitter, analytics, sessionInstance) {
|
|
|
868
898
|
clearTimeout(timeoutId);
|
|
869
899
|
rejectPromise(error);
|
|
870
900
|
},
|
|
901
|
+
/**
|
|
902
|
+
* Extend the pending timeout by disconnectionDurationMs — called on Ably reconnect
|
|
903
|
+
* to compensate for time spent disconnected.
|
|
904
|
+
*/
|
|
905
|
+
extendTimeout: function (disconnectionDurationMs) {
|
|
906
|
+
clearTimeout(timeoutId);
|
|
907
|
+
// Clamp remaining to 0 so a command whose timer expired during the
|
|
908
|
+
// outage still gets the full disconnection duration as its new budget.
|
|
909
|
+
var remaining = Math.max(0, timeoutExpiresAt - Date.now());
|
|
910
|
+
// Minimum 5s remaining after extension to allow the response to arrive.
|
|
911
|
+
var MIN_REMAINING_MS = 5000;
|
|
912
|
+
var newRemaining = Math.max(remaining + disconnectionDurationMs, MIN_REMAINING_MS);
|
|
913
|
+
timeoutExpiresAt = Date.now() + newRemaining;
|
|
914
|
+
timeoutId = setTimeout(timeoutFn, newRemaining);
|
|
915
|
+
if (timeoutId.unref) timeoutId.unref();
|
|
916
|
+
logger.log(
|
|
917
|
+
'[ably] Extended timeout for requestId=' + requestId +
|
|
918
|
+
' by ' + disconnectionDurationMs + 'ms (new remaining: ' + Math.round(newRemaining / 1000) + 's)'
|
|
919
|
+
);
|
|
920
|
+
},
|
|
871
921
|
message: message,
|
|
872
922
|
startTime: Date.now(),
|
|
873
923
|
};
|