import { test } from '@japa/runner' import net from 'node:net' import env from '#start/env' import coordinatorConfig from '#config/coordinator' import pool from '#services/nntp_pool' import type { NntpShare } from '#services/nntp_shares' /** A tiny NNTP server that only logs in, counting the connections open. */ function server(): Promise<{ port: number; open: () => number; close: () => void }> { return new Promise((resolve) => { let open = 0 const srv = net.createServer((sock) => { open++ sock.on('close', () => open--) sock.write('200 welcome\r\n') sock.on('data', (chunk) => { for (const line of chunk.toString().split('\r\n')) { if (line.startsWith('AUTHINFO USER')) sock.write('381 more\r\n') else if (line.startsWith('AUTHINFO PASS')) sock.write('281 ok\r\n') else if (line === 'XFEATURE COMPRESS GZIP') sock.write('290 Feature Enabled\r\n') else if (line === 'QUIT') sock.end('205 bye\r\n') } }) }) srv.listen(0, '127.0.0.1', () => resolve({ port: (srv.address() as net.AddressInfo).port, open: () => open, close: () => srv.close(), }) ) }) } const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)) const share = { sync: async () => 4 } as unknown as NntpShare test.group('nntp / pool', () => { test('a connection free for nntpIdleCloseMs closes on the next sync; one used since stays', async ({ assert, cleanup, }) => { const { port, open, close } = await server() const idleCloseMs = coordinatorConfig.nntpIdleCloseMs env.set('NNTP_HOST', '127.0.0.1') env.set('NNTP_PORT', port) env.set('NNTP_SECURE', false) coordinatorConfig.nntpIdleCloseMs = 100 cleanup(async () => { coordinatorConfig.nntpIdleCloseMs = idleCloseMs await pool.close() close() }) await pool.share(share) // Two at once: two connections. await Promise.all([pool.use(() => sleep(20)), pool.use(() => sleep(20))]) assert.equal(open(), 2) await sleep(150) // One used again: the other has been free for longer than 100 ms. await pool.use(async () => {}) await pool.share(share) await sleep(50) assert.equal(open(), 1) await sleep(150) await pool.share(share) await sleep(50) assert.equal(open(), 0) }) })