Skip to content

Commit 37d49f3

Browse files
gurgundayaduh95
authored andcommitted
process: optimize asyncHandledRejections by using FixedQueue
PR-URL: #60854 Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Ilyas Shabi <ilyasshabi94@gmail.com> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
1 parent b39508b commit 37d49f3

2 files changed

Lines changed: 51 additions & 8 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
constcommon=require('../common.js');
4+
5+
// Benchmarks the throughput of processing many promise rejections that are
6+
// initially unhandled, get warned, and then handled asynchronously, exercising
7+
// asyncHandledRejections + processPromiseRejections.
8+
//
9+
// Note: This benchmark uses --unhandled-rejections=warn to avoid crashing
10+
// when promises are temporarily unhandled.
11+
12+
constbench=common.createBenchmark(main,{
13+
n: [1e4,5e4,1e5],
14+
},{
15+
flags: ['--unhandled-rejections=warn'],
16+
});
17+
18+
functionmain({ n }){
19+
constrejections=[];
20+
21+
// Suppress warning output during the benchmark
22+
process.removeAllListeners('warning');
23+
24+
for(leti=0;i<n;i++){
25+
rejections.push(Promise.reject(i));
26+
}
27+
28+
// Wait for them to be processed as unhandled and warned.
29+
setImmediate(()=>{
30+
setImmediate(()=>{
31+
bench.start();
32+
33+
for(leti=0;i<n;i++){
34+
rejections[i].catch(()=>{});
35+
}
36+
37+
// Let processPromiseRejections drain asyncHandledRejections.
38+
setImmediate(()=>{
39+
bench.end(n);
40+
});
41+
});
42+
});
43+
}

‎lib/internal/process/promises.js‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
'use strict';
22

33
const{
4-
ArrayPrototypePush,
5-
ArrayPrototypeShift,
64
Error,
75
ObjectPrototypeHasOwnProperty,
86
SafeMap,
97
SafeWeakMap,
108
}=primordials;
119

10+
constFixedQueue=require('internal/fixed_queue');
11+
1212
const{
1313
tickInfo,
1414
promiseRejectEvents: {
@@ -142,9 +142,9 @@ const maybeUnhandledPromises = new SafeWeakMap();
142142
letpendingUnhandledRejections=newSafeMap();
143143

144144
/**
145-
* @type {Array<{promise: Promise, warning: Error}>}
145+
* @type {import('internal/fixed_queue')<{promise: Promise, warning: Error}>}
146146
*/
147-
constasyncHandledRejections=[];
147+
constasyncHandledRejections=newFixedQueue();
148148

149149
/**
150150
* @type {number}
@@ -281,7 +281,7 @@ function handledRejection(promise) {
281281
if(promiseInfo.warned){
282282
// Generate the warning object early to get a good stack trace.
283283
constwarning=newPromiseRejectionHandledWarning(promiseInfo.uid);
284-
ArrayPrototypePush(asyncHandledRejections,{ promise, warning });
284+
asyncHandledRejections.push({ promise, warning });
285285
setHasRejectionToWarn(true);
286286
}
287287
}
@@ -437,10 +437,10 @@ function getUnhandledRejectionsMode() {
437437
// a warning to be emitted which requires the microtask and next tick
438438
// queues to be drained again.
439439
functionprocessPromiseRejections(){
440-
letmaybeScheduledTicksOrMicrotasks=asyncHandledRejections.length>0;
440+
letmaybeScheduledTicksOrMicrotasks=!asyncHandledRejections.isEmpty();
441441

442-
while(asyncHandledRejections.length!==0){
443-
const{ promise, warning }=ArrayPrototypeShift(asyncHandledRejections);
442+
while(!asyncHandledRejections.isEmpty()){
443+
const{ promise, warning }=asyncHandledRejections.shift();
444444
if(!process.emit('rejectionHandled',promise)){
445445
process.emitWarning(warning);
446446
}

0 commit comments

Comments
 (0)