Comparing version 0.0.4 to 0.1.0
82
index.js
@@ -7,10 +7,25 @@ 'use strict'; | ||
// Store picked ports for the specified 'reserveTimeout' time. | ||
const reserved = | ||
{ | ||
'udp' : new Set(), | ||
'tcp' : new Set() | ||
}; | ||
const defaultOptions = | ||
{ | ||
type : 'udp', | ||
ip : '127.0.0.1', | ||
port : 0, | ||
range : {} | ||
type : 'udp', | ||
ip : '127.0.0.1', | ||
port : 0, | ||
range : {}, | ||
reserveTimeout : 5 | ||
}; | ||
const reserve = function(type, port, timeout) | ||
{ | ||
reserved[type].add(port); | ||
setTimeout(() => reserved[type].delete(port), timeout * 1000); | ||
}; | ||
const getPort = (options) => new Promise((resolve, reject) => | ||
@@ -26,6 +41,5 @@ { | ||
{ | ||
reserve(options.type, port, options.reserveTimeout); | ||
resolve(port); | ||
return; | ||
}) | ||
@@ -35,6 +49,5 @@ .catch((error) => | ||
reject(error); | ||
}); | ||
return; | ||
}); | ||
return; | ||
} | ||
@@ -51,37 +64,39 @@ | ||
options.port = range.min; | ||
// Take a random port in the range. | ||
options.port = Math.floor( | ||
Math.random() * ((range.max + 1) - range.min)) + range.min; | ||
const pickPort = () => | ||
{ | ||
options.port++; | ||
// Keep the port within the range. | ||
if (options.port > range.max) | ||
options.port = range.min; | ||
// Try picking a free port for as many times as the number of | ||
// ports within the range. | ||
if (retries++ > (range.max - range.min)) | ||
return reject(new Error('All ports in the given range are in use')); | ||
// The port is reserved, try with another one. | ||
if (reserved[options.type].has(options.port)) | ||
return pickPort(); | ||
// The port is not reserved try to bind it. | ||
handler(options) | ||
.then((port) => | ||
{ | ||
// Free. reserve it. | ||
reserve(options.type, port, options.reserveTimeout); | ||
resolve(port); | ||
return; | ||
}) | ||
.catch((error) => | ||
{ | ||
// In use, try with another one. | ||
if (error.code === 'EADDRINUSE') | ||
{ | ||
if (++retries <= range.max - range.min) | ||
{ | ||
options.port++; | ||
pickPort(); | ||
} | ||
else | ||
{ | ||
reject(new Error('All ports in the given range are in use')); | ||
return; | ||
} | ||
} | ||
pickPort(); | ||
else | ||
{ | ||
reject(error); | ||
return; | ||
} | ||
}); | ||
@@ -112,2 +127,5 @@ }; | ||
if (typeof options.reserveTimeout !== 'number') | ||
return Promise.reject(new Error('Invalid parameter: "reserveTimeout"')); | ||
const range = options.range; | ||
@@ -114,0 +132,0 @@ |
{ | ||
"name": "pick-port", | ||
"version": "0.0.4", | ||
"version": "0.1.0", | ||
"description": "Get a free TCP or UDP port for the given IP address", | ||
@@ -5,0 +5,0 @@ "author": "José Luis Millán <jmillan@aliax.net> (https://github.com/jmillan)", |
@@ -14,3 +14,2 @@ | ||
console.log(port); | ||
//=> 34323 | ||
}); | ||
@@ -26,3 +25,6 @@ ``` | ||
console.log(port); | ||
//=> 8000 if the given port if free to use, otherwise the corresponding exception is thrown | ||
}) | ||
.catch((error) => | ||
{ | ||
console.log(error); | ||
}); | ||
@@ -36,4 +38,6 @@ ``` | ||
Returns a `Promise` for a port number. | ||
Returns a `Promise`. | ||
Resolves with the free port number on success or throws if error or no free ports in the given range are available. | ||
#### options | ||
@@ -43,37 +47,49 @@ | ||
##### type | ||
##### options.type | ||
Type: `string` | ||
TCP/IP family type. Possible values for this parameter are 'udp' and 'tcp'. | ||
TCP/IP family type. Options for this parameter are 'udp' and 'tcp'. Default value is 'udp'. | ||
* Type: `String`. | ||
* Default value: 'udp'. | ||
##### port | ||
##### options.port | ||
Type: `number` | ||
Specific port to be checked or 0 to specify that any free port can be taken. | ||
Specific port to be checked. Default value is 0, which means that any free port can be taken. | ||
* Type: `Number`. | ||
* Default value: 0. | ||
##### range | ||
##### options.range | ||
Type: `object` | ||
The port range for which a free port is requested. If specified, only ports in the given range are considered. | ||
The port range for which a free port is requested. If specified, only ports in the given range are considered. It is unset by default. | ||
* Type: `Object`. | ||
* Default value: undefined. | ||
###### range.min | ||
###### options.range.min | ||
Type: `number` | ||
The minimum port number in the range. | ||
###### range.max | ||
* Type: `Number` | ||
Type: `number` | ||
###### options.range.max | ||
The maximum port number in the range. | ||
##### ip | ||
* Type: `Number`. | ||
Type: `string` | ||
##### options.ip | ||
The IP address for which a free port is requested. IPv4 and IPv6 addressing is supported. | ||
Default value is '127.0.0.1'. | ||
* Type: `String`. | ||
* Default value: '127.0.0.1'. | ||
##### options.reserveTimeout | ||
Timeout in seconds, during which a returned free port will be internally reserved and prevented of being returned on a future call before the timeout has elapsed. | ||
This provides the application using this library with the required time to bind the free port before it is given again on a future call. | ||
* Type: `Number`. | ||
* Default value: 5. |
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
11387
345
92