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
feat: add process.takeHeapSnapshot() / webContents.takeHeapSnapshot() #14456
Conversation
7d30e10
to
ab6a9fe
Compare
58ec892
to
a238aa2
Compare
@MarshallOfSound FYI |
e662710
to
139eb32
Compare
@miniak The bug to which you refer was fixed in electron/typescript-definitions#107 if you are up to date with latest master and have the latest version of |
0a9532f
to
a2fa4cf
Compare
a2fa4cf
to
852c51e
Compare
e4ca655
to
174dd5a
Compare
|
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.
👍
docs/api/process.md
Outdated
@@ -171,6 +171,10 @@ Returns `Object`: | |||
Returns an object giving memory usage statistics about the entire system. Note | |||
that all statistics are reported in Kilobytes. | |||
|
|||
### `process.takeHeapSnapshot()` | |||
|
|||
Returns `String` - The file path if the heap snapshot has been created successfully. |
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 method has to be synchronous, right?
What is returned if there is an error?
If a method throws an exception, it has to be documented.
atom/common/api/atom_bindings.cc
Outdated
} | ||
|
||
if (!file.IsValid()) { | ||
args->ThrowError("takeHeapSnapshot failed - cannot create file"); |
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.
Can you please move all error messages to constants in an anonymous namespace on the top of the file?
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.
why? we're not doing that it other places
174dd5a
to
f717965
Compare
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 implementation looks good wrt to file handling for a sandboxed process, Is there any reason this api has to be a synchronous version ? Making it async would allow us to avoid sync IPC as well avoid file operations on the UI task runner, which would be a good thing.
c536b5f
to
324eb17
Compare
@deepak1556, @alexeykuzmin I've refactored the implementation significantly, the file handle is now pushed from the main process when |
324eb17
to
ed93b64
Compare
@deepak1556 I am not sure if it is possible to offload this to a background thread. I've tried taking the snapshot on the main thread and then saving it on IO thread, it didn't work. |
ed93b64
to
42baf25
Compare
spec/api-process-spec.js
Outdated
const filePath = path.join(remote.app.getPath('userData'), 'test.heapsnapshot') | ||
const success = process.takeHeapSnapshot(filePath) | ||
expect(success).to.be.true() | ||
fs.unlink(filePath, () => done()) |
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.
Please call expect
after the unlink.
And it would be better to call it sync version fs.unlinkSync()
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.
refactored a bit differently
spec/api-web-contents-spec.js
Outdated
const filePath = path.join(remote.app.getPath('userData'), 'test.heapsnapshot') | ||
|
||
afterEach(done => { | ||
fs.unlink(filePath, () => done()) |
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.
Please call in a beforeEach
hook.
afterEach
won't be called for failed tests =/
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.
refactored a bit differently
42baf25
to
b0d42b8
Compare
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.
Please replace "it('returns false on failure'" with "it('throws an exception on failure'" in the tests.
👍
d4305d6
to
83b7f23
Compare
@MarshallOfSound I've changed the implementation a bit and I don't need to return a string anymore. The filePath is now passed to the method. I just need to return whether it succeeded or failed. Boolean also has issues so I just throw an exception when it fails. |
docs/api/process.md
Outdated
* `filePath` String - Path to the output file. | ||
|
||
Takes a V8 heap snapshot and saves it to `filePath`. | ||
Throws an exception in case of failure. |
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.
We shouldn't make a worse API because the docs generator is breaking the PR. This should be returning a success state not throwing an error. Working around a docs generator bug by changing the API is a bad idea.
Requesting changes and as mentioned I'll look into the docs generator issue
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.
@MarshallOfSound I get your point, but is it actually worse? An exception can give you potentially much more information why something failed than just a false return value.
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.
waiting for https://github.com/electron/electron-typescript-definitions/releases/tag/v2.0.1 to be published to NPM
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.
@miniak It was published when that github release went out an hour or so ago --> https://www.npmjs.com/package/electron-typescript-definitions/v/2.0.1
It's an automated pipeline
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 npmjs webpage took a while to reflect the update.
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.
Working around a docs generator bug by changing the API is a bad idea.
I agree that generally it is a bad idea.
This should be returning a success state not throwing an error.
But in this case I would argue.
In most cases an exception will be thrown because of a user "error", like an invalid file path or lack of permission to write to a specified location.
Returning just a boolean "state" value simply doesn't provide any useful feedback to a user.
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.
@alexeykuzmin Sure if we have things like EACCESS
, EPERM
and other such standard file errors then throwing them to be consistent with things like node fs makes sense. From what I saw this was just throwing a generic "something went wrong" error which is just as helpful as returning false but harder / more annoying to catch.
a3a1e6b
to
a02e4ac
Compare
@MarshallOfSound electron-typescript-definitions bumped to 2.0.1, boolean return value restored. |
@MarshallOfSound I am going to push a small fix
|
a02e4ac
to
69294ae
Compare
Release Notes Persisted
|
Description of Change
There is a node module for getting V8 heap snapshots https://github.com/bnoordhuis/node-heapdump, but it cannot be used in sandboxed renderers due to node not being available. Currently the only way to do this programmatically is to expose this API in Electron.
This PR is adding these new methods:
process.takeHeapSnapshot()
- allows the main process and non-sandboxed renderers to take its own V8 heap snapshotwebContents.takeHeapSnapshot()
- allows the main process to ask any renderer (including sandboxed ones) to create its V8 heap snapshotChecklist
npm test
passesRelease Notes
Notes: Added
process.getHeapSnapshot()
/webContents.takeHeapSnapshot()
for taking V8 heap snapshots.