fix(desktop): hard-exit a lock-losing second instance before ready

app.quit() does not stop a lock-losing instance from reaching whenReady:
the before-quit teardown coordinator defers the quit (event.preventDefault
+ async backend shutdown), and ready fires in that window. The losing
instance then runs the full startup whose reapOrphans() SIGTERMs the
running instance's live backend (#87295).

The lock-loser holds no state and no backend — requestSingleInstanceLock()
has already delivered the argv to the primary by the time it returns false —
so there is nothing to clean up. app.exit(0) terminates immediately, before
ready, so a second launch routes into the running window and never touches
backend machinery.
This commit is contained in:
YappLeCunt
2026-08-16 07:04:40 +08:00
committed by Teknium
parent 0a8092ac32
commit 7cc006a2ef
+10 -2
View File
@@ -14105,9 +14105,17 @@ function registerDeepLinkProtocol() {
// second-instance argv. Without the lock a second `hermes://` launch spawns a
// whole new app instead of routing into the running one.
const _gotSingleInstanceLock = app.requestSingleInstanceLock()
const isPrimaryInstance = _gotSingleInstanceLock
if (!_gotSingleInstanceLock) {
app.quit()
if (!isPrimaryInstance) {
// Hard-exit, not app.quit(): the before-quit teardown coordinator defers a
// plain quit (event.preventDefault + async backend shutdown), and in that
// window `ready` still fires — the lock-losing instance then runs the full
// startup (shortcut registration, createWindow → startHermes), whose
// reapOrphans() SIGTERMs the running instance's live backend (#87295).
// app.exit() terminates immediately, before `ready`, so a second launch
// routes into the running window and never touches backend machinery.
app.exit(0)
} else {
app.on('second-instance', (_event, argv) => {
const url = _extractDeepLink(argv)