1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-27 01:29:14 -05:00
Commit graph

38 commits

Author SHA1 Message Date
Nathan Whitaker
dd8cbf5e29
fix(node): fix worker_threads issues blocking Angular support (#26024)
Fixes #22995. Fixes #23000.

There were a handful of bugs here causing the hang (each with a
corresponding minimized test):

- We were canceling recv futures when `receiveMessageOnPort` was called,
but this caused the "receive loop" in the message port to exit. This was
due to the fact that `CancelHandle`s are never reset (i.e., once you
`cancel` a `CancelHandle`, it remains cancelled). That meant that after
`receieveMessageOnPort` was called, the subsequent calls to
`op_message_port_recv_message` would throw `Interrupted` exceptions, and
we would exit the loop.

The cancellation, however, isn't actually necessary.
`op_message_port_recv_message` only borrows the underlying port for long
enough to poll the receiver, so the borrow there could never overlap
with `op_message_port_recv_message_sync`.

- Calling `MessagePort.unref()` caused the "receive loop" in the message
port to exit. This was because we were setting
`messageEventListenerCount` to 0 on unref. Not only does that break the
counter when multiple `MessagePort`s are present in the same thread, but
we also exited the "receive loop" whenever the listener count was 0. I
assume this was to prevent the recv promise from keeping the event loop
open.

Instead of this, I chose to just unref the recv promise as needed to
control the event loop.

- The last bug causing the hang (which was a doozy to debug) ended up
being an unfortunate interaction between how we implement our
messageport "receive loop" and a pattern found in `npm:piscina` (which
angular uses). The gist of it is that piscina uses an atomic wait loop
along with `receiveMessageOnPort` in its worker threads, and as the
worker is getting started, the following incredibly convoluted series of
events occurs:
   1. Parent sends a MessagePort `p` to worker
   2. Parent sends a message `m` to the port `p`
3. Parent notifies the worker with `Atomics.notify` that a new message
is available
   4. Worker receives message, adds "message" listener to port `p`
   5. Adding the listener triggers `MessagePort.start()` on `p`
6. Receive loop in MessagePort.start receives the message `m`, but then
hits an await point and yields (before dispatching the "message" event)
7. Worker continues execution, starts the atomic wait loop, and
immediately receives the existing notification from the parent that a
message is available
8. Worker attempts to receive the new message `m` with
`receiveMessageOnPort`, but this returns `undefined` because the receive
loop already took the message in 6
9. Atomic wait loop continues to next iteration, waiting for the next
message with `Atomic.wait`
10. `Atomic.wait` blocks the worker thread, which prevents the receive
loop from continuing and dispatching the "message" event for the
received message
11. The parent waits for the worker to respond to the first message, and
waits
12. The thread can't make any more progress, and the whole process hangs

The fix I've chosen here (which I don't particularly love, but it works)
is to just delay the `MessagePort.start` call until the end of the event
loop turn, so that the atomic wait loop receives the message first. This
prevents the hang.

---

Those were the main issues causing the hang. There ended up being a few
other small bugs as well, namely `exit` being emitted multiple times,
and not patching up the message port when it's received by
`receiveMessageOnPort`.
2024-10-04 09:26:32 -07:00
Kenta Moriuchi
f0a3d20642
fix(runtime): use more null proto objects again (#25040)
proceed with #23921

This PR is a preparation for
https://github.com/denoland/deno_lint/pull/1307

---------

Signed-off-by: Kenta Moriuchi <moriken@kimamass.com>
Co-authored-by: Luca Casonato <hello@lcas.dev>
2024-09-06 12:52:59 +02:00
Nathan Whitaker
511d13abaf
fix(ext/node): emit online event after worker thread is initialized (#25243)
Fixes #23281. Part of #20613.

We were emitting the `online` event in the constructor, so the caller
could never receive it (since there was no time for them to add a
listener). Instead, emit the event where it's intended – after the
worker is initialized.

---

After this parcel no longer freezes, but still will fail due to other
bugs (which will be fixed in other PRs)
2024-08-28 03:05:32 +00:00
David Sherret
a7c002ae63
chore: enable no-console dlint rule (#25113) 2024-08-20 15:14:37 -04:00
Marvin Hagemeister
0cf7f268a7
fix(node/worker_threads): support port.once() (#24725)
Support `MessagePort.once` in Node mode and enable relevant
`worker_threads` test. Noticed that another Node test was passing as
well, so I enabled that too.
2024-07-25 23:06:19 +02:00
Yoshiya Hinosawa
76b8ecbb6d
fix(ext/node): do not expose self global in node (#24637)
closes #23727
2024-07-19 12:37:08 +09:00
Marvin Hagemeister
d7709daaa0
fix(node): patch MessagePort in worker_thread message (#23871)
Our `MessagePort` to Node's `MessagePort` conversion logic was missing
the case where a `MessagePort` is sent _inside_ the message. This broke
`tinypool` which is used by `vitest` as it relies on some node specific
methods on `MessagePort`.

Fixes https://github.com/denoland/deno/issues/23854 , Fixes
https://github.com/denoland/deno/pull/23871
2024-05-20 15:01:40 +02:00
Marvin Hagemeister
e02d0faedc
fix(node): wrong worker_threads.terminate() return value (#23803)
<!--
Before submitting a PR, please read
https://docs.deno.com/runtime/manual/references/contributing

1. Give the PR a descriptive title.

  Examples of good title:
    - fix(std/http): Fix race condition in server
    - docs(console): Update docstrings
    - feat(doc): Handle nested reexports

  Examples of bad title:
    - fix #7123
    - update docs
    - fix bugs

2. Ensure there is a related issue and it is referenced in the PR text.
3. Ensure there are tests that cover the changes.
4. Ensure `cargo test` passes.
5. Ensure `./tools/format.js` passes without changing files.
6. Ensure `./tools/lint.js` passes.
7. Open as a draft PR if your work is still in progress. The CI won't
run
   all steps, but you can add '[ci]' to a commit message to force it to.
8. If you would like to run the benchmarks on the CI, add the 'ci-bench'
label.
-->

Fixes https://github.com/denoland/deno/issues/23801

---------

Signed-off-by: Marvin Hagemeister <marvinhagemeister50@gmail.com>
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
2024-05-15 17:08:25 +02:00
Satya Rohith
0156f82e73
fix(ext/node): support multiple message listeners on MessagePort (#23600)
Closes https://github.com/denoland/deno/issues/23561
2024-04-30 16:59:39 +05:30
Satya Rohith
455cf1743f
fix(ext/node): add support for MessagePort.removeListener/off (#23598)
Closes https://github.com/denoland/deno/issues/23564
2024-04-29 08:53:54 +00:00
Bartek Iwańczuk
b424959d3e
fix(ext/node): worker_threads copies env object (#23536)
Most common argument to `env` option for `worker_threads.Worker` will be
`process.env`.

In Deno `process.env` is a `Proxy` which can't be cloned using
structured clone algorithm.

So to be safe, I'm creating a copy of actual object before it's sent to
the worker thread.

Ref #23522
2024-04-24 16:17:28 +00:00
Divy Srivastava
e0554ac4a2
fix(ext/node): Support env option in worker_thread (#23462)
Fixes https://github.com/denoland/deno/issues/23455
2024-04-20 09:18:10 +05:30
Bartek Iwańczuk
0b8d7d1d4b
fix(ext/node): panic on 'worker_threads.receiveMessageOnPort' (#23386)
Closes https://github.com/denoland/deno/issues/23362

Previously we were panicking if there was a pending read on a
port and `receiveMessageOnPort` was called. This is now fixed
by cancelling the pending read, trying to read a message and
resuming reading in a loop.
2024-04-16 01:06:39 +02:00
Satya Rohith
5a3ee6d9af
fix(ext/node): implement MessagePort.unref() (#23278)
Closes https://github.com/denoland/deno/issues/23252
Closes https://github.com/denoland/deno/issues/23264
2024-04-09 20:15:55 +02:00
Satya Rohith
aa08155fd1
refactor(ext/node): remove worker_threads dependency on ext:runtime (#23206) 2024-04-03 21:39:53 +02:00
Satya Rohith
86bc7a4381
fix(ext/node): patch MessagePort if provided as workerData (#23198)
MessagePort if directly assigned to workerData property instead of
embedding it in an object then it is not patched to a NodeMessagePort.
This commit fixes the bug.
2024-04-03 11:12:16 +00:00
Satya Rohith
4d66ec91c1
fix(ext/node): MessagePort works (#22999)
Closes https://github.com/denoland/deno/issues/22951
Closes https://github.com/denoland/deno/issues/23001

Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
2024-04-02 17:06:09 +05:30
mash-graz
0d43a63636
fix(ext/node): worker_threads ESM handling (#22841)
Fixes #22840
Fixes #22964
2024-03-20 09:12:22 +05:30
Satya Rohith
bbc211906d
fix(ext/node): make worker ids sequential (#22884) 2024-03-13 19:52:53 +00:00
Satya Rohith
0fd8f549e2
fix(ext/node): allow automatic worker_thread termination (#22647)
Co-authored-by: Matt Mastracci <matthew@mastracci.com>
2024-03-13 17:22:25 +00:00
Bartek Iwańczuk
d69aab62b0
fix(ext/node): make worker setup synchronous (#22815)
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 https://github.com/denoland/deno/issues/22783
Closes https://github.com/denoland/deno/issues/22672

---------

Co-authored-by: Satya Rohith <me@satyarohith.com>
2024-03-11 23:18:03 +01:00
Bartek Iwańczuk
bb6e4c7414
fix(ext/node): worker_threads.parentPort is updated on startup (#20794)
This addresses
https://github.com/denoland/deno/issues/20613#issuecomment-1739962483.
2024-03-11 08:21:06 +05:30
mash-graz
80dbcd3ddf
fix(ext/node) implement receiveMessageOnPort for node:worker_threads (#22766)
Implementation of `receiveMessageOnPort` for `node:worker_threads`

Fixes: #22702
2024-03-11 00:23:06 +01:00
Bartek Iwańczuk
93b9d114a4
refactor(ext/node): worker_threads.isMainThread setup (#22785)
This commit changes how we figure out if we're running on main
thread in `node:worker_threads` module. Instead of relying on quirky
"magic variable" for a name to check if we're on main thread, we are
now explicitly passing this information during bootstrapping of the
runtime. As a side effect, `WorkerOptions.name` is more useful
and matches what Node.js does more closely (though not fully).

Towards https://github.com/denoland/deno/issues/22783
2024-03-08 17:31:11 +01:00
Satya Rohith
d5b01e4158
refactor(ext/node): use worker ops directly in worker_threads (#22794) 2024-03-08 14:45:55 +00:00
Matt Mastracci
3745556ccd
feat(ext/node): ref/unref on workers (#22778)
Implements ref/unref on worker to fix part of #22629
2024-03-07 18:51:19 -07:00
Bartek Iwańczuk
345423cf76
refactor: Use virtul ops module (#22175)
Follow up to #22157.

This leaves us with 4 usages of `ensureFastOps()` in `deno` itself.
There's also about 150 usages of `Deno.core.ops.<op_name>` left as well.
2024-01-29 22:02:26 +01:00
Kenta Moriuchi
515a34b4de
refactor: use core.ensureFastOps() (#21888) 2024-01-10 15:37:25 -07:00
David Sherret
7e72f3af61
chore: update copyright to 2024 (#21753) 2024-01-01 19:58:21 +00:00
Bartek Iwańczuk
01f0d03ae8
refactor: rename built-in node modules from ext:deno_node/ to node: (#19680)
Closes https://github.com/denoland/deno/issues/19510
2023-07-02 20:19:30 +02:00
Kenta Moriuchi
e16b74d792
chore(ext/node): disable prefer-primordials on a per-file basis (#19553) 2023-06-27 15:18:22 +09:00
Ryan Clements
b37b286f7f
fix(ext/node): remove path.toFileUrl (#19536) 2023-06-26 13:08:17 +09:00
Vedant Pandey
0c50c39c35
fix(node): Worker constructor doesn't check type: module of package.json (#19480) 2023-06-15 17:00:30 +02:00
Yoshiya Hinosawa
26f42a248f
fix(ext/node): add basic node:worker_threads support (#19192)
This PR restores `node:worker_threads` implementation and test cases
from
[`std@0.175.0/node`](https://github.com/denoland/deno_std/blob/0.175.0/node/worker_threads.ts).

---------

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
2023-05-23 20:56:29 +02:00
Marvin Hagemeister
f1d0f745d3
fix(node): expose channels in worker_threads (#19086)
This PR ensures that node's `worker_threads` module exports
`MessageChannel`, `MessagePort` and the `BroadcastChannel` API. Fixing
these won't make `esbuild` work, but brings us one step closer 🎉

Fixes #19028 .
2023-05-11 12:32:19 +02:00
Bartek Iwańczuk
72fe9bb470
refactor: rename InternalModuleLoader to ExtModuleLoader, use ext: scheme for snapshotted modules (#18041)
This commit renames "deno_core::InternalModuleLoader" to
"ExtModuleLoader" and changes the specifiers used by the 
modules loaded from this loader to "ext:".

"internal:" scheme was really ambiguous and it's more characters than
"ext:", which should result in slightly smaller snapshot size.

Closes https://github.com/denoland/deno/issues/18020
2023-03-08 12:44:54 +01:00
Bartek Iwańczuk
b40086fd7d
refactor(core): include_js_files! 'dir' option doesn't change specifiers (#18019)
This commit changes "include_js_files!" macro from "deno_core"
in a way that "dir" option doesn't cause specifiers to be rewritten 
to include it.

Example:
```
include_js_files! {
  dir "js",
  "hello.js",
}
```

The above definition required embedders to use:
`import ... from "internal:<ext_name>/js/hello.js"`. 
But with this change, the "js" directory in which the files are stored
is an implementation detail, which for embedders results in: 
`import ... from "internal:<ext_name>/hello.js"`.

The directory the files are stored in, is an implementation detail and 
in some cases might result in a significant size difference for the 
snapshot. As an example, in "deno_node" extension, we store the 
source code in "polyfills" directory; which resulted in each specifier 
to look like "internal:deno_node/polyfills/<module_name>", but with 
this change it's "internal:deno_node/<module_name>". 

Given that "deno_node" has over 100 files, many of them having 
several import specifiers to the same extension, this change removes
10 characters from each import specifier.
2023-03-05 02:31:38 +00:00
Bartek Iwańczuk
d47147fb6a
feat(ext/node): embed std/node into the snapshot (#17724)
This commit moves "deno_std/node" in "ext/node" crate. The code is
transpiled and snapshotted during the build process.

During the first pass a minimal amount of work was done to create the
snapshot, a lot of code in "ext/node" depends on presence of "Deno"
global. This code will be gradually fixed in the follow up PRs to migrate
it to import relevant APIs from "internal:" modules.

Currently the code from snapshot is not used in any way, and all
Node/npm compatibility still uses code from 
"https://deno.land/std/node" (or from the location specified by 
"DENO_NODE_COMPAT_URL"). This will also be handled in a follow 
up PRs.

---------

Co-authored-by: crowlkats <crowlkats@toaxl.com>
Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
2023-02-14 17:38:45 +01:00