Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/internal/worker.js')
-rw-r--r--lib/internal/worker.js56
1 files changed, 56 insertions, 0 deletions
diff --git a/lib/internal/worker.js b/lib/internal/worker.js
index e97cd7efea2..b3c310e93e8 100644
--- a/lib/internal/worker.js
+++ b/lib/internal/worker.js
@@ -20,6 +20,7 @@ const {
const EventEmitter = require('events');
const assert = require('internal/assert');
const path = require('path');
+const { timeOrigin } = internalBinding('performance');
const errorCodes = require('internal/errors').codes;
const {
@@ -70,6 +71,8 @@ const kOnMessage = Symbol('kOnMessage');
const kOnCouldNotSerializeErr = Symbol('kOnCouldNotSerializeErr');
const kOnErrorMessage = Symbol('kOnErrorMessage');
const kParentSideStdio = Symbol('kParentSideStdio');
+const kLoopStartTime = Symbol('kLoopStartTime');
+const kIsOnline = Symbol('kIsOnline');
const SHARE_ENV = SymbolFor('nodejs.worker_threads.SHARE_ENV');
let debug = require('internal/util/debuglog').debuglog('worker', (fn) => {
@@ -223,6 +226,12 @@ class Worker extends EventEmitter {
null,
hasStdin: !!options.stdin
}, transferList);
+ // Use this to cache the Worker's loopStart value once available.
+ this[kLoopStartTime] = -1;
+ this[kIsOnline] = false;
+ this.performance = {
+ eventLoopUtilization: eventLoopUtilization.bind(this),
+ };
// Actually start the new thread now that everything is in place.
this[kHandle].startThread();
}
@@ -254,6 +263,7 @@ class Worker extends EventEmitter {
[kOnMessage](message) {
switch (message.type) {
case messageTypes.UP_AND_RUNNING:
+ this[kIsOnline] = true;
return this.emit('online');
case messageTypes.COULD_NOT_SERIALIZE_ERROR:
return this[kOnCouldNotSerializeErr]();
@@ -415,6 +425,52 @@ function makeResourceLimits(float64arr) {
};
}
+function eventLoopUtilization(util1, util2) {
+ // TODO(trevnorris): Works to solve the thread-safe read/write issue of
+ // loopTime, but has the drawback that it can't be set until the event loop
+ // has had a chance to turn. So it will be impossible to read the ELU of
+ // a worker thread immediately after it's been created.
+ if (!this[kIsOnline] || !this[kHandle]) {
+ return { idle: 0, active: 0, utilization: 0 };
+ }
+
+ // Cache loopStart, since it's only written to once.
+ if (this[kLoopStartTime] === -1) {
+ this[kLoopStartTime] = this[kHandle].loopStartTime();
+ if (this[kLoopStartTime] === -1)
+ return { idle: 0, active: 0, utilization: 0 };
+ }
+
+ if (util2) {
+ const idle = util1.idle - util2.idle;
+ const active = util1.active - util2.active;
+ return { idle, active, utilization: active / (idle + active) };
+ }
+
+ const idle = this[kHandle].loopIdleTime();
+
+ // Using performance.now() here is fine since it's always the time from
+ // the beginning of the process, and is why it needs to be offset by the
+ // loopStart time (which is also calculated from the beginning of the
+ // process).
+ const active = now() - this[kLoopStartTime] - idle;
+
+ if (!util1) {
+ return { idle, active, utilization: active / (idle + active) };
+ }
+
+ const idle_delta = idle - util1.idle;
+ const active_delta = active - util1.active;
+ const utilization = active_delta / (idle_delta + active_delta);
+ return { idle: idle_delta, active: active_delta, utilization };
+}
+
+// Duplicate code from performance.now() so don't need to require perf_hooks.
+function now() {
+ const hr = process.hrtime();
+ return (hr[0] * 1000 + hr[1] / 1e6) - timeOrigin;
+}
+
module.exports = {
ownsProcessState,
isMainThread,