You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Quitting the app leaves dev servers and watchers running #83
Quitting the app while a dev server or a watch task is running leaves those processes alive. The Playground server keeps its port and the watcher keeps rebuilding until they are killed by hand — at a Contributor Day that means Task Manager / Activity Monitor. On the next launch, the web-server "already reachable" probe (src/main.js:876-888) can silently adopt the previous session's orphaned server.
Root cause
Two independent gaps:
There is no quit hook anywhere in src/main.js — only the window-all-closed handler (src/main.js:392-394). Nothing sweeps the tracked children (runningInstalls, runningScripts, playgroundServers, the web server) on exit.
Even when the app does kill a child (src/main.js:736, 848, 995), the signal reaches only the direct child. The processes that matter are grandchildren (script runner → shell → grunt → node); on Windows especially, the tree survives.
Related leak: the Windows shim directory created per run in the temp folder (src/main.js:45) is never removed — one leftover directory per launch.
Expected
Quitting the app ends everything it started, on all platforms.
PR #98 lands the sweep (before-quit + taskkill /T on Windows, detached spawn + process-group signal on POSIX) but keeps a known residual gap on Windows: taskkill /T walks parent links at kill time, so a grandchild whose intermediate parent already died can survive. Observed on a Windows VM as a grunt _watch process (spawned via the node shim, so it shows in Task Manager as "WordPress Contributor Toolkit") outliving the quit with its ParentProcessId pointing at a dead process.
Possible directions for the complete fix, in rough order of appeal: have the runners own their children's lifetime (each runner kills its subtree when its stdin closes, i.e. when the app dies — no quit-time race at all); or enumerate the descendant closure from a Win32_Process snapshot taken before any kill; or Windows job objects via a native module. Not release-blocking: the leak is bounded (one watcher process) and strictly smaller than trunk's leak-everything behavior.
Activity
Sweep descendants from a pre-kill snapshot on Windows
Kill spawned process trees when the app quits
juanmaguitar commentedon Jul 31, 2026
PR #98 lands the sweep (before-quit + taskkill /T on Windows, detached spawn + process-group signal on POSIX) but keeps a known residual gap on Windows:
taskkill /Twalks parent links at kill time, so a grandchild whose intermediate parent already died can survive. Observed on a Windows VM as agrunt _watchprocess (spawned via the node shim, so it shows in Task Manager as "WordPress Contributor Toolkit") outliving the quit with itsParentProcessIdpointing at a dead process.Possible directions for the complete fix, in rough order of appeal: have the runners own their children's lifetime (each runner kills its subtree when its stdin closes, i.e. when the app dies — no quit-time race at all); or enumerate the descendant closure from a
Win32_Processsnapshot taken before any kill; or Windows job objects via a native module. Not release-blocking: the leak is bounded (one watcher process) and strictly smaller than trunk's leak-everything behavior.Kill spawned process trees when the app quits (#98)
Route the Playground and stop handlers through the tested child-proce…
Drive the quit sweep over all four child registries (#163)
Let Stop end a running npm install (#274)
Run the initial setup steps as one chain (#246) (#276)
Start the server or the watch when a site is opened, and start again …