Skip to content

Do not drain worker tasks on main thread - #47452

Open
dinfuehr wants to merge 3 commits into
nodejs:mainfrom
dinfuehr:di/do-not-drain-worker-tasks
Open

Do not drain worker tasks on main thread#47452
dinfuehr wants to merge 3 commits into
nodejs:mainfrom
dinfuehr:di/do-not-drain-worker-tasks

Conversation

@dinfuehr

@dinfuehrdinfuehr commented Apr 6, 2023

Copy link
Copy Markdown

Hi!

This PR stops draining worker tasks on the main thread. I believe it's not necessary since V8 will join its own worker tasks as part of v8::Isolate::Dispose. It may also cause deadlocks now that those worker tasks may ask the main thread to perform a GC, see the discussion in this V8 issue here. This should help enable concurrent sparkplug again, which will get/is disabled with this PR.

Do you know why Node is draining worker tasks here? Am I seeing right that NodePlatform::DrainTasks is also invoked from the event loop here? If so, this might be a problem for performance as we block the main thread until those worker tasks are finished when the event loop is empty.

I have to admit that I didn't run tests yet for that PR and it may require V8 patches as well (see the V8 issue linked above) but I opened the PR already to discuss this.

@nodejs-github-botnodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. labels Apr 6, 2023
@targos

Copy link
Copy Markdown
Member

@dinfuehr

Copy link
Copy Markdown
Author

Yes, they are necessary for this.

@joyeecheung

joyeecheung commented Apr 8, 2023

Copy link
Copy Markdown
Member

I think @addaleax would be the best person to answer the questions since she wrote some of the initial patches of the migration to v8 platform, but my 2 cents:

Am I seeing right that NodePlatform::DrainTasks is also invoked from the event loop here?

Yes.

Do you know why Node is draining worker tasks here?

This seems to date back to the initial patches of V8 platform integration, but the same question was asked in https://github.com/v8/node/pull/69/files#r187129604 too. From some local testing it seems if we don't drain the worker tasks here (specifically, in the event loop), some foreground task (e.g. a wasm async compile task, which probably comes from the cjs-module-lexer) could get posted after the event loop already finishes, and the general processing order can be messed up - which is why there are a lot of exit code 13 failures in the test here, that means we have some leftover microtasks not yet cleared from the queue during shutdown. We run the microtasks after running foreground tasks here

InternalCallbackScope cb_scope(env, Object::New(isolate_), { 0, 0 },
(in the InternalCallbackScope destructor) when the Node.js environment is still around e.g. when we are still running the event loop. (Personally I am a bit puzzled why we are using InternalCallbackScope for this because its destructor does..a lot of things, probably way more than what PerIsolatePlatformData::RunForegroundTask needs).

@aduh95

Copy link
Copy Markdown
Contributor

It looks like there are linter and test failures, could you please reabase and address those?

@aduh95aduh95 added the stalled Issues and PRs that are stalled. label May 12, 2024
@github-actions

Copy link
Copy Markdown
Contributor

This issue/PR was marked as stalled, it will be automatically closed in 30 days. If it should remain open, please leave a comment explaining why it should remain open.

@github-actions

Copy link
Copy Markdown
Contributor

Closing this because it has stalled. Feel free to reopen if this issue/PR is still relevant, or to ping the collaborator who labelled it stalled if you have any questions.

@targostargos reopened this Sep 12, 2024
@targostargos removed the stalled Issues and PRs that are stalled. label Sep 12, 2024
@targos

targos commented Sep 12, 2024

Copy link
Copy Markdown
Member

I checked out the PR, rebased it and fixed the linter issues but for some reason I'm unable to push it back:

$ git push git@github.com:dinfuehr/node di/do-not-drain-worker-tasks -f
ERROR: Permission to dinfuehr/node.git denied to targos.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.

In any case, here's a copy on my fork: https://github.com/targos/node/tree/do-not-drain-worker-tasks

@aduh95
aduh95force-pushed the di/do-not-drain-worker-tasks branch from 14b1a3e to 1bc4970CompareSeptember 13, 2024 08:46
Comment threadsrc/node_platform.cc Outdated
@targos

Copy link
Copy Markdown
Member

@aduh95 Thanks! Now I'm curious: how did you do it?

@codecov

codecovBot commented Sep 13, 2024

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.06%. Comparing base (e21984b) to head (ab23463).
⚠️ Report is 5240 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #47452 +/- ##
==========================================
+ Coverage 88.04% 88.06% +0.01% 
==========================================
Files 651 652 +1 Lines 183409 183543 +134 Branches 35828 35864 +36 ==========================================
+ Hits 161487 161635 +148 + Misses 15174 15160 -14 
Partials 6748 6748 
Files with missing linesCoverage Δ
src/node_platform.cc87.80% <100.00%> (-0.03%)⬇️

... and 55 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

nodejs-github-bot pushed a commit that referenced this pull request May 4, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
nodejs-github-bot pushed a commit that referenced this pull request May 4, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
nodejs-github-bot pushed a commit that referenced this pull request May 4, 2025
According to the documentation, the v8 tasks should be executed
based on priority. Previously we always execute the tasks in
FIFO order, this changes the NodePlatform implementation to
execute the higher priority tasks first. The tasks used to
schedule timers for the delayed tasks are run in FIFO order
since priority is irrelavent for the timer scheduling part
while the tasks unwrapped by the timer callbacks are still
ordered by priority.
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
nodejs-github-bot pushed a commit that referenced this pull request May 4, 2025
we should not be blocking on the worker tasks on the
main thread in one go. Doing so leads to two problems:
1. If any of the worker tasks post another foreground task and wait
for it to complete, and that foreground task is posted right after
we flush the foreground task queue and before the foreground thread
goes into sleep, we'll never be able to wake up to execute that
foreground task and in turn the worker task will never complete, and
we have a deadlock.
2. Worker tasks can be posted from any thread, not necessarily
associated with the current isolate, and we can be blocking on a
worker task that is associated with a completely unrelated isolate
in the event loop. This is suboptimal.
However, not blocking on the worker tasks at all can lead to loss of
some critical user-blocking worker tasks e.g. wasm async compilation
tasks, which should block the main thread until they are completed,
as the documentation suggets. As a compromise, we currently only block
on user-blocking tasks to reduce the chance of deadlocks while making
sure that criticl user-blocking tasks are not lost.
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
RafaelGSS pushed a commit that referenced this pull request May 5, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
RafaelGSS pushed a commit that referenced this pull request May 5, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
RafaelGSS pushed a commit that referenced this pull request May 5, 2025
According to the documentation, the v8 tasks should be executed
based on priority. Previously we always execute the tasks in
FIFO order, this changes the NodePlatform implementation to
execute the higher priority tasks first. The tasks used to
schedule timers for the delayed tasks are run in FIFO order
since priority is irrelavent for the timer scheduling part
while the tasks unwrapped by the timer callbacks are still
ordered by priority.
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
RafaelGSS pushed a commit that referenced this pull request May 5, 2025
we should not be blocking on the worker tasks on the
main thread in one go. Doing so leads to two problems:
1. If any of the worker tasks post another foreground task and wait
for it to complete, and that foreground task is posted right after
we flush the foreground task queue and before the foreground thread
goes into sleep, we'll never be able to wake up to execute that
foreground task and in turn the worker task will never complete, and
we have a deadlock.
2. Worker tasks can be posted from any thread, not necessarily
associated with the current isolate, and we can be blocking on a
worker task that is associated with a completely unrelated isolate
in the event loop. This is suboptimal.
However, not blocking on the worker tasks at all can lead to loss of
some critical user-blocking worker tasks e.g. wasm async compilation
tasks, which should block the main thread until they are completed,
as the documentation suggets. As a compromise, we currently only block
on user-blocking tasks to reduce the chance of deadlocks while making
sure that criticl user-blocking tasks are not lost.
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 6, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 6, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 6, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 6, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
RafaelGSS pushed a commit that referenced this pull request May 14, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
RafaelGSS pushed a commit that referenced this pull request May 14, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 16, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 16, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 17, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 17, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 18, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 18, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 19, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 19, 2025
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request Jul 21, 2025
According to the documentation, the v8 tasks should be executed
based on priority. Previously we always execute the tasks in
FIFO order, this changes the NodePlatform implementation to
execute the higher priority tasks first. The tasks used to
schedule timers for the delayed tasks are run in FIFO order
since priority is irrelavent for the timer scheduling part
while the tasks unwrapped by the timer callbacks are still
ordered by priority.
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request Jul 21, 2025
we should not be blocking on the worker tasks on the
main thread in one go. Doing so leads to two problems:
1. If any of the worker tasks post another foreground task and wait
for it to complete, and that foreground task is posted right after
we flush the foreground task queue and before the foreground thread
goes into sleep, we'll never be able to wake up to execute that
foreground task and in turn the worker task will never complete, and
we have a deadlock.
2. Worker tasks can be posted from any thread, not necessarily
associated with the current isolate, and we can be blocking on a
worker task that is associated with a completely unrelated isolate
in the event loop. This is suboptimal.
However, not blocking on the worker tasks at all can lead to loss of
some critical user-blocking worker tasks e.g. wasm async compilation
tasks, which should block the main thread until they are completed,
as the documentation suggets. As a compromise, we currently only block
on user-blocking tasks to reduce the chance of deadlocks while making
sure that criticl user-blocking tasks are not lost.
PR-URL: #58047
Refs: #47452
Refs: #54918
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++Issues and PRs that require attention from people who are familiar with C++.needs-ciPRs that need a full CI run.stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@dinfuehr@targos@joyeecheung@aduh95@avivkeller@nodejs-github-bot