nodejs / nodejs/nan

Worker Creation from Foreign Thread

Open
#669 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
3.4k
Forks
531
Avg merge
21m
Merged PRs (30d)
1

Description

AsyncWorker is useful whenever we want to have an asynchronous call to foreign code and potentially that foreign code can call back into the V8 main thread using AsyncProgressWorker.

However, what if you have a callback from a foreign thread that you don't control? In this case, AsyncWorker cannot be created from within the foreign thread (or it would not be trivial in best case) since you don't have an active V8 isolate. You can create one but anything that you pass to that worker from the main isolate would be useless in the new isolate without heavy amounts of context copying (of which I'm not sure can be done correctly right now). So using a V8 callback from the main isolate is pointless here.

Also, in order to call a V8 callback in the first place, memory must be copied again and sent down the queue again via Send member function. This seems a tad wasteful when I really just want a function to execute in the main thread to begin with.

In the end, I determined I needed a new wrapper to achieve what I wanted and created something for my personal project which basically just creates an uv_async_t. I make a wrapper function where whenever I get the signal from a native thread, it creates a new object with the data provided by the signal and sends it off. It calls an Execute function, which runs in the main thread to which I can call my JS callbacks from, no need for a middle man. The memory is marshaled so the Execute function cleans up its own object at the very last second.

TL;DR I'm curious as to why nobody else seems to have run into this problem and/or if there's a better solution that I'm not seeing. The solution I made seems pretty solid but I'm wondering if it's okay to destroy uv_async_t at the last second like I'm doing since while I don't see anywhere that it does and it seems to work, I'm afraid this may change later on or might be platform specific.

In addition, I tried using uv_queue_work with uv_default_loop but this didn't execute on the main thread. However, uv_async_send does, while also using uv_default_loop. Why is this?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the named entry points AsyncWorker, AsyncProgressWorker, uv_async_t, uv_queue_work, uv_default_loop, and uv_async_send, comparing their thread and lifecycle guarantees. The issue does not name a file or test; done would be a documented, supported approach for invoking the main-thread callback from an uncontrolled foreign thread, including whether the proposed async-handle cleanup is safe.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, nodejs
Domain
backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.