Skip to content

fix(data-process): fix crash-loop detection and renderer hang on give-up - #10388

Open
jackkav wants to merge 1 commit into
feat/utility-data-processfrom
fix/data-process-restart-loop-detection
Open

fix(data-process): fix crash-loop detection and renderer hang on give-up#10388
jackkav wants to merge 1 commit into
feat/utility-data-processfrom
fix/data-process-restart-loop-detection

Conversation

@jackkav

@jackkav jackkav commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Feedback PR for #10259 — two related bugs in data-process-manager.ts's handleExit().

1. restartCount reset undermines MAX_RESTARTS

spawnDataProcess(dbPath)
  .then(() => {
    console.log('[data-process] restarted, re-issuing ports');
    restartCount = 0; // <-- removed
    ...

restartCount was zeroed as soon as the child reached ready, regardless of how quickly it crashed afterwards. If the utility process crashes shortly after reaching ready every time (e.g. a bug that only manifests once init finishes), each restart attempt resets the counter before the next crash increments it again — so restartCount never climbs past 1 and MAX_RESTARTS (10) never trips. The app would restart the data process forever instead of giving up.

The existing RESTART_WINDOW_MS check in the same function already decays the counter correctly for restarts that are spaced more than 60s apart:

if (now - lastRestartTime > RESTART_WINDOW_MS) {
  restartCount = 0;
}

Removing the extra reset-on-success lets that time-based logic do its job as intended, while still correctly capping tight ready-then-crash loops.

2. Renderer windows never learn the data process is permanently gone

When MAX_RESTARTS is exceeded, only mainRpc (the main process's own RPC client) was invalidated:

if (restartCount > MAX_RESTARTS) {
  ...
  mainRpc.invalidate('data-process crashed and could not be restarted');
  return; // <-- no broadcast to renderer windows
}

Each BrowserWindow's own PortRpc (attached via attachDataPortRpc in preload) is only invalidated when it receives the 'data-process.restarting' IPC message — which is sent on every retry but not on the final give-up path. So once the data process is confirmed dead, any pending or future database/services call from a window would hang forever with no error, rather than rejecting with a clear message.

Fix: broadcast 'data-process.restarting' to all windows on the give-up path too, so their pending/future invoke() calls reject instead of hanging.

Testing

  • npx tsc --noEmit and npx eslint clean on the changed file.
  • serialization.test.ts passes; port-rpc.test.ts in this workspace currently fails locally due to an unrelated broken electron postinstall in my worktree, not this change (confirmed the same file's other test suite runs fine and the failure is Electron failed to install correctly, not a code issue).
  • No behavior change for the common case (single crash, successful restart, no further crashes) — only the crash-loop and give-up paths differ.

Two bugs in the crash-restart manager's handleExit():

1. restartCount was reset to 0 after every successful restart (i.e. as
   soon as the child reached 'ready'), not just when restarts were
   spaced apart. A process that repeatedly reaches ready and then
   crashes again seconds later would reset the counter each time,
   defeating MAX_RESTARTS for a ready-then-crash loop. The existing
   RESTART_WINDOW_MS check already decays the counter correctly for
   restarts that occur further apart, so the extra reset is both
   redundant and harmful — removed it.

2. When MAX_RESTARTS is exceeded, only mainRpc (the main process's own
   RPC client) was invalidated. Renderer windows hold their own
   PortRpc instances (attached via attachDataPortRpc in preload),
   which are only invalidated by the 'data-process.restarting' IPC
   message. That message was never sent on the give-up path, so
   pending and future database/service calls from any window would
   hang forever with no error once the data process is confirmed dead.
@github-actions

Copy link
Copy Markdown

✅ Circular References Report

Generated at: 2026-08-13T07:43:05.892Z
Status: ✅ NO CHANGE

Summary

Metric Base (feat/utility-data-process) PR Change
Total Circular References 9 9 0 (0.00%)
Click to view all circular references in PR (9)
insomnia-inso/src/db/models/types.ts -> insomnia-inso/src/db/types.ts
insomnia/src/main/prompt-bridge.ts -> insomnia/src/main/window-utils.ts -> insomnia/src/main/plugin-window.ts
insomnia/src/main/window-utils.ts -> insomnia/src/main/plugin-window.ts
insomnia/src/network/network.ts -> insomnia-scripting-environment/src/objects/index.ts -> insomnia-scripting-environment/src/objects/collection.ts -> insomnia-scripting-environment/src/objects/response.ts
insomnia/src/network/network.ts -> insomnia/src/common/render.ts
insomnia/src/ui/components/settings/import-export.tsx -> insomnia/src/ui/components/modals/export-requests-modal.tsx
insomnia/src/ui/components/tabs/tab-list.tsx -> insomnia/src/ui/components/tabs/tab.tsx
insomnia/src/ui/components/templating/tag-editor-arg-sub-form.tsx -> insomnia/src/ui/components/templating/external-vault/external-vault-form.tsx
insomnia/src/ui/components/viewers/response-viewer.tsx -> insomnia/src/ui/components/viewers/response-multipart-viewer.tsx
Click to view all circular references in base branch (9)
insomnia-inso/src/db/models/types.ts -> insomnia-inso/src/db/types.ts
insomnia/src/main/prompt-bridge.ts -> insomnia/src/main/window-utils.ts -> insomnia/src/main/plugin-window.ts
insomnia/src/main/window-utils.ts -> insomnia/src/main/plugin-window.ts
insomnia/src/network/network.ts -> insomnia-scripting-environment/src/objects/index.ts -> insomnia-scripting-environment/src/objects/collection.ts -> insomnia-scripting-environment/src/objects/response.ts
insomnia/src/network/network.ts -> insomnia/src/common/render.ts
insomnia/src/ui/components/settings/import-export.tsx -> insomnia/src/ui/components/modals/export-requests-modal.tsx
insomnia/src/ui/components/tabs/tab-list.tsx -> insomnia/src/ui/components/tabs/tab.tsx
insomnia/src/ui/components/templating/tag-editor-arg-sub-form.tsx -> insomnia/src/ui/components/templating/external-vault/external-vault-form.tsx
insomnia/src/ui/components/viewers/response-viewer.tsx -> insomnia/src/ui/components/viewers/response-multipart-viewer.tsx

Analysis

No Change: This PR does not introduce or remove any circular references.


This report was generated automatically by comparing against the feat/utility-data-process branch.

@jackkav
jackkav requested a review from ZxBing0066 August 13, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant