-
Notifications
You must be signed in to change notification settings - Fork 6
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
[WIP] Restructure module for thread safety using context aware initialization #15
Conversation
…lization Previously, this module would cause an error if loaded in two separate contexts, e.g. the main thread and a worker thread. We can use the NODE_MODULE_INIT macro to establish our module as being context aware. Next, we need to remove our reliance upon static shared data, especially any v8 objects. Accessing a v8 object across isolates causes a cryptic runtime error. In accordance with the v8 native extensions docs, we create a separate class to store mutable data per thread, and shift all shared v8 objects into this structure (ProfilerData).
Is there a reproduce? |
const {Worker, isMainThread, parentPort} = require('worker_threads');
const profiler = require('v8-profiler-node8');
const workerCode = `
const profiler = require('v8-profiler-node8');
const {parentPort} = require('worker_threads');
profiler.startProfiling('worker');
function work() {
for (let i = 0; i < 1e7; i++) {}
}
work();
const profile = profiler.stopProfiling('worker');
parentPort.postMessage(JSON.stringify(profile));
`;
profiler.startProfiling('main');
const worker = new Worker(workerCode, {eval: true});
worker.on('message', (m) => {
const profile = profiler.stopProfiling('main');
console.log('main thread profile', profile);
console.log('worker thread profile', m);
});
worker.on('error', (e) => {
throw e;
}); Using Node v12.18.2, results in this error:
With this PR applied, it successfully generates traces on both threads. |
Thanks, I'll take a look and get back to you :) |
Heads up in my testing it looks like this PR can cause segfaults right now, still some work to do before it's stable. Will look into that tomorrow. |
This is because I think |
Adding in a segfault handler made it clear that the existing segfault remains in the currently untouched heap profiler, and disabling it fixes the segfault. I'm going to have a go at making the same sort of changes to the heap profiler.
|
Feels much cleaner to have explicitly typed arguments.
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.
Plan to release 7.x@next tag, but need to fix ci on windows/add test for worker thread first
using v8::Isolate; | ||
|
||
ProfilerData::ProfilerData(v8::Local<Context> newContext, Isolate* isolate) { | ||
context = newContext; |
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.
context
seems not used here?
This feature landed in 7330e00 with the npm i v8-profiler-node8@next --save |
Previously, this module would cause an error if loaded in two separate
contexts, e.g. the main thread and a worker thread.
We can use the NODE_MODULE_INIT macro to establish our module as being
context aware.
Next, we need to remove our reliance upon static shared data, especially
any v8 objects. Accessing a v8 object across isolates causes a cryptic
runtime error.
In accordance with the Node native extensions docs, we create a separate
class to store mutable data per thread, and shift all shared v8 objects
into this structure (ProfilerData).
TODO:
ifdef
s are still correctI'm not a C++ dev by trade so apologies if I've made any super obvious mistakes. I'm happy to make changes based on feedback if I've taken a wrong turn somewhere.