const http = require('http');
const https = require('https');
const { performance } = require('perf_hooks');
// Configuration
const TEST_SERVER_PORT = 3006;
const NUM_REQUESTS = 5;
const TARGET_URL = `http://localhost:${TEST_SERVER_PORT}`;
// Create a test server
const server = http.createServer((req, res) => {
// Simulate some server processing time
setTimeout(() => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
url: req.url,
method: req.method,
timestamp: new Date().toISOString(),
connection: {
localPort: req.socket.localPort,
remotePort: req.socket.remotePort,
remoteAddress: req.socket.remoteAddress
}
}));
}, 50); // 50ms delay to simulate processing
});
// Start the test server
server.listen(TEST_SERVER_PORT, 'localhost', async () => {
console.log(`Test server running at http://localhost:${TEST_SERVER_PORT}`);
try {
// Test without connection pooling (new agent per request)
console.log('\n=== Testing WITHOUT connection pooling (new agent per request) ===');
await testRequests(false);
// Test with connection pooling (reusing the same agent)
console.log('\n=== Testing WITH connection pooling (reusing agent) ===');
await testRequests(true);
} catch (err) {
console.error('Test error:', err);
} finally {
// Close the server when done
server.close(() => {
console.log('\nTest server closed');
});
}
});
// Handle server errors
server.on('error', (err) => {
console.error('Server error:', err);
});
/**
* Test making multiple requests with or without connection pooling
*/
async function testRequests(useConnectionPooling) {
const agent = useConnectionPooling ? new http.Agent({ keepAlive: true, maxSockets: 5 }) : null;
const requestPromises = [];
const startTime = performance.now();
console.log(`\nMaking ${NUM_REQUESTS} requests...`);
for (let i = 0; i < NUM_REQUESTS; i++) {
const requestPromise = new Promise((resolve, reject) => {
const options = {
hostname: 'localhost',
port: TEST_SERVER_PORT,
path: `/api/resource/${i + 1}`,
method: 'GET',
agent: useConnectionPooling ? agent : undefined
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
const response = JSON.parse(data);
console.log(`Request ${i + 1}: ${response.connection.remotePort} (${res.statusCode})`);
resolve();
});
});
req.on('error', (err) => {
console.error(`Request ${i + 1} error:`, err.message);
reject(err);
});
req.end();
});
requestPromises.push(requestPromise);
// Add a small delay between requests to better demonstrate the effect
await new Promise(resolve => setTimeout(resolve, 10));
}
// Wait for all requests to complete
await Promise.all(requestPromises);
const endTime = performance.now();
const duration = (endTime - startTime).toFixed(2);
console.log(`\nCompleted ${NUM_REQUESTS} requests in ${duration}ms`);
// Log agent stats if using connection pooling
if (useConnectionPooling && agent) {
console.log('\nAgent stats:');
console.log('Free sockets:', Object.keys(agent.freeSockets).length);
console.log('Active sockets:', Object.keys(agent.sockets).length);
// Destroy the agent to clean up
agent.destroy();
}
}