Skip to content

fix(update): restart hermes-serve systemd units alongside gateways (#83438) - #87859

Merged
teknium1 merged 3 commits into
mainfrom
salvage/83595-serve-restart
Aug 16, 2026
Merged

fix(update): restart hermes-serve systemd units alongside gateways (#83438)#87859
teknium1 merged 3 commits into
mainfrom
salvage/83595-serve-restart

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

hermes update now discovers and restarts hermes-serve* systemd units (the Desktop app's backend) alongside hermes-gateway*, so the Serve backend no longer keeps running stale pre-update code until a manual systemctl --user restart hermes-serve. Fixes #83438.

Salvage of #83595 by @chelsealong — both commits cherry-picked onto current main with authorship preserved (the branch was ~1470 commits stale, CONFLICTING). Conflicts in main.py (lazy-export refactor) and update_cmd.py (process-scan reload, #78574 snapshot bookkeeping) resolved in favor of current main + the PR's intent.

Changes

  • hermes_cli/update_cmd.py: fleet-restart list-units discovery now matches hermes-serve*; unit-name gate accepts the exact hermes-serve.service / hermes-serve-* family; new _service_unit_supports_graceful_sigusr1_restart() routes serve units past the SIGUSR1 drain (only gateway/run.py installs that handler) straight to blunt systemctl restart.
  • hermes_cli/dashboard_procs.py: _kill_stale_dashboard_processes(already_restarted_units=...) skips PIDs whose owning unit the fleet loop already restarted — no double restart on Serve-only installs. Only successfully-restarted units are forwarded (restarted_services appends strictly after _wait_for_service_active succeeds), so failed restarts still get the stale-kill sweep.
  • Follow-up (ours): gateway-side gates tightened to the same exact/hyphenated shape (hermes-gateway.service / hermes-gateway-*), so a near-prefix unit like hermes-gatewayd can't enter the restart path or receive an unhandled SIGUSR1.

Validation

Check Result
test_update_fleet_restart_timeout.py + test_update_stale_dashboard.py 44 passed, 2 skipped
E2E (real imports, discovery gate + eligibility + kwarg threading + lazy export via hermes_cli.main) pass
ruff on changed files clean
Attribution audit all emails mapped (contributors/emails/chelsealong@126.com)

Infographic

hermes update now restarts hermes-serve

chelsealong and others added 3 commits August 16, 2026 10:33
hermes update discovered and restarted hermes-gateway* systemd units but
never looked for hermes-serve* — the Desktop app's backend — so it kept
running stale pre-update code until the user restarted it by hand (#83438).

Extend the systemd unit discovery/restart loop to also match hermes-serve*
units. They don't wire SIGUSR1 to a graceful drain (only gateway/run.py
does), so restart eligibility for the graceful path is now gated on unit
name via a small, directly-tested helper; hermes-serve units fall straight
to the existing blunt systemctl restart path, matching the workaround the
issue already documents.
…tarts

Review on #83595 flagged two service-lifecycle gaps in the hermes-serve
restart support:

- The unit-name gate accepted anything starting with "hermes-serve",
  which also matched the unrelated hermes-server.service. Require the
  exact base unit or the hyphenated profile family instead.
- The fleet-restart loop and _finish_dashboard_update_cleanup() could
  both restart the same hermes-serve unit — the loop restarts it
  directly, then cleanup's PID scan finds the fresh process and
  restarts its owning unit again. Thread the fleet loop's restarted
  unit names through to _kill_stale_dashboard_processes() so it skips
  units already handled.
Mirror the strict unit-name shape from the hermes-serve gate (review on
PR #83595) on the gateway side too: the discovery gate and the SIGUSR1
eligibility helper now accept only `hermes-gateway.service` or the
`hermes-gateway-<profile>` family, so a near-prefix unit like
`hermes-gatewayd.service` can neither enter the restart path nor be sent
a SIGUSR1 it does not handle.
@github-actions

github-actions Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 686afb4 — fix(update): tighten gateway-side unit gates to exact/hyphen

⚠️ Warnings

CI timings · View report · View job

Wall time 7m25s vs 3m28s (+113.9%). 14 job(s) slower, 9 faster, 1 unchanged.

  • Python tests / Run tests slice 3/12: +141.0s
  • Python tests / Run tests slice 9/12: +33.0s
  • Python tests / Run tests slice 4/12: +25.0s
  • Python tests / Run tests slice 1/12: -15.0s
  • OS-specific tests / Windows-only tests: -10.0s

OSV vulnerability scan · View job

5 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.

@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard area/install-update Installer, updater, packaging, wheels, doctor P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Aug 16, 2026
@teknium1
teknium1 merged commit 19631b5 into main Aug 16, 2026
84 of 86 checks passed
@teknium1
teknium1 deleted the salvage/83595-serve-restart branch August 16, 2026 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install-update Installer, updater, packaging, wheels, doctor comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: hermes update does not restart hermes-serve (Desktop backend) — leaves stale code running until manual restart

3 participants