Skip to content

feat: add flock stop and flock start, and Stop Flock in the Windows tray - #96

Open
N7z wants to merge 8 commits into
flock-php:mainfrom
N7z:feat/stop-daemon
Open

N7z wants to merge 8 commits into
flock-php:mainfrom
N7z:feat/stop-daemon

Conversation

@N7z

@N7z N7z commented Nov 3, 2026

Copy link
Copy Markdown

Fixes #92

Adds a way to stop the Flock daemon and every service it runs, and to start it again, from the CLI and the Windows tray. Stopping only lasts until the next start: the scheduled task (LaunchAgent, systemd unit) isn't changed, so the daemon still starts at the next login.

CLI

  • flock stop stops the daemon and all services.
  • flock start starts them again and waits until the daemon answers.

How stopping works

Windows. The daemon gets no signals, so there's a new POST /v1/stop API call. It ends daemon.Run the way SIGTERM does on the other platforms: every service shuts down cleanly (mysqladmin shutdown, pg_ctl stop -m fast, Valkey's SHUTDOWN), and the daemon exits with code 0. The watchdog doesn't restart a daemon that exits with 0, so it ends, and the scheduled task ends with it. flock stop waits up to a minute for the daemon process to exit. If it doesn't, or the daemon is older and has no stop call, it falls back to what flock restart does (schtasks /End). flock start uses the existing runTask.

macOS (not tested): launchctl bootout stops the agent (SIGTERM, so a clean shutdown) and launchctl bootstrap loads it again. The plist stays in LaunchAgents, so it loads at the next login. The bootstrap retry loop moved from installService into bootstrapAgent so both use it.

Linux (not tested): systemctl stop / systemctl start on flock@<user>.service, which the existing polkit rule already allows. The unit stays enabled.

Windows tray

  • The tray menu shows Stop Flock under Restart Flock while the daemon runs. Once it's stopped, the existing Start Flock item shows instead.
  • The panel footer has a Stop link next to Restart.
  • Both run flock stop, the same way Restart runs flock restart.

Docs

  • docs/cli.md lists the new commands.
  • docs/installation.md gets a short "Stopping Flock" section.
  • windows/README.md gets a line in the first-run checklist.

I left out renaming "Quit Flock" on Windows and Linux (point 3 of the issue) to keep this PR focused. I can send it separately if you'd like.

Testing

Automated:

  • go vet passes for windows, darwin and linux (amd64).
  • go test ./... passes on Windows 11, including the new TestStopShutsTheDaemonDown (api) and TestStopEndsRun (daemon).
  • windows/build.ps1 passes: Flock.Kit.Tests 151/151, Flock.Tray.Tests 239/239.

Manual, on Windows 11 with a real install (MySQL 8.4, PostgreSQL 18, Valkey 9.1, PHP 8.3 and 8.4):

  • flock stop with a daemon that has an isolated FLOCK_HOME: it stops, and the daemon process exits by itself.
  • flock stop with the scheduled task: MySQL's error log shows "Shutdown complete", PostgreSQL's log shows "database system is shut down", and the task is back to Ready. No Flock process is left and nothing restarts.
  • flock start brings the daemon back through the task with every service up.
  • Tray: Stop Flock in the menu stops everything cleanly (same checks as above), the menu then shows Start Flock, and Start Flock brings everything back.
  • After stop and start, the scheduled task is still enabled, with its logon trigger unchanged.

Not tested:

  • macOS and Linux: I only checked that they compile and vet.
  • The fallback path, for a daemon that doesn't stop within a minute.

N7z added 3 commits November 3, 2026 16:50
flock stop shuts the daemon down and every service it runs, and flock start
starts it again. Neither changes the service, so the daemon still starts at
the next login (on Linux, with the computer).

On Windows the daemon has no signals, so it gets a new POST /v1/stop API call
that ends Run as SIGTERM does: services shut down cleanly and the daemon exits
with code 0, which the watchdog doesn't restart, so the scheduled task ends
too. A daemon that doesn't stop within a minute, or one without the call, is
ended like flock restart does. On macOS the LaunchAgent is booted out and
bootstrapped again, on Linux the unit is stopped and started.

Refs flock-php#92
The tray menu shows Stop Flock under Restart Flock while the daemon runs, and
the panel has a Stop link next to Restart. Both run flock stop; afterwards
the existing Start Flock item and button appear.

Refs flock-php#92
Quitting the tray app leaves the daemon and the sites running, which "Quit
Flock" didn't make clear. The macOS app says "Quit Flock Bar" for the same
reason. Linux keeps "Quit Flock": its app can also be a window without a
tray icon.

Refs flock-php#92
@onairmarc
onairmarc self-requested a review November 3, 2026 20:26
@onairmarc

Copy link
Copy Markdown
Member

@N7z Could you add start/stop controls to this line in each app? When stopped, only start should appear. When started, both stop and restart appear.

image

@onairmarc

Copy link
Copy Markdown
Member

Also, please contribute the Mac and Linux UIs as well. We'd like to avoid having the platforms drift apart as much as possible

N7z added 2 commits November 3, 2026 18:21
flock stop unloads the LaunchAgent, and flock restart then said the daemon
wasn't installed, so the apps' Start Flock (which runs flock restart) failed
after a stop. It now loads the agent again when it isn't loaded.

Refs flock-php#92
The Daemon row in Settings > General has Stop Daemon next to Restart Daemon
on Windows, macOS and Linux. While the daemon is stopped, Settings already
shows only Start Flock instead of the panes.

After a successful stop the Windows and Linux apps show the daemon as stopped
at once, instead of the stale status until the next poll: on Windows, reading
the status of a daemon that just stopped takes seconds to fail.

Refs flock-php#92
@onairmarc
onairmarc requested a review from lukas-frey November 3, 2026 21:25
The macOS panel's footer has Stop next to Restart, and the Linux tray menu has
Stop Flock under Restart Flock while the daemon runs, as the Windows tray has.
Both run flock stop; afterwards Start Flock shows instead.

Refs flock-php#92
@N7z

N7z commented Nov 3, 2026

Copy link
Copy Markdown
Author

Thanks for review ! , I added Stop to Settings > General in all three apps, and to the macOS panel and the Linux tray menu. I tested it on Windows. I can’t build the macOS and Linux apps, so I’m relying on CI for those.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Stop handling can falsely report success while services remain running or the Windows daemon restarts, while status timeouts and Linux service signaling can prevent reliable, graceful shutdown.

5 open issues
What changed in this PR

Adds temporary daemon stop/start controls to free resources without disabling automatic startup, addressing the core request in #92.

Changes:

  • Adds flock stop and flock start, with platform-specific lifecycle handling and a daemon stop API.
  • Adds Stop controls and busy-state handling across the desktop apps, plus clearer Windows tray quit labels.
  • Adds shutdown tests and documents stopping and starting Flock.
File Description
windows/​README.md Adds manual stop/start checks.
windows/​Flock.Tray/​ViewModels/​PanelViewModel.cs Adds Stop command and lifecycle guards.
windows/​Flock.Tray/​ViewModels/​GeneralViewModel.cs Exposes Stop and stopping state.
windows/​Flock.Tray/​Settings/​GeneralPane.xaml Adds Stop Daemon button.
windows/​Flock.Tray/​PanelWindow.xaml Adds Stop link and clarifies Quit label.
windows/​Flock.Tray/​Infrastructure/​RuntimeService.cs Shares stop/restart execution and updates status.
windows/​Flock.Tray/​App.xaml.cs Adds Stop Flock menu action.
windows/​Flock.Tray.Tests/​GeneralViewModelTests.cs Tests Stop availability and restart blocking.
macos/​Sources/​FlockUI/​Settings/​SettingsWindow.swift Disables Start while stopping.
macos/​Sources/​FlockUI/​Settings/​GeneralPane.swift Adds Stop Daemon control.
macos/​Sources/​FlockUI/​PanelView.swift Adds Stop and stopping-state feedback.
macos/​Sources/​FlockUI/​AppModel.swift Runs the stop command.
linux/​src/​window.rs Disables Start while stopping.
linux/​src/​tray.rs Adds Stop Flock menu item.
linux/​src/​panes/​general.rs Adds Stop Daemon and lifecycle guards.
linux/​src/​model.rs Tracks stopping and clears stopped status.
linux/​src/​main.rs Routes tray Stop action.
internal/​daemon/​daemon.go Adds API-triggered lifecycle cancellation.
internal/​daemon/​daemon_test.go Tests that Stop ends daemon execution.
internal/​cli/​stop.go Implements stop/start commands.
internal/​cli/​root.go Registers stop/start commands.
internal/​cli/​install_windows.go Adds graceful stop, fallback, and startup handling.
internal/​cli/​install_linux.go Adds systemd stop/start operations.
internal/​cli/​install_darwin.go Adds LaunchAgent stop/start and shared bootstrap logic.
internal/​api/​api.go Adds stop endpoint and client method.
internal/​api/​api_test.go Tests stop dispatch, authentication, and HTTP method.
docs/​installation.md Explains stopping and automatic startup behavior.
docs/​cli.md Lists stop/start commands.

Review effort: Balanced

Comment thread internal/cli/install_windows.go Resolved
Comment thread internal/daemon/daemon.go Resolved
Comment thread internal/cli/install_darwin.go Resolved
Comment thread internal/cli/install_linux.go Resolved
Comment thread internal/cli/stop.go Resolved
N7z added 2 commits November 4, 2026 10:14
- A daemon stopped while an API request still runs (an install) cuts it off and
  exits with code 0, instead of returning the shutdown timeout as an error,
  which made the Windows watchdog start it again.
- On Windows, flock stop fails when the fallback could not end the daemon,
  instead of reporting it stopped.
- On macOS, flock stop fails when launchd still has the agent loaded.
- flock stop no longer gives up when the status read fails for another reason
  than the daemon not running: like flock restart, it only uses it for the pid.

Refs flock-php#92
# Conflicts:
#	internal/cli/root.go

This branch has not been deployed

No deployments
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.

Add a way to stop the Flock daemon (tray and CLI)

3 participants