Stop owned processes when their coroutine exits
Asynchronous processes left behind by their starting coroutine could retain native process resources until shutdown. Output callback failures could also interrupt cleanup in framework callers using Symfony Process directly.
Track asynchronous processes weakly in their owning coroutine and stop any remaining children when that coroutine exits. Explicitly detached processes remain detached, and processes started outside a coroutine retain their existing lifetime.
Share the output-failure cleanup guard with schema commands, queue listeners and Composer operations. Move suitable test fixtures onto the Process API, retain independent cleanup in termination regressions, and document when tests should use the framework API or Symfony Process directly.
Targeted tests cover coroutine exit, cancellation, callback failures, process pools and non-coroutine execution. Source analysis and affected tests pass; the full suite and service matrices run in CI.
Summary by cubic
Stops asynchronous processes when the coroutine that started them exits, so orphaned native process resources are released instead of lingering until shutdown.
- Processes started outside a coroutine, or explicitly detached with
create_new_console, keep their previous lifetime and require manualwaitorstop. - Output callback failures in MySQL/Postgres schema dumps, queue listeners, and Composer operations stop the child process before rethrowing; when that emergency cleanup also cancels, the original callback failure is preserved, including when it already wraps a cancellation.
- Test fixtures that only need coroutine-lifetime cleanup now use the Process API; termination-timing tests keep explicit cleanup.
supportandfoundationnow declare a direct dependency onsymfony/process;processadds ahypervel/contextdependency.
[!NOTE]
Stop owned processes automatically when their starting coroutine exits
PendingProcess::start now registers the Symfony process in the current coroutine's ProcessState; ProcessState.php stops all tracked processes via a coroutine defer callback when the owner exits, including on cancellation. Processes started outside a coroutine or with create_new_console are not registered.
- Moves
GuardsProcessOutput from Hypervel\Process\Concerns to Hypervel\Support\Traits in GuardsProcessOutput.php. On an output-callback exception it attempts Process.stop(0) up to twice and picks between the callback exception and any cleanup cancellation when rethrowing.
- Applies the guard to dump, queue worker, and Composer package-command callbacks in
MySqlSchemaState, PostgresSchemaState, Listener, and Composer, so a throwing output callback stops the subprocess before the exception propagates.
- Updates process, testing, and porting docs to describe coroutine ownership, pool cleanup, and explicit stop guidance; many tests add
finally cleanup or switch to the Hypervel process API.
- Behavioral Change: installing the foundation and support packages now requires
symfony/process ^8.1, and the process package requires hypervel/context ^0.4 (composer.json, composer.json). Existing consumers importing GuardsProcessOutput from Hypervel\Process\Concerns must update to the new namespace.
Macroscope summarized 57e74a4.
Summary by CodeRabbit
- New Features
- Asynchronous processes and process pools are now stopped automatically when their owning coroutine exits, including when it is canceled. Detached processes remain independent of coroutine cleanup.
- Output-handler failures now trigger process cleanup before the original error is surfaced.
- Documentation
- Clarified process ownership, cancellation, detachment, and cleanup guidance for asynchronous processes, pools, testing, and Laravel migrations.