Skip to content

Commit 19e8725

Browse files
author
Rafal Augustyniak
committed
new options - resourceLimits
1 parent b2d5552 commit 19e8725

File tree

8 files changed

+158
-9
lines changed

8 files changed

+158
-9
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2.4.0] - 2021-12-03
9+
10+
### Added
11+
12+
- new options `resourceLimits`, See [Node.js new Worker options](https://nodejs.org/api/worker_threads.html#worker_threads_new_worker_filename_options)
13+
814
## [2.3.1] - 2021-05-05
915

1016
### Changed

Readme.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ Describes a WorkerNodes options.
104104
* [.taskMaxRetries](#WorkerNodesOptions+taskMaxRetries) : <code>Number</code>
105105
* [.workerEndurance](#WorkerNodesOptions+workerEndurance) : <code>Number</code>
106106
* [.workerStopTimeout](#WorkerNodesOptions+workerStopTimeout) : <code>Number</code>
107+
* [.resourceLimits](#WorkerNodesOptions+resourceLimits) : <code>Object</code>
107108

108109
<a name="WorkerNodesOptions+autoStart"></a>
109110

@@ -191,6 +192,21 @@ The timeout value (in milliseconds) for the worker to stop before sending SIGKIL
191192

192193
**Kind**: instance property of [<code>WorkerNodesOptions</code>](#WorkerNodesOptions)
193194
**Default**: <code>100</code>
195+
<a name="WorkerNodesOptions+resourceLimits"></a>
196+
197+
### options.resourceLimits : <code>Object</code>
198+
Provides the set of JS engine resource constraints inside this Worker thread.
199+
200+
**Kind**: instance property of [<code>WorkerNodesOptions</code>](#WorkerNodesOptions)
201+
**Properties**
202+
203+
| Name | Type | Description |
204+
| --- | --- | --- |
205+
| maxYoungGenerationSizeMb | <code>Number</code> | The maximum size of a heap space for recently created objects |
206+
| maxOldGenerationSizeMb | <code>Number</code> | The maximum size of the main heap in MB |
207+
| codeRangeSizeMb | <code>Number</code> | The size of a pre-allocated memory range used for generated code |
208+
| stackSizeMb | <code>Number</code> | The default maximum stack size for the thread. Small values may lead to unusable Worker instances |
209+
194210

195211
## Example
196212

e2e/resource-limits.spec.js

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
const test = require('ava');
2+
3+
const WorkerNodes = require('../');
4+
const { fixture } = require('./utils');
5+
6+
test('should set maxYoungGenerationSizeMb', async t => {
7+
// given
8+
const workerNodes = new WorkerNodes(fixture('process-info'), {
9+
autoStart: true,
10+
maxWorkers: 2,
11+
minWorkers: 2,
12+
resourceLimits: {
13+
maxYoungGenerationSizeMb: 20
14+
}
15+
});
16+
17+
// when
18+
await workerNodes.ready();
19+
20+
const workersList = workerNodes.getUsedWorkers();
21+
22+
// then
23+
workersList.forEach(worker => {
24+
if (!worker.resourceLimits) {
25+
// resourceLimits is unsupported before node 12, skipping
26+
return t.true(true);
27+
}
28+
29+
t.true(worker.resourceLimits.maxYoungGenerationSizeMb === 20)
30+
});
31+
});
32+
33+
test('should set maxOldGenerationSizeMb', async t => {
34+
// given
35+
const workerNodes = new WorkerNodes(fixture('process-info'), {
36+
autoStart: true,
37+
maxWorkers: 2,
38+
minWorkers: 2,
39+
resourceLimits: {
40+
maxOldGenerationSizeMb: 300
41+
}
42+
});
43+
44+
// when
45+
await workerNodes.ready();
46+
47+
const workersList = workerNodes.getUsedWorkers();
48+
49+
// then
50+
workersList.forEach(worker => {
51+
if (!worker.resourceLimits) {
52+
// resourceLimits is unsupported before node 12, skipping
53+
return t.true(true);
54+
}
55+
56+
t.true(worker.resourceLimits.maxOldGenerationSizeMb === 300)
57+
});
58+
});
59+
60+
test('should set codeRangeSizeMb', async t => {
61+
// given
62+
const workerNodes = new WorkerNodes(fixture('process-info'), {
63+
autoStart: true,
64+
maxWorkers: 2,
65+
minWorkers: 2,
66+
resourceLimits: {
67+
codeRangeSizeMb: 1
68+
}
69+
});
70+
71+
// when
72+
await workerNodes.ready();
73+
74+
const workersList = workerNodes.getUsedWorkers();
75+
76+
// then
77+
workersList.forEach(worker => {
78+
if (!worker.resourceLimits) {
79+
// resourceLimits is unsupported before node 12, skipping
80+
return t.true(true);
81+
}
82+
83+
t.true(worker.resourceLimits.codeRangeSizeMb === 1)
84+
});
85+
});
86+
87+
test('should set stackSizeMb', async t => {
88+
// given
89+
const workerNodes = new WorkerNodes(fixture('process-info'), {
90+
autoStart: true,
91+
maxWorkers: 2,
92+
minWorkers: 2,
93+
resourceLimits: {
94+
stackSizeMb: 8
95+
}
96+
});
97+
98+
// when
99+
await workerNodes.ready();
100+
101+
const workersList = workerNodes.getUsedWorkers();
102+
103+
// then
104+
workersList.forEach(worker => {
105+
if (!worker.resourceLimits) {
106+
// resourceLimits is unsupported before node 12, skipping
107+
return t.true(true);
108+
}
109+
110+
t.true(worker.resourceLimits.stackSizeMb === 8)
111+
});
112+
});

lib/options.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ class WorkerNodesOptions {
1717
taskTimeout = Infinity,
1818
taskMaxRetries = 0,
1919
workerEndurance = Infinity,
20-
workerStopTimeout = 100
20+
workerStopTimeout = 100,
21+
resourceLimits = {}
2122
} = {}) {
2223
/**
2324
* Whether should initialize the workers before a first call.
@@ -115,6 +116,17 @@ class WorkerNodesOptions {
115116
* @default 100
116117
*/
117118
this.workerStopTimeout = Number(workerStopTimeout);
119+
120+
/**
121+
* Provides the set of JS engine resource constraints inside this Worker thread.
122+
*
123+
* @type {Object}
124+
* @property {Number} maxYoungGenerationSizeMb - The maximum size of a heap space for recently created objects
125+
* @property {Number} maxOldGenerationSizeMb - The maximum size of the main heap in MB
126+
* @property {Number} codeRangeSizeMb - The size of a pre-allocated memory range used for generated code
127+
* @property {Number} stackSizeMb - The default maximum stack size for the thread. Small values may lead to unusable Worker instances
128+
*/
129+
this.resourceLimits = resourceLimits;
118130
}
119131

120132
/**
@@ -139,7 +151,8 @@ class WorkerNodesOptions {
139151
maxTasks: this.maxTasksPerWorker,
140152
endurance: this.workerEndurance,
141153
stopTimeout: this.workerStopTimeout,
142-
asyncWorkerInitialization: this.asyncWorkerInitialization
154+
asyncWorkerInitialization: this.asyncWorkerInitialization,
155+
resourceLimits: this.resourceLimits
143156
}
144157
}
145158
}

lib/worker.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const ProcessResponse = messages.Response;
1010
const workerSerial = new Sequence(1);
1111

1212
class Worker extends EventEmitter {
13-
constructor({ srcFilePath, maxTasks, endurance, stopTimeout, asyncWorkerInitialization }) {
13+
constructor({ srcFilePath, maxTasks, endurance, stopTimeout, asyncWorkerInitialization, resourceLimits }) {
1414
super();
1515

1616
this.id = workerSerial.nextValue();
@@ -21,7 +21,7 @@ class Worker extends EventEmitter {
2121
this.isTerminating = false;
2222
this.isProcessAlive = false;
2323

24-
const process = this.process = new WorkerProcess(srcFilePath, { stopTimeout, asyncWorkerInitialization });
24+
const process = this.process = new WorkerProcess(srcFilePath, { stopTimeout, asyncWorkerInitialization, resourceLimits });
2525

2626
process.once('ready', () => {
2727
this.isProcessAlive = true;

lib/worker/process.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ const worker = require('worker_threads');
22
const EventEmitter = require('events');
33

44
class WorkerProcess extends EventEmitter {
5-
constructor(modulePath, { asyncWorkerInitialization }) {
5+
constructor(modulePath, { asyncWorkerInitialization, resourceLimits }) {
66
super();
77

8-
const child = new worker.Worker(require.resolve('./child-loader'));
8+
const child = new worker.Worker(require.resolve('./child-loader'), {
9+
resourceLimits,
10+
});
911

1012
child.once('message', () => {
1113
// report readiness on a first message received from the child

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "worker-nodes",
3-
"version": "2.3.1",
3+
"version": "2.4.0",
44
"description": "A library to run cpu-intensive tasks without blocking the event loop.",
55
"keywords": [
66
"workers",

0 commit comments

Comments
 (0)