Is your feature request related to a problem? Please describe.
ServerLauncher.start_async in pyrit/cli/_server_launcher.py spans roughly 141 lines and 20 branches. It currently handles parameter validation, platform-specific command construction, detached process launch, PID persistence, readiness polling, diagnostic capture, timeout handling, cancellation, and cleanup in one control flow.
These concerns interact through mutable startup state and cleanup flags. Recent lifecycle fixes around cancellation and stale PID records demonstrate that the code is correctness-sensitive across Windows and Unix. The method is not merely large; launch ownership, readiness state, and cleanup invariants are difficult to verify independently.
Describe the solution you'd like
Refactor the implementation into three cohesive internal seams while retaining ServerLauncher.start_async as the public orchestrator:
- Pure command/platform construction and validation.
- An explicit startup/readiness state machine that records process, PID-write, health-check, timeout, and diagnostic state.
- One idempotent cleanup path used consistently for launch failure, timeout, cancellation, and failed readiness.
The resulting design should make it obvious when a PID record may be written, when it must be removed, which process owns termination, and which exception is propagated.
Describe alternatives you've considered, if relevant
Adding more cleanup flags or broad try/finally blocks would address individual symptoms but retain the hidden state machine. Splitting into pass-through helpers without a shared startup state would also risk duplicated cleanup decisions.
Additional context
Validation should cover:
- all direct
ServerLauncher tests;
- Windows and Unix command construction;
- launch failure before and after PID persistence;
- readiness success and diagnostic failures;
- timeout boundaries without real sleeping;
- cancellation during launch, PID write, and health polling;
- repeated cancellation and idempotent cleanup;
- no stale PID files or orphaned owned processes;
- scanner and shell callers plus an end-to-end smoke path.
This is a high-confidence complexity candidate with medium platform risk. Avoid changing process semantics unless a regression test establishes a defect.
Is your feature request related to a problem? Please describe.
ServerLauncher.start_asyncinpyrit/cli/_server_launcher.pyspans roughly 141 lines and 20 branches. It currently handles parameter validation, platform-specific command construction, detached process launch, PID persistence, readiness polling, diagnostic capture, timeout handling, cancellation, and cleanup in one control flow.These concerns interact through mutable startup state and cleanup flags. Recent lifecycle fixes around cancellation and stale PID records demonstrate that the code is correctness-sensitive across Windows and Unix. The method is not merely large; launch ownership, readiness state, and cleanup invariants are difficult to verify independently.
Describe the solution you'd like
Refactor the implementation into three cohesive internal seams while retaining
ServerLauncher.start_asyncas the public orchestrator:The resulting design should make it obvious when a PID record may be written, when it must be removed, which process owns termination, and which exception is propagated.
Describe alternatives you've considered, if relevant
Adding more cleanup flags or broad
try/finallyblocks would address individual symptoms but retain the hidden state machine. Splitting into pass-through helpers without a shared startup state would also risk duplicated cleanup decisions.Additional context
Validation should cover:
ServerLaunchertests;This is a high-confidence complexity candidate with medium platform risk. Avoid changing process semantics unless a regression test establishes a defect.