Skip to content

Commit 60dfc59

Browse files
committed
Respect clientTtl
1 parent e351cbf commit 60dfc59

4 files changed

Lines changed: 39 additions & 5 deletions

File tree

lib/dispatcher/pool-base.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ class PoolBase extends DispatcherBase {
4343
if (this[kMaxIdle] < Infinity && this[kFree] > this[kMaxIdle]) {
4444
for (let i = 0; i < this[kClients].length; i++) {
4545
const client = this[kClients][i]
46-
if (!client[kNeedDrain]) this[kRemoveClient](client)
46+
if (!client[kNeedDrain]) {
47+
if (client.ttl && client.ttl > Date.now()) continue
48+
this[kRemoveClient](client)
49+
}
4750
if (this[kFree] <= this[kMaxIdle]) break
4851
}
4952
}

lib/dispatcher/pool.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class Pool extends PoolBase {
8282
this.on('connect', (origin, targets) => {
8383
if (clientTtl != null && clientTtl > 0) {
8484
for (const target of targets) {
85-
Object.assign(target, { ttl: Date.now() })
85+
Object.assign(target, { ttl: Date.now() + clientTtl })
8686
}
8787
}
8888
})
@@ -106,7 +106,7 @@ class Pool extends PoolBase {
106106
const clientTtlOption = this[kOptions].clientTtl
107107
for (const client of this[kClients]) {
108108
// check ttl of client and if it's stale, remove it from the pool
109-
if (clientTtlOption != null && clientTtlOption > 0 && client.ttl && ((Date.now() - client.ttl) > clientTtlOption)) {
109+
if (clientTtlOption != null && clientTtlOption > 0 && client.ttl && (client.ttl <= Date.now())) {
110110
this[kRemoveClient](client)
111111
} else if (!client[kNeedDrain]) {
112112
return client

lib/dispatcher/round-robin-pool.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class RoundRobinPool extends PoolBase {
7878
this.on('connect', (origin, targets) => {
7979
if (clientTtl != null && clientTtl > 0) {
8080
for (const target of targets) {
81-
Object.assign(target, { ttl: Date.now() })
81+
Object.assign(target, { ttl: Date.now() + clientTtl })
8282
}
8383
}
8484
})
@@ -111,7 +111,7 @@ class RoundRobinPool extends PoolBase {
111111
const client = this[kClients][this[kIndex]]
112112

113113
// Check if client is stale (TTL expired)
114-
if (clientTtlOption != null && clientTtlOption > 0 && client.ttl && ((Date.now() - client.ttl) > clientTtlOption)) {
114+
if (clientTtlOption != null && clientTtlOption > 0 && client.ttl && (client.ttl <= Date.now())) {
115115
this[kRemoveClient](client)
116116
checked++
117117
continue

test/node-test/agent.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,37 @@ test('Pool enforces maxIdle', async (t) => {
152152
await p.completed
153153
})
154154

155+
test('maxIdle respects clientTtl', async (t) => {
156+
const p = tspl(t, { plan: 1 })
157+
158+
const handler = (_req, res) => res.end('ok')
159+
const server = http.createServer({ joinDuplicateHeaders: true }, handler)
160+
server.listen(0)
161+
await once(server, 'listening')
162+
163+
const host = `http://localhost:${server.address().port}`
164+
const dispatcher = new Pool(host, {
165+
maxIdle: 3,
166+
clientTtl: 2000,
167+
keepAliveTimeout: 1000
168+
})
169+
170+
t.after(closeClientAndServerAsPromise(dispatcher, server))
171+
172+
await Promise.all([
173+
request(host, { dispatcher }),
174+
request(host, { dispatcher }),
175+
request(host, { dispatcher }),
176+
request(host, { dispatcher }),
177+
request(host, { dispatcher })
178+
])
179+
180+
await new Promise(resolve => setTimeout(resolve, 1))
181+
p.equal(dispatcher.stats.free, 5)
182+
183+
await p.completed
184+
})
185+
155186
test('agent should call callback after closing internal pools', async (t) => {
156187
const p = tspl(t, { plan: 2 })
157188

0 commit comments

Comments
 (0)