Skip to content
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

perf_hooks: add ability to fetch performance entries synchronously #39297

Closed
wants to merge 2 commits into from

Conversation

legendecas
Copy link
Member

@legendecas legendecas commented Jul 7, 2021

All API introduced in this PR are compliant with web performance-timeline spec. "performance-timeline" is listed as supported web spec in the doc https://nodejs.org/docs/latest/api/perf_hooks.html#perf_hooks_performance_measurement_apis.

Changes summary:

  1. Add new supported wpt test subsets: user-timing and performance-timeline.
  2. Add support for Performance.getEntries, Performance.getEntriesByName and Performance.getEntriesByType to synchronously fetch buffered performance entries. This means the user should invoke Performance.clearMarks and Performance.clearMeasures to clear buffered entries to prevent from those entries been kept alive forever.
  3. Add support (again after perf_hooks: complete overhaul of the implementation #37136) for buffered flags for PerformanceObserver.
  4. Fixes PerformanceMark and PerformanceMeasure wpt compliance issues
  5. Only user-created performance entries will be buffered globally. This behavior should be compliant with https://w3c.github.io/timing-entrytypes-registry/#registry.

With the new ability to fetch user-created performance entries synchronously, I believe issues raised in nodejs/diagnostics#464 (comment) could also be fixed.

Performance comparison:

                                                     confidence improvement accuracy (*)   (**)  (***)
perf_hooks/usertiming.js observe='all' n=100000            ***     -3.69 %       ±1.77% ±2.36% ±3.09%
perf_hooks/usertiming.js observe='measure' n=100000        ***    -23.74 %       ±2.45% ±3.27% ±4.28%

@github-actions github-actions bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Jul 7, 2021
@legendecas legendecas requested a review from jasnell July 7, 2021 16:45
@legendecas legendecas added the perf_hooks Issues and PRs related to the implementation of the Performance Timing API. label Jul 7, 2021
@jasnell
Copy link
Member

jasnell commented Jul 7, 2021

I'm not convinced we should do this. The persistent marks and measures were removed to avoid the Very Likely chance that they would become a memory leak in server code. If the user is not very careful about clearing those, it'll become a problem very quickly.

@legendecas
Copy link
Member Author

legendecas commented Jul 8, 2021

@jasnell The persistent marks and measures were removed

I'm confused about this statement. The marks are always persistent either with the change of #37136, and users should clear them with Performance.clearMarks in Node.js already. Regarding the spec, the APIs are designed to be used with clearMarks and clearMeasures. So I do not get your point of memory leaks problem. If that is a problem, then that is already a real problem but not introduced in this PR.

lib/internal/perf/observe.js Outdated Show resolved Hide resolved
lib/internal/perf/observe.js Outdated Show resolved Hide resolved
lib/internal/perf/observe.js Outdated Show resolved Hide resolved
@jasnell
Copy link
Member

jasnell commented Jul 8, 2021

@legendecas :

I'm confused about this statement. The marks are always persistent either with the change of #37136, and users should clear them with Performance.clearMarks in Node.js already. Regarding the spec, the APIs are designed to be used with clearMarks and clearMeasures. So I do not get your point of memory leaks problem. If that is a problem, then that is already a real problem but not introduced in this PR.

The marks are stored, yes, using as little memory as possible. The associated PerformanceEntry objects are not, and that's what I'm referring to as a potential memory leak here. Currently, the longest time we queue up the PerformanceEntry objects is a single event loop turn while they are collected before they are emitted to the PerformanceObserver. It's a potential footgun if people aren't aware (keep in mind that users may not even know that they need to call clearMarks() if a buggy dependency is filling up the queue.

Perhaps we could add a process.emitWarning() in here if the queue grows past a given threshhold?

@legendecas
Copy link
Member Author

@jasnell Perhaps we could add a process.emitWarning() in here if the queue grows past a given threshhold?

This sounds pretty good! I'll do an update.

@nodejs-github-bot

This comment has been minimized.

@nodejs-github-bot

This comment has been minimized.

@nodejs-github-bot

This comment has been minimized.

@nodejs-github-bot
Copy link
Collaborator

@legendecas
Copy link
Member Author

Landed in 062f8e3

legendecas added a commit that referenced this pull request Jul 25, 2021
All API introduced in this PR are compliant with web
[performance-timeline](https://w3c.github.io/performance-timeline)
spec. "performance-timeline" is listed as supported web spec in the doc
https://nodejs.org/docs/latest/api/perf_hooks.html#perf_hooks_performance_measurement_apis.

Changes summary:
1. Add new supported wpt test subsets: user-timing and
  performance-timeline.
2. Add support for `Performance.getEntries`,
  `Performance.getEntriesByName` and `Performance.getEntriesByType`
  to synchronously fetch buffered performance entries. This means
  the user should invoke `Performance.clearMarks` and
  `Performance.clearMeasures` to clear buffered entries to prevent from
  those entries been kept alive forever.
3. Add support (again after #37136)
  for `buffered` flags for `PerformanceObserver`.
3. Fixes `PerformanceMark` and `PerformanceMeasure` wpt compliance
  issues.
4. Only user-created performance entries will be buffered globally. This
  behavior should be compliant with
  https://w3c.github.io/timing-entrytypes-registry/#registry.

With the new ability to fetch user-created performance entries
synchronously, the issues raised in
nodejs/diagnostics#464 (comment)
could also be fixed.

PR-URL: #39297
Reviewed-By: James M Snell <jasnell@gmail.com>
@legendecas legendecas closed this Jul 25, 2021
@legendecas legendecas deleted the wpt/user-timing branch July 25, 2021 15:44
@targos targos added the semver-minor PRs that contain new features and should be released in the next minor version. label Jul 25, 2021
@targos
Copy link
Member

targos commented Jul 25, 2021

this seems semver-minor?

@legendecas
Copy link
Member Author

this seems semver-minor?

Yeah, it doesn't introduce breaking changes to the v16.x line. But it depends on #37136 and changed various API semantics (compared to v12.x and v14.x) to be compliant with web specs, it should not be landed on v12.x and v14.x.

targos pushed a commit that referenced this pull request Jul 26, 2021
All API introduced in this PR are compliant with web
[performance-timeline](https://w3c.github.io/performance-timeline)
spec. "performance-timeline" is listed as supported web spec in the doc
https://nodejs.org/docs/latest/api/perf_hooks.html#perf_hooks_performance_measurement_apis.

Changes summary:
1. Add new supported wpt test subsets: user-timing and
  performance-timeline.
2. Add support for `Performance.getEntries`,
  `Performance.getEntriesByName` and `Performance.getEntriesByType`
  to synchronously fetch buffered performance entries. This means
  the user should invoke `Performance.clearMarks` and
  `Performance.clearMeasures` to clear buffered entries to prevent from
  those entries been kept alive forever.
3. Add support (again after #37136)
  for `buffered` flags for `PerformanceObserver`.
3. Fixes `PerformanceMark` and `PerformanceMeasure` wpt compliance
  issues.
4. Only user-created performance entries will be buffered globally. This
  behavior should be compliant with
  https://w3c.github.io/timing-entrytypes-registry/#registry.

With the new ability to fetch user-created performance entries
synchronously, the issues raised in
nodejs/diagnostics#464 (comment)
could also be fixed.

PR-URL: #39297
Reviewed-By: James M Snell <jasnell@gmail.com>
BethGriggs added a commit that referenced this pull request Jul 26, 2021
Notable changes:

build:
  * (SEMVER-MINOR) reset embedder string to "-node.0" (Michaël Zasso) #39470
deps:
  * (SEMVER-MINOR) restore minimum ICU version to 68 (Michaël Zasso) #39470
  * (SEMVER-MINOR) make V8 9.2 abi-compatible with 9.0 (Michaël Zasso) #39470
  * (SEMVER-MINOR) update V8 to 9.2.230.21 (Michaël Zasso) #39470
inspector:
  * mark as stable (Gireesh Punathil) #37748
perf_hooks:
  * (SEMVER-MINOR) web performance timeline compliance (legendecas) #39297
punycode:
  * add pending deprecation (Antoine du Hamel) #38444
repl:
  * (SEMVER-MINOR) enable --experimental-repl-await /w opt-out (hemanth.hm) #34733

PR-URL: TODO
@BethGriggs BethGriggs mentioned this pull request Jul 26, 2021
legendecas added a commit that referenced this pull request Jul 27, 2021
The option buffered is not about queueing the PerformanceEntrys with
an event loop task or not. The option buffered in the spec is about
filling the observer with the global PerformanceEntry buffer. The
current (and the spec) behavior is different with Node.js
version <= v16.0.0.

PR-URL: #39514
Refs: https://w3c.github.io/performance-timeline/#observe-method
Refs: https://nodejs.org/dist/latest-v14.x/docs/api/perf_hooks.html#perf_hooks_performanceobserver_observe_options
Refs: #39297
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
richardlau pushed a commit that referenced this pull request Jul 29, 2021
All API introduced in this PR are compliant with web
[performance-timeline](https://w3c.github.io/performance-timeline)
spec. "performance-timeline" is listed as supported web spec in the doc
https://nodejs.org/docs/latest/api/perf_hooks.html#perf_hooks_performance_measurement_apis.

Changes summary:
1. Add new supported wpt test subsets: user-timing and
  performance-timeline.
2. Add support for `Performance.getEntries`,
  `Performance.getEntriesByName` and `Performance.getEntriesByType`
  to synchronously fetch buffered performance entries. This means
  the user should invoke `Performance.clearMarks` and
  `Performance.clearMeasures` to clear buffered entries to prevent from
  those entries been kept alive forever.
3. Add support (again after #37136)
  for `buffered` flags for `PerformanceObserver`.
3. Fixes `PerformanceMark` and `PerformanceMeasure` wpt compliance
  issues.
4. Only user-created performance entries will be buffered globally. This
  behavior should be compliant with
  https://w3c.github.io/timing-entrytypes-registry/#registry.

With the new ability to fetch user-created performance entries
synchronously, the issues raised in
nodejs/diagnostics#464 (comment)
could also be fixed.

PR-URL: #39297
Reviewed-By: James M Snell <jasnell@gmail.com>
BethGriggs pushed a commit that referenced this pull request Jul 29, 2021
All API introduced in this PR are compliant with web
[performance-timeline](https://w3c.github.io/performance-timeline)
spec. "performance-timeline" is listed as supported web spec in the doc
https://nodejs.org/docs/latest/api/perf_hooks.html#perf_hooks_performance_measurement_apis.

Changes summary:
1. Add new supported wpt test subsets: user-timing and
  performance-timeline.
2. Add support for `Performance.getEntries`,
  `Performance.getEntriesByName` and `Performance.getEntriesByType`
  to synchronously fetch buffered performance entries. This means
  the user should invoke `Performance.clearMarks` and
  `Performance.clearMeasures` to clear buffered entries to prevent from
  those entries been kept alive forever.
3. Add support (again after #37136)
  for `buffered` flags for `PerformanceObserver`.
3. Fixes `PerformanceMark` and `PerformanceMeasure` wpt compliance
  issues.
4. Only user-created performance entries will be buffered globally. This
  behavior should be compliant with
  https://w3c.github.io/timing-entrytypes-registry/#registry.

With the new ability to fetch user-created performance entries
synchronously, the issues raised in
nodejs/diagnostics#464 (comment)
could also be fixed.

PR-URL: #39297
Reviewed-By: James M Snell <jasnell@gmail.com>
BethGriggs added a commit that referenced this pull request Jul 29, 2021
This is a security release.

Notable Changes:

- CVE-2021-22930: Use after free on close http2 on stream canceling
  (High) [#39423](#39423)
- (SEMVER-MINOR) deps: update V8 to 9.2.230.21 (Michaël Zasso)
  [#39470](#39470)
- inspector: mark as stable (Gireesh Punathil)
  [#37748](#37748)
- (SEMVER-MINOR) perf_hooks: web performance timeline compliance
  (legendecas) [#39297](#39297)
- punycode: add pending deprecation (Antoine du Hamel)
  [#38444](#38444)
- (SEMVER-MINOR) repl: enable --experimental-repl-await /w opt-out
  (hemanth.hm) [#34733](#34733)

PR-URL: #39534
BethGriggs added a commit that referenced this pull request Jul 29, 2021
This is a security release.

Notable Changes:

- CVE-2021-22930: Use after free on close http2 on stream canceling
  (High) [#39423](#39423)
- (SEMVER-MINOR) deps: update V8 to 9.2.230.21 (Michaël Zasso)
  [#39470](#39470)
- inspector: mark as stable (Gireesh Punathil)
  [#37748](#37748)
- (SEMVER-MINOR) perf_hooks: web performance timeline compliance
  (legendecas) [#39297](#39297)
- punycode: add pending deprecation (Antoine du Hamel)
  [#38444](#38444)
- (SEMVER-MINOR) repl: enable --experimental-repl-await /w opt-out
  (hemanth.hm) [#34733](#34733)

PR-URL: #39534
@BethGriggs
Copy link
Member

This seemed to cause a test failure with radium that was surfaced when running CITGM on v16.6.0 - see #39534 (comment).

@legendecas
Copy link
Member Author

This seemed to cause a test failure with radium that was surfaced when running CITGM on v16.6.0 - see #39534 (comment).

#39532 is supposed to fix the issue.

ronag pushed a commit to nxtedition/node that referenced this pull request Aug 1, 2021
All API introduced in this PR are compliant with web
[performance-timeline](https://w3c.github.io/performance-timeline)
spec. "performance-timeline" is listed as supported web spec in the doc
https://nodejs.org/docs/latest/api/perf_hooks.html#perf_hooks_performance_measurement_apis.

Changes summary:
1. Add new supported wpt test subsets: user-timing and
  performance-timeline.
2. Add support for `Performance.getEntries`,
  `Performance.getEntriesByName` and `Performance.getEntriesByType`
  to synchronously fetch buffered performance entries. This means
  the user should invoke `Performance.clearMarks` and
  `Performance.clearMeasures` to clear buffered entries to prevent from
  those entries been kept alive forever.
3. Add support (again after nodejs#37136)
  for `buffered` flags for `PerformanceObserver`.
3. Fixes `PerformanceMark` and `PerformanceMeasure` wpt compliance
  issues.
4. Only user-created performance entries will be buffered globally. This
  behavior should be compliant with
  https://w3c.github.io/timing-entrytypes-registry/#registry.

With the new ability to fetch user-created performance entries
synchronously, the issues raised in
nodejs/diagnostics#464 (comment)
could also be fixed.

PR-URL: nodejs#39297
Reviewed-By: James M Snell <jasnell@gmail.com>
targos pushed a commit that referenced this pull request Aug 2, 2021
The option buffered is not about queueing the PerformanceEntrys with
an event loop task or not. The option buffered in the spec is about
filling the observer with the global PerformanceEntry buffer. The
current (and the spec) behavior is different with Node.js
version <= v16.0.0.

PR-URL: #39514
Refs: https://w3c.github.io/performance-timeline/#observe-method
Refs: https://nodejs.org/dist/latest-v14.x/docs/api/perf_hooks.html#perf_hooks_performanceobserver_observe_options
Refs: #39297
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
danielleadams pushed a commit that referenced this pull request Aug 16, 2021
All API introduced in this PR are compliant with web
[performance-timeline](https://w3c.github.io/performance-timeline)
spec. "performance-timeline" is listed as supported web spec in the doc
https://nodejs.org/docs/latest/api/perf_hooks.html#perf_hooks_performance_measurement_apis.

Changes summary:
1. Add new supported wpt test subsets: user-timing and
  performance-timeline.
2. Add support for `Performance.getEntries`,
  `Performance.getEntriesByName` and `Performance.getEntriesByType`
  to synchronously fetch buffered performance entries. This means
  the user should invoke `Performance.clearMarks` and
  `Performance.clearMeasures` to clear buffered entries to prevent from
  those entries been kept alive forever.
3. Add support (again after #37136)
  for `buffered` flags for `PerformanceObserver`.
3. Fixes `PerformanceMark` and `PerformanceMeasure` wpt compliance
  issues.
4. Only user-created performance entries will be buffered globally. This
  behavior should be compliant with
  https://w3c.github.io/timing-entrytypes-registry/#registry.

With the new ability to fetch user-created performance entries
synchronously, the issues raised in
nodejs/diagnostics#464 (comment)
could also be fixed.

PR-URL: #39297
Reviewed-By: James M Snell <jasnell@gmail.com>
danielleadams pushed a commit that referenced this pull request Aug 16, 2021
The option buffered is not about queueing the PerformanceEntrys with
an event loop task or not. The option buffered in the spec is about
filling the observer with the global PerformanceEntry buffer. The
current (and the spec) behavior is different with Node.js
version <= v16.0.0.

PR-URL: #39514
Refs: https://w3c.github.io/performance-timeline/#observe-method
Refs: https://nodejs.org/dist/latest-v14.x/docs/api/perf_hooks.html#perf_hooks_performanceobserver_observe_options
Refs: #39297
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. perf_hooks Issues and PRs related to the implementation of the Performance Timing API. semver-minor PRs that contain new features and should be released in the next minor version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants