Skip to content

fix(desktop): recover when the gateway is slow to start instead of stranding the app - #41

Open
ankit-thebigred wants to merge 1 commit into
suitedaces:mainfrom
ankit-thebigred:fix/gateway-slow-start-never-recovers
Open

fix(desktop): recover when the gateway is slow to start instead of stranding the app#41
ankit-thebigred wants to merge 1 commit into
suitedaces:mainfrom
ankit-thebigred:fix/gateway-slow-start-never-recovers

Conversation

@ankit-thebigred

Copy link
Copy Markdown

Found while fixing #37. No issue filed for this one.

The problem

waitForReady() gives up after a fixed 20s and throws. The interesting part is what happens next.

The throw reaches start()'s catch block, which increments retries and schedules setTimeout(() => this.start(), 1000). But start() opens with:

if (this.process) return;

On a readiness timeout the gateway process is still alive, so this.process is still set and the retry returns immediately without doing anything. It is a silent no-op. Nothing re-checks the socket afterwards, and because no exception is thrown the second time, the retry counter stops advancing and onError is never reached either.

The result is that a gateway which simply needed longer than 20s comes up healthy moments later and the desktop never notices. The window stays dead until the user quits and relaunches the whole app.

This is reachable through ordinary slow startup work: a schema migration, or a search index rebuild on a large database. Before #37 is fixed, that rebuild happens on every launch, so the two bugs compound into an app that cannot start at all.

The fix

Treat "slow" and "failed" as different things.

  • Keep polling while the process is alive rather than against a wall clock deadline.
  • At the old 20s mark, log and fire a new optional onSlowStart callback once, so the UI can say startup is still in progress instead of showing nothing.
  • Keep a generous hard ceiling (10 minutes) purely as a backstop against a process that is alive but permanently wedged.

Genuine failures are unaffected and still take the existing path: the exit handler clears this.process, which trips the this.process !== proc identity check already inside the loop, which throws and drives the established restart logic.

onSlowStart is optional, so no caller has to change.

Verification

cd desktop && npm run typecheck reports 0 errors, identical to the main baseline.

Note

Raising the 20000 constant is the obvious workaround and it does help, but it only moves the cliff. The reason the app never recovers is the no-op retry, so that is what this addresses.

…randing the app

waitForReady() threw after a fixed 20s. The throw reached start()'s catch, which
scheduled a retry, but start() begins with `if (this.process) return` and the
gateway process is still alive at that point, so the retry was a silent no-op.
Nothing re-checked the socket afterwards. A gateway that simply needed longer
than 20s (schema migration, search index rebuild on a large database) would come
up healthy moments later while the window stayed dead until the user quit and
relaunched the app.

Keep waiting while the process is alive and surface a slow-start notice at the
old 20s mark, with a generous hard ceiling as a backstop. Genuine failures are
unaffected: the existing 'exit' handler clears this.process, which trips the
identity check inside the loop and drives the established restart path.

Adds an optional onSlowStart callback so the UI can tell the user startup is
still in progress rather than showing nothing.
@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

@ankit-thebigred is attempting to deploy a commit to the DevApe Team on Vercel.

A member of the Team first needs to authorize it.

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