Skip to content

Commit 33c87ec

Browse files
authored
benchmark: fix race condition on fs benchs
PR-URL: #50035 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 0f0dd1a commit 33c87ec

5 files changed

+99
-67
lines changed

benchmark/fs/readfile-partitioned.js

+25-13
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const filename = path.resolve(__dirname,
1414
`.removeme-benchmark-garbage-${process.pid}`);
1515
const fs = require('fs');
1616
const zlib = require('zlib');
17-
const assert = require('assert');
1817

1918
const bench = common.createBenchmark(main, {
2019
duration: [5],
@@ -35,41 +34,49 @@ function main({ len, duration, concurrent, encoding }) {
3534

3635
const zipData = Buffer.alloc(1024, 'a');
3736

37+
let waitConcurrent = 0;
38+
39+
// Plus one because of zip
40+
const targetConcurrency = concurrent + 1;
41+
const startedAt = Date.now();
42+
const endAt = startedAt + (duration * 1000);
43+
3844
let reads = 0;
3945
let zips = 0;
40-
let benchEnded = false;
46+
4147
bench.start();
42-
setTimeout(() => {
48+
49+
function stop() {
4350
const totalOps = reads + zips;
44-
benchEnded = true;
4551
bench.end(totalOps);
52+
4653
try {
4754
fs.unlinkSync(filename);
4855
} catch {
4956
// Continue regardless of error.
5057
}
51-
}, duration * 1000);
58+
}
5259

5360
function read() {
5461
fs.readFile(filename, encoding, afterRead);
5562
}
5663

5764
function afterRead(er, data) {
5865
if (er) {
59-
if (er.code === 'ENOENT') {
60-
// Only OK if unlinked by the timer from main.
61-
assert.ok(benchEnded);
62-
return;
63-
}
6466
throw er;
6567
}
6668

6769
if (data.length !== len)
6870
throw new Error('wrong number of bytes returned');
6971

7072
reads++;
71-
if (!benchEnded)
73+
const benchEnded = Date.now() >= endAt;
74+
75+
if (benchEnded && (++waitConcurrent) === targetConcurrency) {
76+
stop();
77+
} else if (!benchEnded) {
7278
read();
79+
}
7380
}
7481

7582
function zip() {
@@ -81,12 +88,17 @@ function main({ len, duration, concurrent, encoding }) {
8188
throw er;
8289

8390
zips++;
84-
if (!benchEnded)
91+
const benchEnded = Date.now() >= endAt;
92+
93+
if (benchEnded && (++waitConcurrent) === targetConcurrency) {
94+
stop();
95+
} else if (!benchEnded) {
8596
zip();
97+
}
8698
}
8799

88100
// Start reads
89-
while (concurrent-- > 0) read();
101+
for (let i = 0; i < concurrent; i++) read();
90102

91103
// Start a competing zip
92104
zip();

benchmark/fs/readfile-permission-enabled.js

+17-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
const common = require('../common.js');
77
const fs = require('fs');
8-
const assert = require('assert');
98

109
const tmpdir = require('../../test/common/tmpdir');
1110
tmpdir.refresh();
@@ -36,40 +35,46 @@ function main({ len, duration, concurrent, encoding }) {
3635
data = null;
3736

3837
let reads = 0;
39-
let benchEnded = false;
38+
let waitConcurrent = 0;
39+
40+
const startedAt = Date.now();
41+
const endAt = startedAt + (duration * 1000);
42+
4043
bench.start();
41-
setTimeout(() => {
42-
benchEnded = true;
44+
45+
function stop() {
4346
bench.end(reads);
47+
4448
try {
4549
fs.unlinkSync(filename);
4650
} catch {
4751
// Continue regardless of error.
4852
}
53+
4954
process.exit(0);
50-
}, duration * 1000);
55+
}
5156

5257
function read() {
5358
fs.readFile(filename, encoding, afterRead);
5459
}
5560

5661
function afterRead(er, data) {
5762
if (er) {
58-
if (er.code === 'ENOENT') {
59-
// Only OK if unlinked by the timer from main.
60-
assert.ok(benchEnded);
61-
return;
62-
}
6363
throw er;
6464
}
6565

6666
if (data.length !== len)
6767
throw new Error('wrong number of bytes returned');
6868

6969
reads++;
70-
if (!benchEnded)
70+
const benchEnded = Date.now() >= endAt;
71+
72+
if (benchEnded && (++waitConcurrent) === concurrent) {
73+
stop();
74+
} else if (!benchEnded) {
7175
read();
76+
}
7277
}
7378

74-
while (concurrent--) read();
79+
for (let i = 0; i < concurrent; i++) read();
7580
}

benchmark/fs/readfile-promises.js

+20-15
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
const common = require('../common.js');
77
const fs = require('fs');
8-
const assert = require('assert');
98

109
const tmpdir = require('../../test/common/tmpdir');
1110
tmpdir.refresh();
@@ -35,19 +34,25 @@ function main({ len, duration, concurrent, encoding }) {
3534
fs.writeFileSync(filename, data);
3635
data = null;
3736

38-
let writes = 0;
39-
let benchEnded = false;
37+
let reads = 0;
38+
let waitConcurrent = 0;
39+
40+
const startedAt = Date.now();
41+
const endAt = startedAt + (duration * 1000);
42+
4043
bench.start();
41-
setTimeout(() => {
42-
benchEnded = true;
43-
bench.end(writes);
44+
45+
function stop() {
46+
bench.end(reads);
47+
4448
try {
4549
fs.unlinkSync(filename);
4650
} catch {
4751
// Continue regardless of error.
4852
}
53+
4954
process.exit(0);
50-
}, duration * 1000);
55+
}
5156

5257
function read() {
5358
fs.promises.readFile(filename, encoding)
@@ -57,21 +62,21 @@ function main({ len, duration, concurrent, encoding }) {
5762

5863
function afterRead(er, data) {
5964
if (er) {
60-
if (er.code === 'ENOENT') {
61-
// Only OK if unlinked by the timer from main.
62-
assert.ok(benchEnded);
63-
return;
64-
}
6565
throw er;
6666
}
6767

6868
if (data.length !== len)
6969
throw new Error('wrong number of bytes returned');
7070

71-
writes++;
72-
if (!benchEnded)
71+
reads++;
72+
const benchEnded = Date.now() >= endAt;
73+
74+
if (benchEnded && (++waitConcurrent) === concurrent) {
75+
stop();
76+
} else if (!benchEnded) {
7377
read();
78+
}
7479
}
7580

76-
while (concurrent--) read();
81+
for (let i = 0; i < concurrent; i++) read();
7782
}

benchmark/fs/readfile.js

+20-15
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
const common = require('../common.js');
77
const fs = require('fs');
8-
const assert = require('assert');
98

109
const tmpdir = require('../../test/common/tmpdir');
1110
tmpdir.refresh();
@@ -29,40 +28,46 @@ function main({ len, duration, concurrent, encoding }) {
2928
data = null;
3029

3130
let reads = 0;
32-
let benchEnded = false;
31+
let waitConcurrent = 0;
32+
33+
const startedAt = Date.now();
34+
const endAt = startedAt + (duration * 1000);
35+
3336
bench.start();
34-
setTimeout(() => {
35-
benchEnded = true;
37+
38+
function read() {
39+
fs.readFile(filename, encoding, afterRead);
40+
}
41+
42+
function stop() {
3643
bench.end(reads);
44+
3745
try {
3846
fs.unlinkSync(filename);
3947
} catch {
4048
// Continue regardless of error.
4149
}
42-
process.exit(0);
43-
}, duration * 1000);
4450

45-
function read() {
46-
fs.readFile(filename, encoding, afterRead);
51+
process.exit(0);
4752
}
4853

4954
function afterRead(er, data) {
5055
if (er) {
51-
if (er.code === 'ENOENT') {
52-
// Only OK if unlinked by the timer from main.
53-
assert.ok(benchEnded);
54-
return;
55-
}
5656
throw er;
5757
}
5858

5959
if (data.length !== len)
6060
throw new Error('wrong number of bytes returned');
6161

6262
reads++;
63-
if (!benchEnded)
63+
const benchEnded = Date.now() >= endAt;
64+
65+
if (benchEnded && (++waitConcurrent) === concurrent) {
66+
stop();
67+
} else if (!benchEnded) {
6468
read();
69+
}
6570
}
6671

67-
while (concurrent--) read();
72+
for (let i = 0; i < concurrent; i++) read();
6873
}

benchmark/fs/writefile-promises.js

+17-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
const common = require('../common.js');
77
const fs = require('fs');
8-
const assert = require('assert');
98
const tmpdir = require('../../test/common/tmpdir');
109

1110
tmpdir.refresh();
@@ -38,20 +37,26 @@ function main({ encodingType, duration, concurrent, size }) {
3837
}
3938

4039
let writes = 0;
41-
let benchEnded = false;
40+
let waitConcurrent = 0;
41+
42+
const startedAt = Date.now();
43+
const endAt = startedAt + (duration * 1000);
44+
4245
bench.start();
43-
setTimeout(() => {
44-
benchEnded = true;
46+
47+
function stop() {
4548
bench.end(writes);
49+
4650
for (let i = 0; i < filesWritten; i++) {
4751
try {
4852
fs.unlinkSync(`${filename}-${i}`);
4953
} catch {
5054
// Continue regardless of error.
5155
}
5256
}
57+
5358
process.exit(0);
54-
}, duration * 1000);
59+
}
5560

5661
function write() {
5762
fs.promises.writeFile(`${filename}-${filesWritten++}`, chunk, encoding)
@@ -61,18 +66,18 @@ function main({ encodingType, duration, concurrent, size }) {
6166

6267
function afterWrite(er) {
6368
if (er) {
64-
if (er.code === 'ENOENT') {
65-
// Only OK if unlinked by the timer from main.
66-
assert.ok(benchEnded);
67-
return;
68-
}
6969
throw er;
7070
}
7171

7272
writes++;
73-
if (!benchEnded)
73+
const benchEnded = Date.now() >= endAt;
74+
75+
if (benchEnded && (++waitConcurrent) === concurrent) {
76+
stop();
77+
} else if (!benchEnded) {
7478
write();
79+
}
7580
}
7681

77-
while (concurrent--) write();
82+
for (let i = 0; i < concurrent; i++) write();
7883
}

0 commit comments

Comments
 (0)