Comparing version 5.0.0 to 5.1.0
/// <reference types="node"/> | ||
import {Omit} from 'type-fest'; | ||
import {ListenOptions} from 'net'; | ||
@@ -4,0 +3,0 @@ |
44
index.js
'use strict'; | ||
const net = require('net'); | ||
class Locked extends Error { | ||
constructor(port) { | ||
super(`${port} is locked`); | ||
} | ||
} | ||
const lockedPorts = { | ||
old: new Set(), | ||
young: new Set() | ||
}; | ||
// On this interval, the old locked ports are discarded, | ||
// the young locked ports are moved to old locked ports, | ||
// and a new young set for locked ports are created. | ||
const releaseOldLockedPortsIntervalMs = 1000 * 15; | ||
// Lazily create interval on first use | ||
let interval; | ||
const getAvailablePort = options => new Promise((resolve, reject) => { | ||
@@ -25,3 +44,3 @@ const server = net.createServer(); | ||
module.exports = async options => { | ||
let ports = null; | ||
let ports; | ||
@@ -32,7 +51,26 @@ if (options) { | ||
if (interval === undefined) { | ||
interval = setInterval(() => { | ||
lockedPorts.old = lockedPorts.young; | ||
lockedPorts.young = new Set(); | ||
}, releaseOldLockedPortsIntervalMs); | ||
interval.unref(); | ||
} | ||
for (const port of portCheckSequence(ports)) { | ||
try { | ||
return await getAvailablePort({...options, port}); // eslint-disable-line no-await-in-loop | ||
let availablePort = await getAvailablePort({...options, port}); // eslint-disable-line no-await-in-loop | ||
while (lockedPorts.old.has(availablePort) || lockedPorts.young.has(availablePort)) { | ||
if (port !== 0) { | ||
throw new Locked(port); | ||
} | ||
availablePort = await getAvailablePort({...options, port}); // eslint-disable-line no-await-in-loop | ||
} | ||
lockedPorts.young.add(availablePort); | ||
return availablePort; | ||
} catch (error) { | ||
if (error.code !== 'EADDRINUSE') { | ||
if (!['EADDRINUSE', 'EACCES'].includes(error.code) && !(error instanceof Locked)) { | ||
throw error; | ||
@@ -39,0 +77,0 @@ } |
{ | ||
"name": "get-port", | ||
"version": "5.0.0", | ||
"version": "5.1.0", | ||
"description": "Get an available port", | ||
"license": "MIT", | ||
"repository": "sindresorhus/get-port", | ||
"funding": "https://github.com/sponsors/sindresorhus", | ||
"author": { | ||
@@ -39,11 +40,8 @@ "name": "Sindre Sorhus", | ||
], | ||
"dependencies": { | ||
"type-fest": "^0.3.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^11.13.0", | ||
"ava": "^1.4.1", | ||
"tsd": "^0.7.2", | ||
"xo": "^0.24.0" | ||
"@types/node": "^12.12.21", | ||
"ava": "^2.4.0", | ||
"tsd": "^0.11.0", | ||
"xo": "^0.25.3" | ||
} | ||
} |
@@ -5,3 +5,2 @@ # get-port [![Build Status](https://travis-ci.org/sindresorhus/get-port.svg?branch=master)](https://travis-ci.org/sindresorhus/get-port) | ||
## Install | ||
@@ -13,3 +12,2 @@ | ||
## Usage | ||
@@ -55,3 +53,3 @@ | ||
### getPort([options]) | ||
### getPort(options?) | ||
@@ -62,3 +60,3 @@ Returns a `Promise` for a port number. | ||
Type: `Object` | ||
Type: `object` | ||
@@ -95,7 +93,7 @@ ##### port | ||
## Beware | ||
There is a very tiny chance of a race condition if another service starts using the same port number as you in between the time you get the port number and you actually start using it. | ||
There is a very tiny chance of a race condition if another process starts using the same port number as you in between the time you get the port number and you actually start using it. | ||
Race conditions in the same process are mitigated against by using a lightweight locking mechanism where a port will be held for a minimum of 15 seconds and a maximum of 30 seconds before being released again. | ||
@@ -106,5 +104,12 @@ ## Related | ||
--- | ||
## License | ||
MIT © [Sindre Sorhus](https://sindresorhus.com) | ||
<div align="center"> | ||
<b> | ||
<a href="https://tidelift.com/subscription/pkg/npm-get-port?utm_source=npm-get-port&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a> | ||
</b> | ||
<br> | ||
<sub> | ||
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies. | ||
</sub> | ||
</div> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8629
0
136
110
- Removedtype-fest@^0.3.0
- Removedtype-fest@0.3.1(transitive)