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
fix(ext/node) worker_threads ESM handling #22841
Conversation
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.
Thanks! Let me know if you need further help on this one.
Probably a test could be added in tests/integration/npm_tests.rs
ext/node/polyfills/worker_threads.ts
Outdated
const cwdFileUrl = toFileUrl(Deno.cwd()); | ||
specifier = | ||
`data:text/javascript,(async function() {const { createRequire } = await import("node:module");const require = createRequire("${cwdFileUrl}");require("${specifier}");})();`; | ||
} else { | ||
specifier = toFileUrl(specifier as string); | ||
} |
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.
Nevertheless, a more general solution for the file type detection...
There is a function, url_to_node_resolution
on NodeResolver
. Probably that should be used everywhere. Also, all files outside a node_modules directory are considered ESM in Deno (there is a in_npm_package
function on NodeResolver
to tell that).
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 url_to_node_resolution
handles only an URL to path resp. string conversion.
But it doesn't provide any file type related differentiation, if I'm not wrong.
Right now the format decision is done by looking at 1.) the file suffix and 2.) op_require_read_closest_package_json
to check, if a typ: module
entry is present somewhere in a package.json
file above the script.
But the code without my patch always seemed to choose the exactly opposite consequence based on these checks! ESM files got wrapped in require(...)
fragments and CJS files became imported by their URL, not the other way around! (<= But please double-check this claim!)
But .mjs
files still seemed to work all the time somehow and simply ignored this defect.
That's why the unit test doesn't report an error.
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 url_to_node_resolution handles only an URL to path resp. string conversion.
But it doesn't provide any file type related differentiation, if I'm not wrong.
It works for file:///
urls.
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.
That's interesting!
Which property of the URL object could be used for a more useful import type specific proceeding?
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.
@dsherret: I think, I finally understood now your url_to_node_resolution
! :)
I'll try to use it as replacement here as well to minimize the code duplication and unexpected behavior.
@mash-graz can you link to some of the package you said don't work without this patch? We can boil down a test case out of them. |
I noticed the issue while working on this But I'll look, if I can extract a working example till tomorrow... It's really crazy -- I can somehow understand, what's wrong with this particular code passage, but I can not grasp, why most examples, and the |
o.k. -- I have prepared a practical demonstration of this issue for you:
you will get this error, if you execute the unpatched but if you utilize this PR everything should work as expected and you will see something like this:
I really can't explain, why the import will not work in this case, but seems to work in many other situations. That's why I couldn't find a more suitable unit test. But the reported |
I just added two additional unit tests. But creating them, I had to notice, that exceptions generated during Worker creations, will not be caught by these tests! :( for example, when I try to create a worker with a non-existing path specifier (here:
But the test will nevertheless pass and report:
|
I finally figured out an indirect check for correct worker script import, which will fail on errors. This should now at least cover all the possible processing paths within the patched sequence, although the CJS test is rather weak. I don't know if it should accept |
This commit fixes race condition in "node:worker_threads" module were the first message did a setup of "threadId", "workerData" and "environmentData". Now this data is passed explicitly during workers creation and is set up before any user code is executed. Closes #22783 Closes #22672 --------- Co-authored-by: Satya Rohith <me@satyarohith.com>
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.
Thank you for the PR @mash-graz, I'm going to mark it as "Request changes" so that we can first fix regressions in #22934 and #22935 to not introduce more moving pieces and potential regressions. We'll land this one as soon as we fix these two problems.
That's perfectly fine! I try to prepare another improved/corrected version in the meanwhile. ;) |
With both of the linked issues now being resolved, would this PR be up for another review? |
Please wait just one or two days more! I'm working on a much more satisfying rewrite, which handles both input options (ULRs or path entries) equally well. That's unfortunately not case with all these earlier variants. Therefore, this temporary |
It's finally ready for review (again)! :) I spend a lot of time into input verification and early exception throwing, because initialization errors on the worker side are usually only reported as File and Data-URL-Objects should be accepted equally than absolute and relative path strings, in compliance to the expectations defined by the Although I did my best to handle also CJS scripts sufficiently by wrapping them in helper scripts,
CJS support isn't utterly irrelevant in this particular case, because the support for ESM in workers in VMs in I hope, the changes are mostly acceptable. And thanks again for all other help! |
@littledivy @satyarohith please review this PR, this might be overlapping with #22977 you're working on. |
Now it's finally passing the CI pipeline, but one important test (execution of the CJS wrapped code) is disabled on windows! :( That's a really inconvenient situation, because fixing this necessary differences in handling of ESM vs. CJS scripts was the main goal of this PR. How should we go on?
It's very hard for me to debug the cause of these windows specific bugs. I do not have a setup to reproduce them locally and always waiting for the CI results is an enormous waste of time... Please give me just a little bit of honest feedback, what would look as the most appreciable solution to you? |
The windows bug seems to be outside of my code changes in
I'll open another issue and Fix for this problem... |
e8f7257
to
f50c52f
Compare
Just tested this PR on Nuxt and Sveltekit. It solves the problem for both, let's try to get this merged.
I like the port to Rust. Rewrites like these are welcome since they reduce the startup snapshot size. I just noticed you enabled the tests on Windows. Does it work now? |
Yes -- it should now work on all platforms! I hope, it's more or less o.k. by now, but somebody should definitely take careful look on the code, because this windows related path issues nearly drove my crazy. |
@bartlomieju could you please take another look at this code. It should now work on all platforms, but im sure, many thinks could be done better. |
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.
LGTM
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.
LGTM. Nice to have more operations done on the rust side.
thanks for the approvals! :) |
Fixes #22840
Fixes #22964
I still have to look for better test example, because for the very simple
parallel/test-worker-esmodule.js
and its*.mjs
worker file it doesn't make difference if this patch gets applied, but my projects, which use.js
files in ordinary packages, do not work anymore without this modification.I'll leave it as draft in the meanwhile...