From 43a26753e342fe1644907b3bd96e7b20ffbf2763 Mon Sep 17 00:00:00 2001 From: JamesHenry Date: Tue, 29 Oct 2024 17:29:00 +0400 Subject: [PATCH 1/4] chore: replace FinalizationRegistry usage with WeakRef to fix test on Node 20.18.0 --- packages/rxjs/spec/Subscriber-spec.ts | 57 +++++++++++++++------------ 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/rxjs/spec/Subscriber-spec.ts b/packages/rxjs/spec/Subscriber-spec.ts index 84220e7411..08f3290485 100644 --- a/packages/rxjs/spec/Subscriber-spec.ts +++ b/packages/rxjs/spec/Subscriber-spec.ts @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import type { Observer} from 'rxjs'; +import type { Observer } from 'rxjs'; import { Subscriber, Observable, of, config, operate } from 'rxjs'; import * as sinon from 'sinon'; import { asInteropSubscriber } from './helpers/interop-helper'; @@ -301,35 +301,40 @@ describe('Subscriber', () => { }); }); - const FinalizationRegistry = (global as any).FinalizationRegistry; - if (FinalizationRegistry && global.gc) { - it('should not leak the destination', (done) => { - let observer: Observer | undefined = { - next() { - /* noop */ - }, - error() { - /* noop */ - }, - complete() { - /* noop */ - }, - }; + it('should not leak the destination', function (done) { + this.timeout(10000); - const registry = new FinalizationRegistry((value: any) => { - expect(value).to.equal('observer'); - done(); - }); - registry.register(observer, 'observer'); + const observer: Observer | undefined = { + next() { + /* noop */ + }, + error() { + /* noop */ + }, + complete() { + /* noop */ + }, + }; + + /** + * Use WeakRef instead of FinalizationRegistry (as was originally used). Per MDN, FinalizationRegistry is not a deterministic enough mechanism + * on which to base reliable tests: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry + */ + const weakRef = new WeakRef(observer); - const subscription = of(42).subscribe(observer); + // Subscribe to the observable which will complete and unsubscribe automatically. This should not cause any remaining references to the observer after garbage collection. + of(42).subscribe(observer); - observer = undefined; + setTimeout(() => { global.gc?.(); - }); - } else { - console.warn(`No support for FinalizationRegistry in Node ${process.version}`); - } + + if (weakRef.deref() === undefined) { + done(); + } else { + done(new Error('Observer was not garbage collected - possible memory leak')); + } + }, 1000); + }); }); describe('operate', () => { From e375951012e4f768c4b54d98fa57cb65833d824d Mon Sep 17 00:00:00 2001 From: JamesHenry Date: Tue, 29 Oct 2024 17:34:28 +0400 Subject: [PATCH 2/4] chore: fail-fast false on matrix --- .github/workflows/ci_main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci_main.yml b/.github/workflows/ci_main.yml index 0bb556da4f..a106949412 100644 --- a/.github/workflows/ci_main.yml +++ b/.github/workflows/ci_main.yml @@ -11,6 +11,8 @@ jobs: build: runs-on: ubuntu-latest strategy: + # Prevent GitHub from canceling all in-progress jobs when a matrix job fails + fail-fast: false matrix: node: ['18', '20'] From 4fb8a2e0b0254f81f105a22aa5462bf992e47d75 Mon Sep 17 00:00:00 2001 From: JamesHenry Date: Tue, 29 Oct 2024 18:03:30 +0400 Subject: [PATCH 3/4] chore: run node with --expose-gc for mocha tests to support Node 18 --- packages/rxjs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rxjs/package.json b/packages/rxjs/package.json index 90c26e6051..d360f7eddc 100644 --- a/packages/rxjs/package.json +++ b/packages/rxjs/package.json @@ -61,7 +61,7 @@ "scripts": { "lint": "eslint --ext=ts,js src spec spec-dtslint", "dtslint": "npm run lint && tsc -b ./src/tsconfig.types.json", - "test": "cross-env TS_NODE_PROJECT=tsconfig.mocha.json mocha --config spec/support/.mocharc.js \"spec/**/*-spec.ts\"", + "test": "cross-env TS_NODE_PROJECT=tsconfig.mocha.json node --expose-gc ../../node_modules/.bin/_mocha --config spec/support/.mocharc.js \"spec/**/*-spec.ts\"", "test:esm": "node spec/module-test-spec.mjs", "test:circular": "dependency-cruiser --validate .dependency-cruiser.json -x \"^node_modules\" dist/esm", "test:import": "node integration/import/runner.js", From 72884e22b93aab8e58e12e2e8b90d24748f469c0 Mon Sep 17 00:00:00 2001 From: JamesHenry Date: Tue, 29 Oct 2024 18:47:52 +0400 Subject: [PATCH 4/4] chore: align lib types across rxjs and observable packages --- packages/rxjs/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rxjs/tsconfig.json b/packages/rxjs/tsconfig.json index 691cab447c..fe5f879a2f 100644 --- a/packages/rxjs/tsconfig.json +++ b/packages/rxjs/tsconfig.json @@ -9,7 +9,7 @@ "moduleResolution": "node", "stripInternal": true, "noEmit": true, - "lib": ["esnext", "dom"], + "lib": ["es2022", "dom"], "target": "esnext", "baseUrl": ".", "paths": {