Support worker env.[aka: context aware]#1981
Support worker env.[aka: context aware]#1981niyan-ly wants to merge 10 commits intoAutomattic:masterfrom
Conversation
There was a problem hiding this comment.
Thanks for starting on this! I don't think this is quite the right approach however. All static-duration data (such as font_face_list in Canvas.cc) has to be moved to instance data for the module, or has to not be JS objects and has to be thread-safe, which std::vector is not when there are multiple readers+writers. I think that is also the preferred approach for dealing with the Persistent handles, rather than storing them on a global object and retrieving them by calling into JS. https://nodejs.org/api/addons.html#context-aware-addons has the clearest info on this.
is relatively safer than type casting many void* pointer.
Which casts are you looking at? The "receiver" (in V8 terms) should be checked in all cases. For example:
> x = canvas.createCanvas(50,50)
[Canvas 50x50]
> y = x.getContext('2d')
CanvasRenderingContext2D { canvas: [Canvas 50x50] }
> z = y.createLinearGradient()
CanvasGradient {}
> z.addColorStop.call({}, 4, "abc")
Uncaught TypeError: Illegal invocation
|
Yes, you are right. I've just focused on existing issues, but didn't take a complete check on the package level. I will continue this work to see if we can make it. |
|
I've movd all persistent handle and non v8 data into a new context level store |
|
There are some extra works to do. Font registration are not at thread level, so move |
Fixed this issue by apply mutex lock, |
|
Hello! Not sure how useful this will be... But, for my use case of parallelization in some visual-regression tests using Resemble & Codeceptjs, I am still receiving the same error |
|
@nateGarcia Hi, did you still get this error on this PR? If so, could you give me a minimum replicable test case. |
|
Hello, first of all, thanks for this pull request! it will help my project. // index.js
import {Worker} from 'worker_threads';
function createWorker() {
new Worker(`./worker.js`);
}
createWorker();
createWorker();// worker.js
import {Canvas} from "canvas";
console.log('thread', Canvas.toString());By loading worker multiple times, it crash by showing It happens too when loading canvas from main thread, and worker thread: // index.js
import {Worker} from 'worker_threads';
import {Canvas} from "canvas";
console.log('main', Canvas.toString());
new Worker(`./worker.js`);// worker.js
import {Canvas} from "canvas";
console.log('thread', Canvas.toString());Windows x64 21H2 22000.795 |
64ed3d8 to
ff0f2ab
Compare
This
PRremoves all function template, instead, keep trace of js constructor for each individual v8::Context. To achieve this, it holds all necessary js constructor under global property__node_canvasin each context. It may not that graceful, but is relatively safer than type casting many void* pointer.