@ricsam/isolate 0.1.7 → 0.1.10

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.
@@ -311,6 +311,45 @@ function logRuntimeLifecycle(state, event, instance, reason, level = "log") {
311
311
  const reasonSuffix = reason ? `: ${reason}` : "";
312
312
  logger(`[isolate-daemon] ${event} runtime ${import_runtime_pool.formatRuntimeLabel(instance)}${poisonedSuffix}${reasonSuffix}; ${import_runtime_pool.formatRuntimePoolSnapshot(import_runtime_pool.collectRuntimePoolSnapshot(state))}`);
313
313
  }
314
+ function formatDebugValue(value) {
315
+ if (typeof value === "string") {
316
+ return JSON.stringify(value);
317
+ }
318
+ if (typeof value === "number" || typeof value === "boolean" || value === null) {
319
+ return String(value);
320
+ }
321
+ try {
322
+ return JSON.stringify(value);
323
+ } catch {
324
+ return JSON.stringify(String(value));
325
+ }
326
+ }
327
+ function formatDebugFields(fields) {
328
+ return Object.entries(fields).filter(([, value]) => value !== undefined).map(([key, value]) => `${key}=${formatDebugValue(value)}`).join(" ");
329
+ }
330
+ function isDisposedOperationError(error) {
331
+ const text = getErrorText(error).toLowerCase();
332
+ return text.includes("disposed");
333
+ }
334
+ function buildRuntimeDebugFields(instance, connection, extras = {}) {
335
+ return {
336
+ isolateId: instance.isolateId,
337
+ namespaceId: instance.namespaceId ?? null,
338
+ pooled: instance.isDisposed,
339
+ ownerMatches: instance.ownerConnection === connection.socket,
340
+ connectionOwnsIsolate: connection.isolates.has(instance.isolateId),
341
+ runtimeAbortAborted: instance.runtimeAbortController?.signal.aborted ?? null,
342
+ disposedForMs: instance.disposedAt !== undefined ? Date.now() - instance.disposedAt : null,
343
+ callbackConnectionPresent: !!instance.callbackContext?.connection,
344
+ reconnectPending: !!instance.callbackContext?.reconnectionPromise,
345
+ callbackRegistrations: instance.callbacks.size,
346
+ ...extras
347
+ };
348
+ }
349
+ function logSuspiciousRuntimeOperation(state, operation, instance, connection, extras = {}, level = "warn") {
350
+ const logger = level === "warn" ? console.warn : console.log;
351
+ logger(`[isolate-daemon] ${operation} runtime ${import_runtime_pool.formatRuntimeLabel(instance)}; ${import_runtime_pool.formatRuntimePoolSnapshot(import_runtime_pool.collectRuntimePoolSnapshot(state))} ${formatDebugFields(buildRuntimeDebugFields(instance, connection, extras))}`);
352
+ }
314
353
  async function hardDeleteRuntime(instance, state, reason) {
315
354
  const wasPooled = instance.isDisposed;
316
355
  try {
@@ -343,6 +382,8 @@ async function hardDeleteRuntime(instance, state, reason) {
343
382
  }
344
383
  var RECONNECTION_TIMEOUT_MS = 30000;
345
384
  function softDeleteRuntime(instance, state, reason) {
385
+ const runtimeAbortWasAborted = instance.runtimeAbortController?.signal.aborted ?? false;
386
+ const hadCallbackConnection = !!instance.callbackContext?.connection;
346
387
  if (instance.runtimeAbortController && !instance.runtimeAbortController.signal.aborted) {
347
388
  instance.runtimeAbortController.abort(new Error(reason ?? "Runtime was soft-disposed"));
348
389
  }
@@ -380,8 +421,19 @@ function softDeleteRuntime(instance, state, reason) {
380
421
  instance.returnedIterators?.clear();
381
422
  instance.runtime.clearModuleCache();
382
423
  logRuntimeLifecycle(state, "soft-disposed", instance, reason);
424
+ console.warn(`[isolate-daemon] soft-dispose state runtime ${import_runtime_pool.formatRuntimeLabel(instance)}; ${import_runtime_pool.formatRuntimePoolSnapshot(import_runtime_pool.collectRuntimePoolSnapshot(state))} ${formatDebugFields({
425
+ runtimeAbortWasAborted,
426
+ runtimeAbortAborted: instance.runtimeAbortController?.signal.aborted ?? null,
427
+ hadCallbackConnection,
428
+ callbackConnectionPresent: !!instance.callbackContext?.connection,
429
+ reconnectPending: !!instance.callbackContext?.reconnectionPromise,
430
+ callbackRegistrations: instance.callbacks.size
431
+ })}`);
383
432
  }
384
433
  function reuseNamespacedRuntime(instance, connection, message, state) {
434
+ const disposedForMs = instance.disposedAt !== undefined ? Date.now() - instance.disposedAt : null;
435
+ const runtimeAbortWasAborted = instance.runtimeAbortController?.signal.aborted ?? false;
436
+ const reconnectWasPending = !!instance.callbackContext?.reconnectionPromise;
385
437
  instance.ownerConnection = connection.socket;
386
438
  instance.isDisposed = false;
387
439
  instance.isPoisoned = false;
@@ -492,6 +544,11 @@ function reuseNamespacedRuntime(instance, connection, message, state) {
492
544
  instance.returnedIterators = new Map;
493
545
  instance.nextLocalCallbackId = 1e6;
494
546
  logRuntimeLifecycle(state, "reused pooled", instance);
547
+ logSuspiciousRuntimeOperation(state, "reuse state", instance, connection, {
548
+ disposedForMs,
549
+ runtimeAbortWasAborted,
550
+ reconnectWasPending
551
+ }, "log");
495
552
  }
496
553
  async function waitForConnection(callbackContext) {
497
554
  if (callbackContext.connection) {
@@ -1162,6 +1219,12 @@ async function handleDispatchRequest(message, connection, state) {
1162
1219
  sendError(connection.socket, message.requestId, import_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
1163
1220
  return;
1164
1221
  }
1222
+ if (instance.isDisposed) {
1223
+ logSuspiciousRuntimeOperation(state, "dispatchRequest received for pooled", instance, connection, {
1224
+ method: message.request.method,
1225
+ url: message.request.url
1226
+ });
1227
+ }
1165
1228
  instance.lastActivity = Date.now();
1166
1229
  const dispatchAbortController = new AbortController;
1167
1230
  connection.dispatchAbortControllers.set(message.requestId, dispatchAbortController);
@@ -1207,6 +1270,13 @@ async function handleDispatchRequest(message, connection, state) {
1207
1270
  }
1208
1271
  } catch (err) {
1209
1272
  const error = err;
1273
+ if (instance.isDisposed || isDisposedOperationError(error)) {
1274
+ logSuspiciousRuntimeOperation(state, "dispatchRequest failed", instance, connection, {
1275
+ method: message.request.method,
1276
+ url: message.request.url,
1277
+ error: error.message
1278
+ });
1279
+ }
1210
1280
  sendError(connection.socket, message.requestId, import_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
1211
1281
  } finally {
1212
1282
  connection.dispatchAbortControllers.delete(message.requestId);
@@ -1325,12 +1395,20 @@ async function handleFetchGetUpgradeRequest(message, connection, state) {
1325
1395
  sendError(connection.socket, message.requestId, import_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
1326
1396
  return;
1327
1397
  }
1398
+ if (instance.isDisposed) {
1399
+ logSuspiciousRuntimeOperation(state, "getUpgradeRequest received for pooled", instance, connection);
1400
+ }
1328
1401
  instance.lastActivity = Date.now();
1329
1402
  try {
1330
1403
  const upgradeRequest = instance.runtime.fetch.getUpgradeRequest();
1331
1404
  sendOk(connection.socket, message.requestId, upgradeRequest);
1332
1405
  } catch (err) {
1333
1406
  const error = err;
1407
+ if (instance.isDisposed || isDisposedOperationError(error)) {
1408
+ logSuspiciousRuntimeOperation(state, "getUpgradeRequest failed", instance, connection, {
1409
+ error: error.message
1410
+ });
1411
+ }
1334
1412
  sendError(connection.socket, message.requestId, import_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
1335
1413
  }
1336
1414
  }
@@ -1340,12 +1418,20 @@ async function handleFetchHasServeHandler(message, connection, state) {
1340
1418
  sendError(connection.socket, message.requestId, import_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
1341
1419
  return;
1342
1420
  }
1421
+ if (instance.isDisposed) {
1422
+ logSuspiciousRuntimeOperation(state, "hasServeHandler received for pooled", instance, connection);
1423
+ }
1343
1424
  instance.lastActivity = Date.now();
1344
1425
  try {
1345
1426
  const hasHandler = instance.runtime.fetch.hasServeHandler();
1346
1427
  sendOk(connection.socket, message.requestId, hasHandler);
1347
1428
  } catch (err) {
1348
1429
  const error = err;
1430
+ if (instance.isDisposed || isDisposedOperationError(error)) {
1431
+ logSuspiciousRuntimeOperation(state, "hasServeHandler failed", instance, connection, {
1432
+ error: error.message
1433
+ });
1434
+ }
1349
1435
  sendError(connection.socket, message.requestId, import_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
1350
1436
  }
1351
1437
  }
@@ -1355,12 +1441,20 @@ async function handleFetchHasActiveConnections(message, connection, state) {
1355
1441
  sendError(connection.socket, message.requestId, import_protocol.ErrorCode.ISOLATE_NOT_FOUND, `Isolate not found: ${message.isolateId}`);
1356
1442
  return;
1357
1443
  }
1444
+ if (instance.isDisposed) {
1445
+ logSuspiciousRuntimeOperation(state, "hasActiveConnections received for pooled", instance, connection);
1446
+ }
1358
1447
  instance.lastActivity = Date.now();
1359
1448
  try {
1360
1449
  const hasConnections = instance.runtime.fetch.hasActiveConnections();
1361
1450
  sendOk(connection.socket, message.requestId, hasConnections);
1362
1451
  } catch (err) {
1363
1452
  const error = err;
1453
+ if (instance.isDisposed || isDisposedOperationError(error)) {
1454
+ logSuspiciousRuntimeOperation(state, "hasActiveConnections failed", instance, connection, {
1455
+ error: error.message
1456
+ });
1457
+ }
1364
1458
  sendError(connection.socket, message.requestId, import_protocol.ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
1365
1459
  }
1366
1460
  }
@@ -2014,4 +2108,4 @@ async function handleClearCollectedData(message, connection, state) {
2014
2108
  }
2015
2109
  }
2016
2110
 
2017
- //# debugId=0C2C837A78ED90B564756E2164756E21
2111
+ //# debugId=E087502A37B0261064756E2164756E21