diff --git a/index.js b/index.js index 7451574..8938ae2 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,10 @@ 'use strict'; const net = require('net'); +const used = { + old: new Set(), + young: new Set() +}; const getAvailablePort = options => new Promise((resolve, reject) => { const server = net.createServer(); server.unref(); @@ -23,14 +27,24 @@ const portCheckSequence = function * (ports) { module.exports = async options => { let ports = null; - + const sweep = 1000 * 15; if (options) { ports = typeof options.port === 'number' ? [options.port] : options.port; } + const interval = setInterval(() => { + used.old = used.young; + used.young = new Set(); + }, sweep); + interval.unref(); for (const port of portCheckSequence(ports)) { try { - return await getAvailablePort({...options, port}); // eslint-disable-line no-await-in-loop + let p = await getAvailablePort({...options, port}); // eslint-disable-line no-await-in-loop + while (used.old.has(p) || used.young.has(p)) { + p = await getAvailablePort({...options, port}); // eslint-disable-line no-await-in-loop + } + used.young.add(p); + return p; } catch (error) { if (error.code !== 'EADDRINUSE') { throw error; diff --git a/test.js b/test.js index 65f4ab7..15668df 100644 --- a/test.js +++ b/test.js @@ -44,7 +44,7 @@ test('port can be bound to IPv4 host when promise resolves', async t => { }); test('preferred port given IPv4 host', async t => { - const desiredPort = 8080; + const desiredPort = 8081; const port = await getPort({ port: desiredPort, host: '0.0.0.0'