Skip to content

node:child_process: implement subprocess[Symbol.dispose] lifecycle method #2556

Closed

Description

@andrewtdiz

Summary

Current Node exposes subprocess[Symbol.dispose]() on ChildProcess; as of Node v24.2.0 it is no longer experimental and it calls subprocess.kill('SIGTERM'). Perry's child-process objects expose kill, ref, unref, and IPC methods, but do not expose or dispatch the well-known disposer method for child processes.

This leaves using child = spawn(...) / explicit child[Symbol.dispose]() cleanup paths incompatible even though the adjacent timer disposer support already exists.

Evidence

  • Current Node docs document subprocess[Symbol.dispose]() as stable and define it as calling subprocess.kill() with SIGTERM: https://nodejs.org/api/child_process.html#subprocesssymboldispose
  • test-files/test_parity_child_process.ts:125 explicitly skips subprocess[Symbol.dispose]() because symbol-key dispatch for this surface is not yet uniform.
  • Live spawn() ChildProcess objects are constructed with methods on, once, addListener, prependListener, removeListener, off, removeAllListeners, emit, kill, ref, and unref, but no disposer: crates/perry-runtime/src/child_process/reactor.rs:369-384.
  • fork() ChildProcess objects add send and disconnect, but likewise omit a disposer: crates/perry-runtime/src/child_process/fork.rs:72-89.
  • The generic native method dispatch has special well-known-dispose handling for timer handles only (__perry_dispose__ / @@__perry_wk_dispose clear timeout/interval/immediate IDs): crates/perry-runtime/src/object/native_call_method.rs:344-395.

Duplicate check

Searched issues and PRs for:

  • subprocess Symbol.dispose child_process dispose child.kill SIGTERM
  • child_process Symbol.dispose
  • subprocess dispose

No open or closed tracker for this child-process disposer gap was found. This is separate from #2555's option-semantics issue and from closed spawn / fork IPC work (#1933/#1934).

Acceptance sketch

  • child[Symbol.dispose]() exists on ChildProcess objects from both spawn() and fork().
  • Calling it invokes the same path as child.kill('SIGTERM') and returns undefined.
  • The well-known symbol lowering path (@@__perry_wk_dispose / class-member equivalent) routes to child-process disposal without affecting existing timer disposal behavior.
  • Add a deterministic parity test that creates a long-lived child, calls the disposer, and observes termination/cleanup without hanging.

Note: this issue was confirmed from committed source and current Node docs; no local target/release/perry binary was available in this checkout for a fresh runtime probe.

Activity

  1. andrewtdiz commented on Jun 2, 2026

    @andrewtdiz
    ContributorAuthor

    Taking this with #2717 and #3316 as a focused node:child_process lifecycle/IPC surface PR cut. Planned scope: ChildProcess Symbol.dispose dispatch, _forkChild enumerable export shape, and subprocess.send callback/closed-channel observable semantics. Non-goals: broad spawn/exec option semantics (#2555), setup arg validation (#3079), and child-side process IPC surface (#2529) unless a minimal helper is required for the selected tests.

  2. andrewtdiz commented on Jun 2, 2026

    @andrewtdiz
    ContributorAuthor

    Implemented in draft PR #4110.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions