Skip to content

fix(update): relaunch the new version instead of the old running process - #69

Merged
DamienBattistella merged 2 commits into
mainfrom
claude/app-restart-process-issue-o2i1e0
Jul 10, 2026
Merged

fix(update): relaunch the new version instead of the old running process#69
DamienBattistella merged 2 commits into
mainfrom
claude/app-restart-process-issue-o2i1e0

Conversation

@DamienBattistella

Copy link
Copy Markdown
Collaborator

Description

Clicking "Restart now" / "Redémarrer maintenant" after an update finished downloading kept running the previous version (e.g. it stayed on v1.9.0 instead of switching to v1.10.0). The earlier fix (#67) corrected which binary path the relaunch targets on disk, but two remaining bugs kept the old process alive:

  1. RestartApplication never set the quitting flag. QuitApp sets a.quitting.Store(true) before runtime.Quit specifically so beforeClose doesn't intercept the quit. RestartApplication omitted this, so when "Minimize to tray" was enabled, beforeClose ran with quitting == false and returned true (prevent) → the old process merely hid its window instead of quitting, lingering in the tray on the previous version and never releasing the single-instance lock.

  2. Single-instance-lock race. cmd.Start() launches the new binary, then runtime.Quit begins a shutdown that takes time (disconnect Discord, stop tray, …). During that window the old process still holds the com.plexcord.app single-instance lock, so the freshly-launched new binary is treated as a second instance — it calls onSecondInstanceLaunch (restores the old window) and exits. The new version never runs.

Fix

  • Set a.quitting.Store(true) before runtime.Quit in RestartApplication (mirrors QuitApp), so the old process actually terminates regardless of the "Minimize to tray" setting.
  • Pass the old process PID to the relaunched child via PLEXCORD_RELAUNCH_PID. In main(), before wails.Run acquires the single-instance lock, the child waits (bounded to 15s) for that PID to exit and for the OS to release the lock. The updated binary then starts as the primary instance.
  • Per-platform process-liveness check: WaitForSingleObject on Windows (relaunch_windows.go), signal 0 on Unix (relaunch_unix.go).

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Related Issues

Fixes the reported issue where the app restarts the current process rather than the freshly downloaded new version.

Testing

  • Tested on Windows
  • Tested on macOS
  • Tested on Linux
  • Added/updated unit tests
  • All tests pass locally

Added relaunch_test.go covering processExists (self alive, reaped-child dead) and waitForPreviousInstanceExit (no-op without the env marker; returns promptly and clears the env when the predecessor is already gone). Verified go build, go vet, and the full go test ./... suite pass for both linux/amd64 and windows/amd64.

Checklist

  • My code follows the project's code style
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings or errors
  • I have added tests that prove my fix is effective
  • New and existing unit tests pass locally with my changes

Additional Notes

Both fixes are needed together: fix (1) makes the old process actually exit, and fix (2) ensures the new binary doesn't bail out as a "second instance" during the old process's shutdown window.

🤖 Generated with Claude Code


Generated by Claude Code

claude added 2 commits July 10, 2026 16:23
Clicking "Restart now" after an update kept running the previous version.
Two compounding causes, neither addressed by the earlier relaunch-path fix:

- RestartApplication never set the `quitting` flag, so `beforeClose`
  intercepted `runtime.Quit` and merely hid the window whenever "Minimize
  to tray" was enabled. The old process lingered in the tray running the
  previous version and never released the single-instance lock. Set the
  flag before quitting, mirroring QuitApp.

- Even when the old process did quit, the freshly spawned binary raced its
  shutdown: while the old instance still held the `com.plexcord.app`
  single-instance lock, the new one was treated as a second instance,
  restored the old window, and exited. The new version never ran.

The relaunched child now receives the old PID via PLEXCORD_RELAUNCH_PID and
waits (bounded) for that process to exit before wails.Run acquires the
single-instance lock, so the updated binary starts as the primary instance.
Process liveness is checked per-platform (WaitForSingleObject on Windows,
signal 0 on Unix).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CTxwvdhzd1rVPZt98Acf9A
- Check the os.Unsetenv error in waitForPreviousInstanceExit (errcheck
  check-blank).
- Use exec.CommandContext in the relaunch tests (noctx).
- Guard pid and close the process handle in the Windows liveness check so
  windows-tagged builds also lint clean (gosec G115, errcheck).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CTxwvdhzd1rVPZt98Acf9A
@DamienBattistella
DamienBattistella marked this pull request as ready for review July 10, 2026 16:41
@DamienBattistella
DamienBattistella merged commit c7e7204 into main Jul 10, 2026
9 checks passed
@DamienBattistella
DamienBattistella deleted the claude/app-restart-process-issue-o2i1e0 branch July 10, 2026 16:41
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.10.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants