-
Notifications
You must be signed in to change notification settings - Fork 15
feat(utils): add NodeJS profiler #1219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add explanation that sink determines output format (DevTools TraceEvent, OpenTelemetry, etc.) - Improve documentation clarity for flexible serialization capabilities - Fix duplicate imports in profiler unit test
- Replace method implementations with vi.fn() spy functions - Add vi import from vitest - Enables better testing with call tracking and assertions
|
View your CI Pipeline Execution ↗ for commit 9b75840
☁️ Nx Cloud last updated this comment at |
@code-pushup/ci
@code-pushup/cli
@code-pushup/core
@code-pushup/create-cli
@code-pushup/models
@code-pushup/nx-plugin
@code-pushup/axe-plugin
@code-pushup/coverage-plugin
@code-pushup/eslint-plugin
@code-pushup/js-packages-plugin
@code-pushup/jsdocs-plugin
@code-pushup/lighthouse-plugin
@code-pushup/typescript-plugin
@code-pushup/utils
commit: |
Code PushUp🤨 Code PushUp report has both improvements and regressions – compared current commit b341e30 with previous commit 270b474. 🕵️ See full comparison in Code PushUp portal 🔍 🏷️ Categories👍 3 groups improved, 👎 2 groups regressed, 👍 7 audits improved, 👎 8 audits regressed, 20 audits changed without impacting score🗃️ Groups
29 other groups are unchanged. 🛡️ Audits
644 other audits are unchanged. |
Code PushUp🤨 Code PushUp report has both improvements and regressions – compared current commit b341e30 with previous commit 270b474. 💼 Project
|
| 🏷️ Category | ⭐ Previous score | ⭐ Current score | 🔄 Score change |
|---|---|---|---|
| Documentation | 🔴 45 | 🟡 56 | |
| Code coverage | 🟢 95 | 🟢 95 |
4 other categories are unchanged.
👍 1 group improved, 👎 1 group regressed, 👍 6 audits improved, 👎 3 audits regressed
🗃️ Groups
| 🔌 Plugin | 🗃️ Group | ⭐ Previous score | ⭐ Current score | 🔄 Score change |
|---|---|---|---|---|
| JSDocs coverage | Documentation coverage | 🔴 45 | 🟡 56 | |
| Code coverage | Code coverage metrics | 🟢 95 | 🟢 95 |
13 other groups are unchanged.
🛡️ Audits
| 🔌 Plugin | 🛡️ Audit | 📏 Previous value | 📏 Current value | 🔄 Value change |
|---|---|---|---|---|
| JSDocs coverage | Properties coverage | 🟥 27 undocumented properties | 🟥 23 undocumented properties | |
| JSDocs coverage | Classes coverage | 🟨 3 undocumented classes | 🟨 2 undocumented classes | |
| JSDocs coverage | Methods coverage | 🟨 13 undocumented methods | 🟨 9 undocumented methods | |
| JSDocs coverage | Variables coverage | 🟥 49 undocumented variables | 🟥 48 undocumented variables | |
| JSDocs coverage | Types coverage | 🟥 66 undocumented types | 🟥 65 undocumented types | |
| JSDocs coverage | Functions coverage | 🟥 239 undocumented functions | 🟥 239 undocumented functions | |
| Code coverage | Branch coverage | 🟩 91.8 % | 🟩 91.6 % | |
| Code coverage | Function coverage | 🟩 96.2 % | 🟩 96 % | |
| Code coverage | Line coverage | 🟩 97.8 % | 🟩 97.8 % |
435 other audits are unchanged.
13 other projects are unchanged.
Co-authored-by: Hanna Skryl <80118140+hanna-skryl@users.noreply.github.com>
| * @throws {Error} If the sink is closed before subscription | ||
| * | ||
| */ | ||
| subscribe(): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The subscribe() method doesn't actually check if the sink is closed or throw an error. 🤔
| /** Sink for buffering and flushing performance data | ||
| * @NOTE this is dummy code and will be replaced by PR #1210 | ||
| **/ | ||
| sink: Sink<DomainEvents, unknown> & Recoverable; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the intention here to wait until the referenced PR merges and refactor this fragment?
| it('should write to file on flush', () => { | ||
| expect(true).toBe(true); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are you checking here? 😅
|
|
||
| // Initial state: idle | ||
| expect(profiler.isRunning()).toBe(false); | ||
| expect(profiler.activeat()).toBe(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| expect(profiler.activeat()).toBe(false); | |
| expect(profiler.activate()).toBe(false); |
| try { | ||
| this.#queue.forEach(item => { | ||
| this.#sink.write(item); | ||
| this.#written++; | ||
| }); | ||
| } catch (error) { | ||
| this.#dropped += this.#queue.length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like #dropped can potentially overcount if write() throws partway through the queue.
| } | ||
| this.#observer?.disconnect(); | ||
| this.flush(); | ||
| this.#queue.length = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The this.#queue.length = 0 line is redundant since flush() always clears the queue in its finally block.
| this.#queue.length = 0; |
| * This means any future {@link Profiler} instantiations (including child processes) will use the same enabled state. | ||
| * | ||
| * @param enabled - Whether profiling should be enabled | ||
| */ | ||
| setEnabled(enabled: boolean): void { | ||
| process.env[PROFILER_ENABLED_ENV_VAR] = `${enabled}`; | ||
| this.#enabled = enabled; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The JSDoc doesn't match the implementation now that setEnabled intentionally only modifies the instance's private state.
| expect(profiler.isEnabled()).toBe(false); | ||
| expect(sink.isClosed()).toBe(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was about to suggest replacing toBe(true)/toBe(false) with toBeTrue()/toBeFalse() per our jest-extended rules, but then started wondering why ESLint wasn't flagging these automatically. After investigating, I found the root cause.
eslint-plugin-jest-extended only detects global expect, not imported expect. Since test files explicitly import from vitest, ESLint sees expect as an imported identifier, not a global, so the rules never match.
Vitest config factory already includes globals: true, so these imports are redundant at runtime. Removing them would enable jest-extended ESLint rules to fire correctly and surface existing violations.
Related: #1197
This PR includes:
NodeJSProfilerclassNodeJSProfilerPerformanceObserverSink- add getStatus for better testing, more robust and memory friendly buffer logic