From c9b2194cf87421ce879445b40b73a10d4d735714 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 1 Oct 2024 00:05:36 +0200 Subject: [PATCH] Fix a lock-up of the stats-getter For some reason, those promises never settle, so we end up stuck trying to load users. Provide our own timeout on top of it, so that we bail if this happens. --- src/pushStats/users.js | 43 +++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/pushStats/users.js b/src/pushStats/users.js index ef3b781..1ad2c9c 100644 --- a/src/pushStats/users.js +++ b/src/pushStats/users.js @@ -5,39 +5,52 @@ const SERVER_PORT = parseInt(/** @type {string} */ (process.env.SERVER_PORT), 10 /** * Check whether there's a server nearby - * @returns {Promise<[string, number]>} + * @returns {Promise<[string, number] | undefined>} */ async function checkLocalhostServer() { + console.log('Checking for local server'); const hosts = [ 'localhost', 'host.docker.internal', '172.17.0.1', ]; - /** @type {Promise<[string, number]>[]} */ + /** @type {Promise<[string, number] | undefined>[]} */ const promises = []; for (const host of hosts) { const p = new Promise((resolve, reject) => { const sock = new net.Socket(); - sock.setTimeout(2500); - console.log(`[${host}:${SERVER_PORT}] attempting connection`); + function kill() { + sock.removeAllListeners(); + sock.end(); + sock.destroy(); + sock.unref(); + } + sock.setTimeout(200); sock - .on('connect', () => { - sock.destroy(); + .once('connect', () => { + kill(); resolve([host, SERVER_PORT]); }) - .on('error', () => { - sock.destroy(); - reject(); + .once('error', () => { + kill(); + reject(new Error('Error connecting to server')); }) - .on('timeout', () => { - sock.destroy(); - reject(); + .once('timeout', () => { + kill(); + reject(new Error('Timeout connecting to server')); }) .connect(SERVER_PORT, host); }); promises.push(p); } - return Promise.any(promises); + promises.push(new Promise((resolve) => { setTimeout(() => resolve(undefined), 1000); })); + const server = await Promise.any(promises); + if (server) { + console.log(`Found server at ${server[0]}:${server[1]}`); + } else { + console.log('No server found'); + } + return server; } /** @@ -78,6 +91,9 @@ export default async function loadUsers() { if (!user.host) { try { if (user.type === 'private') { + if (!localServer) { + throw new Error('no local server available, and host unspecified'); + } [user.host, user.port] = localServer; } else { [user.host, user.port] = getHostInfoFromType(user.type); @@ -101,5 +117,6 @@ export default async function loadUsers() { } validUsers.push(user); } + console.log(`Loaded ${validUsers.length} users (out of ${users.length})`); return validUsers; }