Skip to content

Support native Windows services and systemd lifecycle notifications - #1503

Open
lovasoa wants to merge 4 commits into
mainfrom
codex/native-service-lifecycle
Open

lovasoa wants to merge 4 commits into
mainfrom
codex/native-service-lifecycle

Conversation

@lovasoa

@lovasoa lovasoa commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

SQLPage currently cannot run directly under the Windows Service Control Manager, and systemd considers it started before database initialization or migrations finish. This adds native Windows service mode (--service NAME --web-root <absolute path>) and systemd readiness/stopping notifications, with one graceful shutdown path for service controls and Unix signals.

  • Report readiness after database initialization, migrations, and HTTP listener/worker startup. Drain active requests for up to 30 seconds, close the database, and flush telemetry before exiting. Startup failures remain failures to the supervisor.
  • Set the Windows service working directory explicitly and report SCM lifecycle states and failure exit codes. Write Application Event Log records through a background thread with a persistent native handle. A bounded queue holds 256 records of at most 16 KiB; overload drops records with a warning summary, and shutdown flushes accepted records before reporting STOPPED.
  • Update the systemd unit to Type=notify, bounded startup/stop timeouts, journal logging, and restart-on-failure. Add installation and operation guides for both platforms.

Validation:

  • cargo fmt --all
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo test: 329 local tests passed, including real-process readiness, in-flight request draining for SIGTERM/SIGINT/SIGQUIT, bind failure, termination during database startup, and logging queue behavior.
  • systemd-analyze verify on a temporary copy of the unit with ExecStart pointing to the locally built binary.
  • CI at e7059079: Windows passed 331 Rust tests plus a real SCM integration test covering failed startup, readiness, active-request draining, clean stop, log flushing, and restart. Linux linting, all six database test configurations, and Playwright passed.

Impact measured on Linux x86_64, Rust 1.98.1, the shipping superoptimized profile (fat LTO), static ODBC, and identical frontend assets:

  • Release binary: 34,144,688 to 34,250,880 bytes, an increase of 106,192 bytes (104 KiB, 0.31%).
  • Root-crate rebuild with dependencies already built: baseline 402.62 seconds, current PR 396.23 seconds. These single samples do not establish a speedup or regression. An earlier comparison against a much faster first baseline was not reproducible and does not support a 40% compile-time increase.
  • Five interleaved 300,000-request samples with routine logging disabled: median 107.8k vs 107.6k requests/second, with overlapping ranges; median RSS 22.27 vs 22.25 MiB. No meaningful runtime regression was demonstrated in this workload.
  • Linux adds only sd-notify (0.19 seconds to compile in the initial measurement), with no native libsystemd dependency. Tokio signals were already enabled transitively. Windows adds windows-service and Event Log API features in the existing windows-sys dependency.

Windows release size, compile-time deltas, and throughput have not been measured. Its background logger adds one thread, a bounded queue, and formatting/enqueue work on producers; native Event Log calls run on the writer thread. It can drop log records under sustained overload, as documented.

@lovasoa
lovasoa marked this pull request as draft September 28, 2026 01:23
@lovasoa
lovasoa marked this pull request as ready for review September 28, 2026 01:44
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.

1 participant