Repository: nodejs/node
Pull request: process: fix symbol name and mark experimental new process methods

The methods landed (and were released 😞) with two shortcomings:

- The added methods were not marked as experimental.
- The symbol name they used did not follow our conventions: https://github.com/nodejs/node/blob/cd4f4b4dfac4d96316058e12aafdc2737ed43f72/doc/contributing/using-symbols.md#L67-L68

Refs: https://github.com/nodejs/node/pull/56400#discussion_r1906543664

<!--
Before submitting a pull request, please read:

- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md
- the commit message formatting guidelines at
  https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

If you believe this PR should be highlighted in the Node.js CHANGELOG
please add the `notable-change` label.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->


Changed files:
filename: doc/api/process.md
patch: @@ -3248,11 +3248,13 @@ console.log(`The parent process is pid ${ppid}`);
 added: v23.6.0
 -->
 
+> Stability: 1 - Experimental
+
 * `maybeRefable` {any} An object that may be "refable".
 
 An object is "refable" if it implements the Node.js "Refable protocol".
-Specifically, this means that the object implements the `Symbol.for('node:ref')`
-and `Symbol.for('node:unref')` methods. "Ref'd" objects will keep the Node.js
+Specifically, this means that the object implements the `Symbol.for('nodejs.ref')`
+and `Symbol.for('nodejs.unref')` methods. "Ref'd" objects will keep the Node.js
 event loop alive, while "unref'd" objects will not. Historically, this was
 implemented by using `ref()` and `unref()` methods directly on the objects.
 This pattern, however, is being deprecated in favor of the "Refable protocol"
@@ -4307,11 +4309,13 @@ In [`Worker`][] threads, `process.umask(mask)` will throw an exception.
 added: v23.6.0
 -->
 
+> Stability: 1 - Experimental
+
 * `maybeUnfefable` {any} An object that may be "unref'd".
 
 An object is "unrefable" if it implements the Node.js "Refable protocol".
-Specifically, this means that the object implements the `Symbol.for('node:ref')`
-and `Symbol.for('node:unref')` methods. "Ref'd" objects will keep the Node.js
+Specifically, this means that the object implements the `Symbol.for('nodejs.ref')`
+and `Symbol.for('nodejs.unref')` methods. "Ref'd" objects will keep the Node.js
 event loop alive, while "unref'd" objects will not. Historically, this was
 implemented by using `ref()` and `unref()` methods directly on the objects.
 This pattern, however, is being deprecated in favor of the "Refable protocol"

filename: lib/internal/process/per_thread.js
patch: @@ -421,12 +421,14 @@ function toggleTraceCategoryState(asyncHooksEnabled) {
 const { arch, platform, version } = process;
 
 function ref(maybeRefable) {
-  const fn = maybeRefable?.[SymbolFor('node:ref')] || maybeRefable?.ref;
+  const fn = maybeRefable?.[SymbolFor('nodejs.ref')] || maybeRefable?.[SymbolFor('node:ref')] || maybeRefable?.ref;
   if (typeof fn === 'function') FunctionPrototypeCall(fn, maybeRefable);
 }
 
 function unref(maybeRefable) {
-  const fn = maybeRefable?.[SymbolFor('node:unref')] || maybeRefable?.unref;
+  const fn = maybeRefable?.[SymbolFor('nodejs.unref')] ||
+             maybeRefable?.[SymbolFor('node:unref')] ||
+             maybeRefable?.unref;
   if (typeof fn === 'function') FunctionPrototypeCall(fn, maybeRefable);
 }
 

filename: test/parallel/test-process-ref-unref.js
patch: @@ -23,6 +23,18 @@ class Foo {
 }
 
 class Foo2 {
+  refCalled = 0;
+  unrefCalled = 0;
+  [Symbol.for('nodejs.ref')]() {
+    this.refCalled++;
+  }
+  [Symbol.for('nodejs.unref')]() {
+    this.unrefCalled++;
+  }
+}
+
+// TODO(aduh95): remove support for undocumented symbol
+class Foo3 {
   refCalled = 0;
   unrefCalled = 0;
   [Symbol.for('node:ref')]() {
@@ -39,14 +51,19 @@ describe('process.ref/unref work as expected', () => {
     // just work.
     const foo1 = new Foo();
     const foo2 = new Foo2();
+    const foo3 = new Foo3();
     process.ref(foo1);
     process.unref(foo1);
     process.ref(foo2);
     process.unref(foo2);
+    process.ref(foo3);
+    process.unref(foo3);
     strictEqual(foo1.refCalled, 1);
     strictEqual(foo1.unrefCalled, 1);
     strictEqual(foo2.refCalled, 1);
     strictEqual(foo2.unrefCalled, 1);
+    strictEqual(foo3.refCalled, 1);
+    strictEqual(foo3.unrefCalled, 1);
 
     // Objects that implement the legacy API also just work.
     const i = setInterval(() => {}, 1000);