Skip to content

Commit

Permalink
worker: add hasRef()
Browse files Browse the repository at this point in the history
This should help projects like
https://github.com/mafintosh/why-is-node-running and
https://github.com/facebook/jest to detect if Worker instances are
keeping the event loop active correctly.

Fixes: #42091
Refs: mafintosh/why-is-node-running#59
Signed-off-by: Darshan Sen <raisinten@gmail.com>
  • Loading branch information
RaisinTen committed Apr 16, 2022
1 parent 24adba6 commit 3a000eb
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 0 deletions.
12 changes: 12 additions & 0 deletions doc/api/worker_threads.md
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,18 @@ Send a message to the worker that is received via
[`require('worker_threads').parentPort.on('message')`][].
See [`port.postMessage()`][] for more details.

### `worker.hasRef()`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
* Returns: {boolean}

If `true`, the `Worker` object will keep the Node.js event loop active.

### `worker.ref()`

<!-- YAML
Expand Down
6 changes: 6 additions & 0 deletions lib/internal/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,12 @@ class Worker extends EventEmitter {
});
}

hasRef() {
if (this[kHandle] === null) return false;

return this[kHandle].hasRef();
}

ref() {
if (this[kHandle] === null) return;

Expand Down
8 changes: 8 additions & 0 deletions src/node_worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,12 @@ void Worker::Ref(const FunctionCallbackInfo<Value>& args) {
}
}

void Worker::HasRef(const FunctionCallbackInfo<Value>& args) {
Worker* w;
ASSIGN_OR_RETURN_UNWRAP(&w, args.This());
args.GetReturnValue().Set(w->has_ref_);
}

void Worker::Unref(const FunctionCallbackInfo<Value>& args) {
Worker* w;
ASSIGN_OR_RETURN_UNWRAP(&w, args.This());
Expand Down Expand Up @@ -827,6 +833,7 @@ void InitWorker(Local<Object> target,

env->SetProtoMethod(w, "startThread", Worker::StartThread);
env->SetProtoMethod(w, "stopThread", Worker::StopThread);
env->SetProtoMethod(w, "hasRef", Worker::HasRef);
env->SetProtoMethod(w, "ref", Worker::Ref);
env->SetProtoMethod(w, "unref", Worker::Unref);
env->SetProtoMethod(w, "getResourceLimits", Worker::GetResourceLimits);
Expand Down Expand Up @@ -890,6 +897,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(Worker::New);
registry->Register(Worker::StartThread);
registry->Register(Worker::StopThread);
registry->Register(Worker::HasRef);
registry->Register(Worker::Ref);
registry->Register(Worker::Unref);
registry->Register(Worker::GetResourceLimits);
Expand Down
1 change: 1 addition & 0 deletions src/node_worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Worker : public AsyncWrap {
static void SetEnvVars(const v8::FunctionCallbackInfo<v8::Value>& args);
static void StartThread(const v8::FunctionCallbackInfo<v8::Value>& args);
static void StopThread(const v8::FunctionCallbackInfo<v8::Value>& args);
static void HasRef(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Ref(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Unref(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetResourceLimits(
Expand Down
15 changes: 15 additions & 0 deletions test/parallel/test-worker-hasref.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';
const common = require('../common');

const { Worker } = require('worker_threads');
const { strictEqual } = require('assert');

const w = new Worker('', { eval: true });

strictEqual(w.hasRef(), true);
w.unref();
strictEqual(w.hasRef(), false);
w.ref();
strictEqual(w.hasRef(), true);

w.on('exit', common.mustCall(() => strictEqual(w.hasRef(), false)));

0 comments on commit 3a000eb

Please sign in to comment.