Repository navigation
Conversation
Adds `process_registry_new.rs`, exposed as the `process_registry_new` module so it can be evaluated next to the current registry without colliding with it. The `exec_*` paths on `Command` still use the old registry; swapping them over is a follow-up. The new registry owns the child lifetime end to end: - Tracks children (`spawn`/`track`), reaps exits in the background via `SIGCHLD` with an interval sweep as a safety net, and keeps exited children tracked until released so a forced shutdown can still stop readers draining pipes held by descendants. - Kills a running child when its original handle is dropped (cancellation), configurable via `kill_on_drop`. - Forwards OS termination signals and programmatic `shutdown` to every running child and its descendants, with a grace period before force killing and immediate escalation on a second signal. - Can `stop`/`start`/`restart` its background tasks without losing tracked children, cache, or subscribers. - Works as a singleton (`instance`/`register`) or as independent instances. - Caches output with `exec_cached`, coalescing concurrent identical runs. - Emits lifecycle events over a broadcast channel. Process trees are enumerated via `/proc` on Linux, `proc_listchildpids` on macOS, `ps` on other Unixes, and a ToolHelp snapshot on Windows. Also fixes a latent race in `SharedChild::wait`: reaping a tokio `Child` through `try_wait` drops tokio's per-child `SIGCHLD` listener, so a concurrent `wait` lost its waker and hung. `wait` now also wakes on an exit recorded by `try_wait`. A public `SharedChild::try_wait` is added for the reaper, as tokio's `wait` closes stdin. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Moves `process_registry_new.rs` into `src/registry/` with one file per concern: options, tracked child types, events, the shared state and shutdown algorithm, the background tasks, process tree enumeration, the output cache, and the `ProcessRegistry` type itself. The module is now `starbase_process::registry`; the public API is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…cess-registry-054e9e * origin/master: build: Upgrade Rust to v1.99. chore: Release deps: Audit 09/21 (#226)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a second-generation
ProcessRegistryundercrates/process/src/registry/, exposed as thestarbase_process::registrymodule so it sits next to the current registry without a name collision. It is split by concern:options,child(tracked child types),event,state(shared state and the shutdown algorithm),tasks(reaper and shutdown coordinator),tree(process-tree enumeration per platform),cache, andprocess_registry(the public type). The existing registry and theexec_*methods onCommandare untouched; swapping them over (and then removing the old file) is a follow-up once the API is agreed on.What the new registry does
spawna tokioCommand(recording its command line) ortrackan existingChild. Children have aRunning/Exitedstate and stay tracked untilreleased, so a forced shutdown can still stop readers draining pipes held open by descendants.SIGCHLDon Unix, with an interval sweep as a safety net (and as the mechanism on Windows). Dropping a running child's original handle kills it as a cancellation (kill_on_drop); dropping an exited handle releases it.ProcessEventstream covers tracked/exited/released/signal/shutdown started/forced/finished.signal_descendantssnapshots each child's descendants before signalling, so a shell wrapper's work is reached too. Linux reads/proc, macOS usesproc_listchildpids, other Unixes fall back tops, Windows uses a ToolHelp snapshot +OpenProcess/TerminateProcess.shutdown(signal)signals every running child, waits up toshutdown_threshold, force kills the rest, stops all output readers, and returns once everything has exited. A second signal escalates immediately. Routes through the coordinator when started, runs inline when stopped.Arcborrowed by the tasks, so tasks can be moved between runtimes without losing tracked children, cache, or subscribers. Constructing outside a runtime leaves it stopped untilstart.instance/register(options)/try_instance, ornew/with_optionsfor independent registries.exec_cached, which coalesces concurrent identical runs into one execution. Failures are not cached.Supporting changes
SharedChild::try_wait(public): lets the reaper check for exit without tokio'swait, which closes stdin.SharedChild::wait: reaping a tokioChildviatry_waitdrops tokio's per-childSIGCHLDlistener, so a task already insidewaitlost its waker and hung. Found via stress testing; the existingkill_with_signalpath has the same latent race.waitnow also wakes on an exit recorded bytry_wait.windows-sysfeatures for the ToolHelp snapshot.Testing
tests/registry_test.rs(Unix), covering lifecycle, tracking, reaping without closing stdin, drop semantics, single and tree signalling, graceful/forced/inline shutdown, events, and cache coalescing. Passed 20/20 stress runs after the race fix.-D warnings), rustfmt, and rustdoc (-D warnings) are clean; the crate type-checks forx86_64-pc-windows-msvc. Linux was not compile-checked locally.exec_command_test::cancellation::force_kill_unblocks_continuous_input_with_inherited_stdinflakes roughly 1 in 10 runs onmasteras well (missing marker file); it is unrelated to this change.🤖 Generated with Claude Code