Skip to content

Commit 3a4d845

Browse files
committed
Enforce maxFree
1 parent 09fadaa commit 3a4d845

5 files changed

Lines changed: 23 additions & 4 deletions

File tree

lib/core/symbols.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,6 @@ module.exports = {
7070
kPingInterval: Symbol('ping interval'),
7171
kNoProxyAgent: Symbol('no proxy agent'),
7272
kHttpProxyAgent: Symbol('http proxy agent'),
73-
kHttpsProxyAgent: Symbol('https proxy agent')
73+
kHttpsProxyAgent: Symbol('https proxy agent'),
74+
kMaxFree: Symbol('max free')
7475
}

lib/dispatcher/pool-base.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const { PoolStats } = require('../util/stats.js')
44
const DispatcherBase = require('./dispatcher-base')
55
const FixedQueue = require('./fixed-queue')
6-
const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = require('../core/symbols')
6+
const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch, kMaxFree } = require('../core/symbols')
77

88
const kClients = Symbol('clients')
99
const kNeedDrain = Symbol('needDrain')
@@ -40,6 +40,14 @@ class PoolBase extends DispatcherBase {
4040
needDrain = !client.dispatch(item.opts, item.handler)
4141
}
4242

43+
if (this[kMaxFree] < Infinity && this[kFree] > this[kMaxFree]) {
44+
for (let i = 0; i < this[kClients].length; i++) {
45+
const client = this[kClients][i]
46+
if (!client[kNeedDrain]) this[kRemoveClient](client)
47+
if (this[kFree] <= this[kMaxFree]) break
48+
}
49+
}
50+
4351
client[kNeedDrain] = needDrain
4452

4553
if (!needDrain && this[kNeedDrain]) {

lib/dispatcher/pool.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const {
1313
InvalidArgumentError
1414
} = require('../core/errors')
1515
const util = require('../core/util')
16-
const { kUrl } = require('../core/symbols')
16+
const { kUrl, kMaxFree } = require('../core/symbols')
1717
const buildConnector = require('../core/connect')
1818

1919
const kOptions = Symbol('options')
@@ -37,6 +37,7 @@ class Pool extends PoolBase {
3737
autoSelectFamilyAttemptTimeout,
3838
allowH2,
3939
clientTtl,
40+
maxFree = Infinity,
4041
...options
4142
} = {}) {
4243
if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
@@ -51,6 +52,10 @@ class Pool extends PoolBase {
5152
throw new InvalidArgumentError('connect must be a function or an object')
5253
}
5354

55+
if (typeof maxFree !== 'number' || Number.isNaN(maxFree) || maxFree <= 0) {
56+
throw new InvalidArgumentError('maxFree must be a number greater than 0')
57+
}
58+
5459
if (typeof connect !== 'function') {
5560
connect = buildConnector({
5661
...tls,
@@ -67,11 +72,12 @@ class Pool extends PoolBase {
6772

6873
this[kConnections] = connections || null
6974
this[kUrl] = util.parseOrigin(origin)
70-
this[kOptions] = { ...util.deepClone(options), connect, allowH2, clientTtl }
75+
this[kOptions] = { ...util.deepClone(options), connect, allowH2, clientTtl, maxFree }
7176
this[kOptions].interceptors = options.interceptors
7277
? { ...options.interceptors }
7378
: undefined
7479
this[kFactory] = factory
80+
this[kMaxFree] = maxFree
7581

7682
this.on('connect', (origin, targets) => {
7783
if (clientTtl != null && clientTtl > 0) {

types/agent.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ declare namespace Agent {
2525

2626
interceptors?: { Agent?: readonly Dispatcher.DispatchInterceptor[] } & Pool.Options['interceptors']
2727
maxOrigins?: number
28+
/** The max number of free (idle) connections to keep open per origin. Passed to each Pool. Default `Infinity`. */
29+
maxFree?: number
2830
}
2931

3032
export interface DispatchOptions extends Dispatcher.DispatchOptions {

types/pool.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ declare namespace Pool {
3535
connections?: number | null;
3636
/** The amount of time before a client is removed from the pool and closed. `null` if no time limit. Default `null` */
3737
clientTtl?: number | null;
38+
/** The max number of free (idle) connections to keep open per origin. Default `Infinity`. */
39+
maxFree?: number;
3840

3941
interceptors?: { Pool?: readonly Dispatcher.DispatchInterceptor[] } & Client.Options['interceptors']
4042
}

0 commit comments

Comments
 (0)