Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add tests and fix implementation
  • Loading branch information
tdeekens committed Apr 13, 2025
commit f2452c4f505f02e698253e9954bbb9f74e4c3312
9 changes: 4 additions & 5 deletions lib/dispatcher/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,13 @@ class Agent extends DispatcherBase {
}

get stats () {
Comment thread
tdeekens marked this conversation as resolved.
const stats = []
const allClientStats = []
for (const client of this[kClients].values()) {
const stats = client.stats
if (stats) {
stats.push([client[kUrl], stats])
if (client.stats) {
allClientStats.push([client[kUrl].origin, client.stats])
}
}
Comment thread
mcollina marked this conversation as resolved.
return stats
return allClientStats
}
}

Expand Down
4 changes: 4 additions & 0 deletions lib/dispatcher/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ class Client extends DispatcherBase {
this[kResume](true)
}

get stats () {
return this[kStats]
}

get [kPending] () {
return this[kQueue].length - this[kPendingIdx]
}
Expand Down
30 changes: 30 additions & 0 deletions test/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -2166,3 +2166,33 @@ test('\\n in Method', async (t) => {
t.strictEqual(err.message, 'invalid request method')
})
})

test('stats', async (t) => {
t = tspl(t, { plan: 3 })

const server = createServer({ joinDuplicateHeaders: true }, (req, res) => {
t.strictEqual('/', req.url)
t.strictEqual('GET', req.method)
t.strictEqual(`localhost:${server.address().port}`, req.headers.host)
res.setHeader('Content-Type', 'text/plain')
res.end('hello')
})
after(() => server.close())

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
after(() => client.close())

client.request({
path: '/',
method: 'GET'
}, (err, data) => {
t.ifError(err)
t.strictEqual(client.stats.connected, true)
t.strictEqual(client.stats.pending, 1)
t.strictEqual(client.stats.running, 1)
})
})

await t.completed
})
38 changes: 38 additions & 0 deletions test/node-test/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -808,3 +808,41 @@ test('the dispatcher is truly global', t => {
assert.ok(require.resolve('../../index.js') in require.cache)
assert.strictEqual(agent, undiciFresh.getGlobalDispatcher())
})

test('stats', async t => {
const p = tspl(t, { plan: 8 })
const wanted = 'payload'

const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => {
p.strictEqual('/', req.url)
p.strictEqual('GET', req.method)
res.end(wanted)
})

t.after(closeServerAsPromise(server))

const dispatcher = new Agent({
connect: {
servername: 'agent1'
}
})

server.listen(0, () => {
request(`http://localhost:${server.address().port}`, { dispatcher })
.then(({ statusCode, headers, body }) => {
p.strictEqual(statusCode, 200)
const agentStats = dispatcher.stats[0]
const [origin, stats] = agentStats
p.strictEqual(origin, `http://localhost:${server.address().port}`)
p.strictEqual(stats.connected, 1)
p.strictEqual(stats.pending, 0)
p.strictEqual(stats.running, 0)
p.strictEqual(stats.size, 0)
})
.catch(err => {
p.fail(err)
})
})

await p.completed
})
32 changes: 32 additions & 0 deletions test/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -1150,3 +1150,35 @@ test('pool destroy fails queued requests', async (t) => {
})
await t.completed
})

test('stats', async (t) => {
t = tspl(t, { plan: 11 })

const server = createServer({ joinDuplicateHeaders: true }, (req, res) => {
t.strictEqual('/', req.url)
t.strictEqual('GET', req.method)
res.setHeader('content-type', 'text/plain')
res.end('hello')
})
after(() => server.close())

server.listen(0, async () => {
const client = new Pool(`http://localhost:${server.address().port}`)
after(() => client.destroy())

t.strictEqual(client[kUrl].origin, `http://localhost:${server.address().port}`)

client.request({ path: '/', method: 'GET' }, (err, { statusCode, headers, body }) => {
t.ifError(err)
t.strictEqual(statusCode, 200)
t.strictEqual(client.stats.connected, 1)
t.strictEqual(client.stats.free, 0)
t.strictEqual(client.stats.pending, 0)
t.strictEqual(client.stats.queued, 0)
t.strictEqual(client.stats.running, 1)
t.strictEqual(client.stats.size, 1)
})
})

await t.completed
})