Skip to content

fix(desktop): wait for backend exit before reloading on connection-config apply - #38289

Closed
AhmetArif0 wants to merge 1 commit into
NousResearch:mainfrom
AhmetArif0:fix/desktop-connection-config-apply-race
Closed

fix(desktop): wait for backend exit before reloading on connection-config apply#38289
AhmetArif0 wants to merge 1 commit into
NousResearch:mainfrom
AhmetArif0:fix/desktop-connection-config-apply-race

Conversation

@AhmetArif0

Copy link
Copy Markdown
Contributor

Problem

hermes:connection-config:apply called resetHermesConnection() (which sends SIGTERM and immediately nulls hermesProcess), then used a hard-coded setTimeout(() => mainWindow?.reload(), 150) to trigger the renderer reload.

150 ms is an arbitrary delay that doesn't track actual process shutdown. If the Python backend takes longer to terminate (signal handler, file-lock release, cleanup code), the renderer reloads and startHermes() tries to bind the same port while the old process is still alive — resulting in an "address already in use" connection failure.

Fix

Capture the process reference before resetHermesConnection() nulls it, then await the real exit event:

  • If a local backend was running: wait for it to exit, with a 5 s SIGKILL fallback in case SIGTERM is ignored.
  • If no local process was alive (remote backend, already stopped): reload immediately — same behaviour as before.
const dying = hermesProcess && !hermesProcess.killed ? hermesProcess : null
resetHermesConnection()

if (dying) {
  await new Promise(resolve => {
    const timer = setTimeout(() => {
      try { dying.kill('SIGKILL') } catch {}
      resolve()
    }, 5000)
    dying.once('exit', () => {
      clearTimeout(timer)
      resolve()
    })
  })
}

mainWindow?.reload()

Test plan

  • Change connection config to a remote backend while a local backend is running → renderer reloads cleanly without a "port in use" error in the logs
  • Change connection config when no local backend is running → reload happens immediately (no 5 s wait)
  • Kill the backend process externally mid-apply → SIGKILL fallback fires after 5 s and reload proceeds

…nfig apply

The apply handler sent SIGTERM then fired a 150 ms setTimeout to reload
the renderer. If the backend took longer to shut down the port was still
bound when startHermes() ran after reload, causing an "address already
in use" failure.

Capture the process reference before resetHermesConnection() nulls it,
then await the actual exit event. A 5 s SIGKILL fallback ensures the
wait never hangs if the backend ignores SIGTERM.
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have labels Jun 3, 2026
@teknium1

teknium1 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Merged via PR #39070. Your commit was cherry-picked onto current main as 6feb40e with your authorship preserved in git log. Thanks!

@teknium1 teknium1 closed this Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants