hypha-rpc 0.20.85 → 0.20.86
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.
|
@@ -51,6 +51,31 @@ function _appendBuffer(buffer1, buffer2) {
|
|
|
51
51
|
return tmp.buffer;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Wrap a promise with a timeout.
|
|
56
|
+
* @param {Promise} promise - The promise to wrap.
|
|
57
|
+
* @param {number} timeoutMs - The timeout in milliseconds.
|
|
58
|
+
* @param {string} message - Optional error message for timeout.
|
|
59
|
+
* @returns {Promise} - The wrapped promise that will reject on timeout.
|
|
60
|
+
*/
|
|
61
|
+
function withTimeout(promise, timeoutMs, message = "Operation timed out") {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
const timeoutId = setTimeout(() => {
|
|
64
|
+
reject(new Error(`TimeoutError: ${message}`));
|
|
65
|
+
}, timeoutMs);
|
|
66
|
+
|
|
67
|
+
promise
|
|
68
|
+
.then((result) => {
|
|
69
|
+
clearTimeout(timeoutId);
|
|
70
|
+
resolve(result);
|
|
71
|
+
})
|
|
72
|
+
.catch((error) => {
|
|
73
|
+
clearTimeout(timeoutId);
|
|
74
|
+
reject(error);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
54
79
|
function indexObject(obj, is) {
|
|
55
80
|
if (!is) throw new Error("undefined index");
|
|
56
81
|
if (typeof is === "string") return indexObject(obj, is.split("."));
|
|
@@ -418,19 +443,35 @@ class RPC extends _utils_index_js__WEBPACK_IMPORTED_MODULE_0__.MessageEmitter {
|
|
|
418
443
|
let registeredCount = 0;
|
|
419
444
|
const failedServices = [];
|
|
420
445
|
|
|
446
|
+
// Use timeout for service registration to prevent hanging
|
|
447
|
+
const serviceRegistrationTimeout = this._method_timeout || 30000;
|
|
448
|
+
|
|
421
449
|
for (let service of services) {
|
|
422
450
|
try {
|
|
423
451
|
const serviceInfo = this._extract_service_info(service);
|
|
424
|
-
await
|
|
452
|
+
await withTimeout(
|
|
453
|
+
manager.registerService(serviceInfo),
|
|
454
|
+
serviceRegistrationTimeout,
|
|
455
|
+
`Timeout registering service ${service.id || "unknown"}`,
|
|
456
|
+
);
|
|
425
457
|
registeredCount++;
|
|
426
458
|
console.debug(
|
|
427
459
|
`Successfully registered service: ${service.id || "unknown"}`,
|
|
428
460
|
);
|
|
429
461
|
} catch (serviceError) {
|
|
430
462
|
failedServices.push(service.id || "unknown");
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
463
|
+
if (
|
|
464
|
+
serviceError.message &&
|
|
465
|
+
serviceError.message.includes("TimeoutError")
|
|
466
|
+
) {
|
|
467
|
+
console.error(
|
|
468
|
+
`Timeout registering service ${service.id || "unknown"}`,
|
|
469
|
+
);
|
|
470
|
+
} else {
|
|
471
|
+
console.error(
|
|
472
|
+
`Failed to register service ${service.id || "unknown"}: ${serviceError}`,
|
|
473
|
+
);
|
|
474
|
+
}
|
|
434
475
|
}
|
|
435
476
|
}
|
|
436
477
|
|
|
@@ -478,10 +519,12 @@ class RPC extends _utils_index_js__WEBPACK_IMPORTED_MODULE_0__.MessageEmitter {
|
|
|
478
519
|
}
|
|
479
520
|
};
|
|
480
521
|
|
|
481
|
-
// Subscribe to the event topic first
|
|
482
|
-
this._clientDisconnectedSubscription = await
|
|
483
|
-
"client_disconnected",
|
|
484
|
-
|
|
522
|
+
// Subscribe to the event topic first with timeout
|
|
523
|
+
this._clientDisconnectedSubscription = await withTimeout(
|
|
524
|
+
manager.subscribe(["client_disconnected"]),
|
|
525
|
+
serviceRegistrationTimeout,
|
|
526
|
+
"Timeout subscribing to client_disconnected events",
|
|
527
|
+
);
|
|
485
528
|
|
|
486
529
|
// Then register the local event handler
|
|
487
530
|
this.on("client_disconnected", handleClientDisconnected);
|
|
@@ -6278,12 +6321,22 @@ class WebsocketRPCConnection {
|
|
|
6278
6321
|
}
|
|
6279
6322
|
} catch (e) {
|
|
6280
6323
|
if (`${e}`.includes("ConnectionAbortedError:")) {
|
|
6281
|
-
console.warn("
|
|
6324
|
+
console.warn("Server refused to reconnect:", e);
|
|
6325
|
+
// Mark as closed and notify the application
|
|
6326
|
+
this._closed = true;
|
|
6327
|
+
if (this._handle_disconnected) {
|
|
6328
|
+
this._handle_disconnected(`Server refused reconnection: ${e}`);
|
|
6329
|
+
}
|
|
6282
6330
|
return;
|
|
6283
6331
|
} else if (`${e}`.includes("NotImplementedError:")) {
|
|
6284
6332
|
console.error(
|
|
6285
6333
|
`${e}\nIt appears that you are trying to connect to a hypha server that is older than 0.20.0, please upgrade the hypha server or use the websocket client in imjoy-rpc(https://www.npmjs.com/package/imjoy-rpc) instead`,
|
|
6286
6334
|
);
|
|
6335
|
+
// Mark as closed to prevent further reconnection attempts
|
|
6336
|
+
this._closed = true;
|
|
6337
|
+
if (this._handle_disconnected) {
|
|
6338
|
+
this._handle_disconnected(`Server too old: ${e}`);
|
|
6339
|
+
}
|
|
6287
6340
|
return;
|
|
6288
6341
|
}
|
|
6289
6342
|
|
|
@@ -6337,21 +6390,20 @@ class WebsocketRPCConnection {
|
|
|
6337
6390
|
await reconnect();
|
|
6338
6391
|
} else {
|
|
6339
6392
|
console.error(
|
|
6340
|
-
`Failed to reconnect after ${MAX_RETRY} attempts, giving up
|
|
6393
|
+
`Failed to reconnect after ${MAX_RETRY} attempts, giving up.`,
|
|
6341
6394
|
);
|
|
6395
|
+
// Mark as closed to prevent further reconnection attempts
|
|
6396
|
+
this._closed = true;
|
|
6342
6397
|
// Notify about max retry exceeded
|
|
6343
6398
|
if (this._handle_disconnected) {
|
|
6344
6399
|
this._handle_disconnected(
|
|
6345
6400
|
"Max reconnection attempts exceeded",
|
|
6346
6401
|
);
|
|
6347
6402
|
}
|
|
6348
|
-
//
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
);
|
|
6353
|
-
process.exit(1);
|
|
6354
|
-
}
|
|
6403
|
+
// Note: We intentionally do NOT call process.exit() here.
|
|
6404
|
+
// Instead, we mark the connection as closed and let the
|
|
6405
|
+
// application handle the failure through the disconnected
|
|
6406
|
+
// handler or by checking connection state.
|
|
6355
6407
|
}
|
|
6356
6408
|
}, finalDelay);
|
|
6357
6409
|
this._reconnect_timeouts.add(timeoutId);
|