Skip to content

fix(cluster): match Node 26 semantics - #7105

Merged
proggeramlug merged 1 commit into
mainfrom
fix/cluster-node26-parity
Aug 1, 2026
Merged

fix(cluster): match Node 26 semantics#7105
proggeramlug merged 1 commit into
mainfrom
fix/cluster-node26-parity

Conversation

@TheHypnoo

@TheHypnoo TheHypnoo commented Jul 31, 2026

Copy link
Copy Markdown
Member

Summary

  • Align node:cluster exports, worker lifecycle, validation, events, networking, and IPC with Node.js 26.5.0.
  • Preserve advanced structured-clone values across cluster worker IPC.
  • Stack this change on child-process parity PR fix(child-process): complete Node 26 parity #7089.

Changes

  • Implement the Node-compatible Worker surface, setup semantics, scheduling validation, and lifecycle ordering.
  • Propagate fork options and advanced IPC framing through the shared child-process runtime.
  • Fix the shared HIR/codegen behavior exposed by strict worker callbacks and optional chaining.
  • Guard the advanced-serialization fixture's primary-only setup call, matching Node's worker API availability.

Related issue

Closes #6772

Stacked on #7089; base: fix/child-process-node26-parity.

Test plan

  • cargo build -p perry --release
  • cargo test -p perry-codegen type_analysis --lib (12 passed)
  • ./run_parity_tests.sh --suite node-suite --module cluster (41 passed; 0 failures, compile failures, crashes, or skips)

Checklist

  • I have NOT bumped the workspace version or edited CLAUDE.md / CHANGELOG.md
  • My commits follow the conventional fix: format
  • I've read CONTRIBUTING.md and agree to the Code of Conduct

Summary by CodeRabbit

  • New Features

    • Expanded node:cluster compatibility with improved worker lifecycle events, listener management, worker APIs, networking, setup validation, and advanced IPC serialization.
    • Added support for advanced process messaging, including structured data and ArrayBuffer values.
    • Improved child-process argument handling and IPC channel controls.
  • Bug Fixes

    • Corrected conditional type handling, strict-mode declarations, callback validation, disconnect timing, and listener behavior.
  • Tests

    • Expanded cluster parity coverage; all 43 cluster fixtures now pass.
  • Documentation

    • Updated version information and documented Node.js 26 cluster parity improvements.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b1b96a55-53d2-4b02-8ae4-32f3d2c96b02

📥 Commits

Reviewing files that changed from the base of the PR and between 4cede62 and 76fa7b4.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (34)
  • CLAUDE.md
  • Cargo.toml
  • changelog.d/7105-node-cluster-node26-parity.md
  • crates/perry-codegen/src/lower_call/native_table/node_misc.rs
  • crates/perry-codegen/src/type_analysis/predicates.rs
  • crates/perry-ext-net/src/lib.rs
  • crates/perry-hir/src/lower/expr_call/native_module.rs
  • crates/perry-hir/src/lower_decl/block.rs
  • crates/perry-runtime/src/child_process/emitter.rs
  • crates/perry-runtime/src/child_process/fork.rs
  • crates/perry-runtime/src/child_process/reactor.rs
  • crates/perry-runtime/src/child_process/v8_serde.rs
  • crates/perry-runtime/src/child_process/validate.rs
  • crates/perry-runtime/src/cluster.rs
  • crates/perry-runtime/src/cluster_sched.rs
  • crates/perry-runtime/src/object/class_registry.rs
  • crates/perry-runtime/src/object/class_registry/construct.rs
  • crates/perry-runtime/src/object/instanceof.rs
  • crates/perry-runtime/src/object/native_module.rs
  • crates/perry-runtime/src/object/native_module/callable_exports.rs
  • crates/perry-runtime/src/object/native_module_dispatch/dispatch_a_c.rs
  • crates/perry-runtime/src/object/native_module_registry.rs
  • crates/perry-runtime/src/process.rs
  • crates/perry-runtime/src/process/ipc.rs
  • test-parity/node-suite/cluster/README.md
  • test-parity/node-suite/cluster/STATUS.md
  • test-parity/node-suite/cluster/default-import-shape.ts
  • test-parity/node-suite/cluster/events/listener-validation.ts
  • test-parity/node-suite/cluster/fork/roles-and-env.ts
  • test-parity/node-suite/cluster/serialization/advanced-tcp.ts
  • test-parity/node-suite/cluster/serialization/advanced.ts
  • test-parity/node-suite/cluster/setup/validation-exec-args.ts
  • test-parity/node-suite/cluster/setup/validation-serialization-inspect.ts
  • test-parity/node_suite_baseline.json

📝 Walkthrough

Walkthrough

This change completes node:cluster parity work across EventEmitter APIs, Worker lifecycle behavior, setup validation, networking, child-process execution, advanced IPC serialization, compiler lowering, and 43 parity fixtures. It also updates the package version and changelog.

Changes

Node cluster parity

Layer / File(s) Summary
Cluster API surface and Worker construction
crates/perry-codegen/..., crates/perry-hir/..., crates/perry-runtime/src/cluster.rs, crates/perry-runtime/src/object/..., test-parity/node-suite/cluster/events/*, test-parity/node-suite/cluster/default-import-shape.ts
Adds listener-management methods, Worker construction and prototypes, EventEmitter checks, dispatch wiring, and listener validation.
Worker lifecycle, setup, and networking
crates/perry-runtime/src/cluster.rs, crates/perry-runtime/src/child_process/..., crates/perry-runtime/src/process.rs, crates/perry-ext-net/src/lib.rs, test-parity/node-suite/cluster/fork/*
Adds cached worker detection, deferred lifecycle events, fork setup validation, execution-argument propagation, scheduling-policy handling, and worker listening notifications.
Advanced IPC framing and serialization
crates/perry-runtime/src/process/ipc.rs, crates/perry-runtime/src/child_process/{reactor.rs,v8_serde.rs}, crates/perry-runtime/src/cluster_sched.rs
Adds advanced IPC mode tracking, length-prefixed V8 frames, structured-clone serialization, ArrayBuffer support, advanced query replies, and mode-specific readers.
Conditional typing and strict block lowering
crates/perry-codegen/src/type_analysis/predicates.rs, crates/perry-hir/src/lower_decl/block.rs
Keeps conditional expressions unknown when either branch is unknown and adds strict-mode block function declaration hoisting.
Parity coverage and release metadata
test-parity/node-suite/cluster/serialization/*, test-parity/node-suite/cluster/setup/*, test-parity/node-suite/cluster/README.md, test-parity/node-suite/cluster/STATUS.md, test-parity/node_suite_baseline.json, changelog.d/*, Cargo.toml, CLAUDE.md
Adds advanced TCP coverage, updates cluster status from 15/41 to 43/43, and updates version and changelog metadata.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • PerryTS/perry#6931: Both changes extend the native module callable-export attach registry for cluster support.
  • PerryTS/perry#7089: Both changes modify child-process fork, emitter, reactor, validation, and V8 serialization code.

Suggested labels: parity, rust

Suggested reviewers: proggeramlug

Sequence Diagram(s)

sequenceDiagram
  participant Primary
  participant ClusterWorker
  participant ChildIpc
  participant TcpServer
  Primary->>ClusterWorker: fork worker with advanced serialization
  ClusterWorker->>ChildIpc: send listening address and port
  ChildIpc->>Primary: deliver advanced IPC frame
  Primary->>TcpServer: connect to worker address
  TcpServer->>Primary: return TCP response
  Primary->>ClusterWorker: disconnect worker
  ClusterWorker->>Primary: emit exit status
Loading
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cluster-node26-parity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@TheHypnoo TheHypnoo added the type:bug Bug fix label Jul 31, 2026
@TheHypnoo
TheHypnoo marked this pull request as ready for review July 31, 2026 08:16
@TheHypnoo
TheHypnoo force-pushed the fix/cluster-node26-parity branch from 89944e7 to 140253d Compare July 31, 2026 11:54
Base automatically changed from fix/child-process-node26-parity to main August 1, 2026 05:39
@proggeramlug
proggeramlug force-pushed the fix/cluster-node26-parity branch from 140253d to aed4fed Compare August 1, 2026 08:18
Align cluster exports, worker lifecycle, validation, events, networking, and IPC with Node.js 26.5.0. Complete the maintainer audit for EventEmitter semantics, worker identity and lifecycle, advanced IPC framing, scheduling, and parity coverage.

Closes #6772
@proggeramlug
proggeramlug force-pushed the fix/cluster-node26-parity branch from aed4fed to 76fa7b4 Compare August 1, 2026 08:20
@proggeramlug
proggeramlug merged commit 76fa7b4 into main Aug 1, 2026
@proggeramlug
proggeramlug deleted the fix/cluster-node26-parity branch August 1, 2026 08:20
proggeramlug pushed a commit to jdalton/perry that referenced this pull request Aug 1, 2026
`every_dispatch_entry_has_manifest_counterpart` listed 14 missing rows at
origin/main; this branch as authored fixed 3 of them (dgram::sendto,
sqlite::serialize/deserialize). The other 11 landed on main *after* the
branch point, so merging main re-reds the very gate the branch exists to
turn green:

  inspector::log/info/debug/warn/error, inspector/promises::SessionCall
      — PerryTS#7090 (47040d5) inspector Node 26.5 parity
  cluster::listeners/rawListeners/setMaxListeners/getMaxListeners
      — PerryTS#7105 (76fa7b4) cluster Node 26 semantics
  lru-cache::peek
      — PerryTS#7136 (5f5006a) lru-cache faithful JS-value keys/values

Rows mirror how each surface is already modelled:

- the five `inspector.console.*` forwarders carry the dispatch table's
  `class_filter: Some("console")`, so they hang off the existing
  `property("inspector", "console")` instead of becoming named exports;
- `inspector/promises::SessionCall` is the synthetic row for `Session(...)`
  called without `new` (js_node_inspector_session_call_without_new), so it
  is `internal_method` — the .d.ts keeps advertising `Session`;
- the four `cluster` EventEmitter methods join their eleven siblings as
  `internal_method` + paired `internal_property`, matching the PerryTS#3687 block
  directly above them.

All rows use the plain `method`/`internal_method` helpers (params: &[],
returns: Any), which `manifest_param_counts_match_dispatch_table`
deliberately skips as the "no signature data" fallback — so no arity claim
is invented for them.

manifest_consistency: 5 passed / 0 failed (was 2 passed / 3 failed at
origin/main, 4 passed / 1 failed with only the original branch fix).
docs/src/api/reference.md regenerated: +6 rendered entries (the internal_*
rows stay out of the public surface, as cluster's existing ones already do);
docs/api/perry.d.ts is byte-unchanged, since nothing added is a named export.
proggeramlug pushed a commit that referenced this pull request Aug 1, 2026
…ble (#7159)

* fix(api-manifest): reconcile API_MANIFEST with the native dispatch table

The manifest_consistency drift guards in perry-codegen were red on main:

- every_native_module_has_at_least_one_manifest_entry / #513: iovalkey
  (a NATIVE_MODULES member and well_known_bindings entry that normalizes
  to ioredis in dispatch) had zero API_MANIFEST rows, so strict mode
  never engaged for it. Add the Redis class + createClient rows,
  mirroring the redis alias.
- every_dispatch_entry_has_manifest_counterpart: dgram Socket.sendto and
  sqlite DatabaseSync.serialize/deserialize existed in NATIVE_MODULE_TABLE
  with no manifest counterpart. Add the matching receiver-method rows.
- every_well_known_binding_has_manifest_entry: the test's inline TOML
  parser misread the new [bindings.*.upstream] provenance sub-tables as
  binding names (dotenv.upstream, iovalkey.upstream, ...). Teach it to
  skip nested sub-tables so it only checks real routed module names.

Regenerate docs/api/perry.d.ts and docs/src/api/reference.md from the
manifest (api-docs-drift gate); this also folds in the previously
uncommitted node-forge and tls.convertALPNProtocols entries.

* chore(changelog): key the fragment to PR 7159

changelog.d fragments are named <PR>-<slug>.md (changelog.d/README.md), so
in-flight PRs never collide. This one was keyed to the issue it fixes (0513)
rather than the PR.

Also confirms the merge resolution: regenerating both API-docs artifacts from
the merged manifest reproduces the committed files byte-for-byte, and their
only delta against main is the "Coverage:"/"Total:" header count — main's
#7118 regenerated the artifacts without adding manifest rows, so nothing from
main is dropped.

* fix(api-manifest): cover the dispatch rows main added after this branch

`every_dispatch_entry_has_manifest_counterpart` listed 14 missing rows at
origin/main; this branch as authored fixed 3 of them (dgram::sendto,
sqlite::serialize/deserialize). The other 11 landed on main *after* the
branch point, so merging main re-reds the very gate the branch exists to
turn green:

  inspector::log/info/debug/warn/error, inspector/promises::SessionCall
      — #7090 (47040d5) inspector Node 26.5 parity
  cluster::listeners/rawListeners/setMaxListeners/getMaxListeners
      — #7105 (76fa7b4) cluster Node 26 semantics
  lru-cache::peek
      — #7136 (5f5006a) lru-cache faithful JS-value keys/values

Rows mirror how each surface is already modelled:

- the five `inspector.console.*` forwarders carry the dispatch table's
  `class_filter: Some("console")`, so they hang off the existing
  `property("inspector", "console")` instead of becoming named exports;
- `inspector/promises::SessionCall` is the synthetic row for `Session(...)`
  called without `new` (js_node_inspector_session_call_without_new), so it
  is `internal_method` — the .d.ts keeps advertising `Session`;
- the four `cluster` EventEmitter methods join their eleven siblings as
  `internal_method` + paired `internal_property`, matching the #3687 block
  directly above them.

All rows use the plain `method`/`internal_method` helpers (params: &[],
returns: Any), which `manifest_param_counts_match_dispatch_table`
deliberately skips as the "no signature data" fallback — so no arity claim
is invented for them.

manifest_consistency: 5 passed / 0 failed (was 2 passed / 3 failed at
origin/main, 4 passed / 1 failed with only the original branch fix).
docs/src/api/reference.md regenerated: +6 rendered entries (the internal_*
rows stay out of the public surface, as cluster's existing ones already do);
docs/api/perry.d.ts is byte-unchanged, since nothing added is a named export.

* docs(changelog): note the post-branch dispatch rows in the 7159 fragment

---------

Co-authored-by: Ralph Küpper <ralph@skelpo.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[parity] node:cluster — 27 failing node-suite tests (2026-07-22 baseline)

2 participants