GithubHelp home page GithubHelp logo

http-party / node-portfinder Goto Github PK

View Code? Open in Web Editor NEW
874.0 874.0 94.0 187 KB

A simple tool to find an open port or domain socket on the current machine

Home Page: https://github.com/http-party/node-portfinder

License: Other

JavaScript 100.00%

node-portfinder's People

Contributors

brunogaspar avatar cades avatar chyzwar avatar dcharbonnier avatar dependabot[bot] avatar dguettler avatar eriktrom avatar indexzero avatar inlined avatar jj avatar jonluca avatar jucrouzet avatar kayakyakr avatar kemitchell avatar kiwiupover avatar kwiatkk1 avatar kylev avatar lostinbrittany avatar masterodin avatar mmalecki avatar msbit avatar nairboon avatar ni-kit avatar pimterry avatar prithvirajbilla avatar rgbkrk avatar selfcontained avatar tomhughes avatar winfinit avatar xiaofan9 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-portfinder's Issues

Sync Chat

@indexzero - do we have a synchronous way to chat - for community members who seem to be becoming more interested in this project, a way to chat seems reasonable. (not a lot of people but atm, it's hard to directly chat with anyone, non async).

slack, gitter, discord - does http-party team such a thing?

(if not, should I set it up, if so, preference?)

Return with a range of free ports

I want to spin up two servers. So I run two getPorts. However, the servers step on each other.

portfinder = require("portfinder");

portfinder.getPort(function(err1,port1){
  portfinder.getPort(function(err2, port2){
    console.log("Port1 = " + port1 + ", Port2 = " + port2);
  });
});

outputs:
"Port1 = 8000, Port2 = 8000"

Add Changelog and Release Tool

Add changelog and release tool (it should give credit to author, provide link to the pr merged, with description (ideally pr title, which means the only thing we need to manually ensure is that PR titles are accurate descriptions prior to merge)

  • Note that if you choose a tool, please see http-party/node-http-proxy#1383 -- if the tool works across all http-party org repos, that is highly ideal.
    • when choosing a tool, unless your well versed and have no reservations, please drop a note on the aforementioned meta issue(http-party/node-http-proxy#1383) so that the whole org is on board.
    • If you write one from scratch, and it's good/fulfills needs, while I can't speak for the org, I personally believe you would become the maintainer if the tool becomes part of the org, making this a enticing issue to tackle. that said, there are many such tools, re-invent if you want, but copy ideas from other node changelog release tools to gain experiential knowledge and ideas. (in other words, if you don't think a new changelog/release tool that can be used widely and has potential to gain large nodejs community momentum, don't write your own. However, if your frustrated with most of the tools out there, go for it. I have not looked, so I'm leaving this research and dev up to the contributor who tackles this.

Note, while the pr for the tool can be submitted here, once approved and discussed, it will need to be added to all http-party repos. If it's a re-written/re-invent the wheel new lib, it'll need it's own repo, in which case, you can point to your personal github for discussion and we'll transfer ownership, upon approval of all http-party maintainers.

(1/10 or 1/100 chance of writing a new tool and succeeding, so make it a code kata, not and end all goal, just fyi, for your sanity, friends, don't get your hopes up too high. again i don't know what else is out there atm though...)


Addresses a bullet in #92


EDIT: Look into github packages: https://docs.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-npm-for-use-with-github-packages ?

Doesn't seem to work

I'm trying to run multiple instances of Express and while one receives port 80 (defined as base-port) the other (I'm testing with just two instances atm) also receives 80 from portfinder (despite already taken). Bug or am I doing something wrong?

Breaking pipes

Related:
nodejs/node-v0.x-archive#1331

Right now the domain socket checking in port finder is sometimes (seems close to always?) clobbering open domain sockets and causing broken pipes on connections that were listening to the existing socket.

Replace sequential scan with random search

Instead of scanning from the base port to the highest port, a randomized search would be more robust. Currently, if I am launching several servers in quick succession, there can be port collisions because one server may not have finished binding to the port discovered by portfinder before the next call to getPort, which then considers the same port to still be unbound.

The specified port is invalid and is always a random port

The specified port is invalid and is always a random port.
I found this bug on line 159 of "protfinder.js"
You can do it this way:

var candidatePorts = []
  for (i = options.port; i < options.stopPort; i++) {
    candidatePorts.push(i)
  }
  randomShuffle(candidatePorts);

  candidatePorts.push(options.port);    //Inserts the current port into the end of the array

[email protected] returns random port (Docker examples)

Something changed that is causing portfinder to return random ports instead of the requested port which is open:

docker run --rm -it node:10.16.3 bash
root@0ba5c01217f7:/# npm install [email protected]
npm WARN saveError ENOENT: no such file or directory, open '/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/package.json'
npm WARN !invalid#1 No description
npm WARN !invalid#1 No repository field.
npm WARN !invalid#1 No README data
npm WARN !invalid#1 No license field.

+ [email protected]
added 6 packages from 6 contributors and audited 6 packages in 0.999s
found 0 vulnerabilities

root@0ba5c01217f7:/# node
> const PortFinder = require('portfinder');
undefined
> PortFinder.getPort({port: 4200, host: 'localhost'}, function(err, port) {console.debug(`err = ${err}, port = ${port}`)});
undefined
> err = null, port = 21663

> PortFinder.getPort({port: 4200, host: 'localhost'}, function(err, port) {console.debug(`err = ${err}, port = ${port}`)});
undefined
> err = null, port = 26449

Here is the same code running successfully with [email protected]:

docker run --rm -it node:10.16.3 bash
root@55537e7efc22:/# npm install [email protected]
npm WARN saveError ENOENT: no such file or directory, open '/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/package.json'
npm WARN !invalid#1 No description
npm WARN !invalid#1 No repository field.
npm WARN !invalid#1 No README data
npm WARN !invalid#1 No license field.

+ [email protected]
added 6 packages from 6 contributors and audited 6 packages in 1.023s
found 0 vulnerabilities

root@55537e7efc22:/# node
> const PortFinder = require('portfinder');
undefined
> PortFinder.getPort({port: 4200, host: 'localhost'}, function(err, port) {console.debug(`err = ${err}, port = ${port}`)});
undefined
> err = null, port = 4200

> PortFinder.getPort({port: 4200, host: 'localhost'}, function(err, port) {console.debug(`err = ${err}, port = ${port}`)});
undefined
> err = null, port = 4200

Breaking change in 1.0.22 if port is > 40000 and stopPort is not set

Default highest port was reduced in #82 from 65535 to 40000. This was discussed in #82 (comment) and explicitly stated to be done to not introduce a breaking change. But it has indeed if getPort() is called with port > 40000 and without stopPort and without overriding portfinder.highestPort before. E.g. this usage:

portfinder.getPort({
    port: 49741
}, callback);

throws

Provided options.stopPort(40000is less than options.startPort (49741)

Noticed this breaking change by failing tests that depend on tomdale/ember-cli-addon-tests#212.

It simply doesn't work for me. it always give me 800.

However, this simple code does work:
export function findFreePort() { return new Promise((resolve, reject) => { var server = createServer() , port = 0 server.on("listening", function () { port = server.address().port server.close() }) server.on("close", function () { resolve(port) }) server.on('error', function (err) { reject(err) }) server.listen(0, '127.0.0.1') }) }

v1.0.8 defaultHosts not finding 0.0.0.0

Somewhat recently npm install portfinder started giving us a version 1.0.8 (which strangely doesn't exist here on the github site). We're using it as part of ember-cli. When we spin up a server locally with portfinder debugging turned on we can see:

portfinder:defaultHosts exports._defaultHosts is: ['::1', '127.0.0.1', <public_ip>, <vpn_ip> ]

Where it used to be:

portfinder:defaultHosts exports._defaultHosts is: [ '0.0.0.0', '::1', '127.0.0.1', <public_ip>, <vpn_ip>]

The omission is causing ember to try and serve the app on the ip_address:port instead of at localhost:port which, due to VPN stuff, isn't working.

Is this a deliberate omission?

Before filing a socket not closed issue: understanding async I/O + ordering + OS differences + stability requirements

write contributor guidelines, including emphasis on development of port finding:

  • stability over speed,
  • stability over features that don't serve the larger portion of the consumer base (aka, wrap this lib if you want to extend it, provide examples and how to's for those in need).
  • edge cases (per OS, mentioned many times in discussion, but mainly 1) macOS touch bar takes ports 40,000-60,000, so exclude those) 2) Windows (in the past) has allowed port rebinding
  • How to wrap portfinder for your own custom need (in order to leave this lib encapsulated to one task that is done well (unix/substack philosophy).

Summary: (from #105 (comment))

Here is what I would consider:

not modifying this library, except under one circumstance
that another library, call it portlocker™️, that wraps port finder to find a port, but then also maintains that open socket, which can then be used via a callback
--
Reasoning:

We have no idea how this lib is being consumed - with 7+ million npm downloads a week, we don't want to break anything nor anyones expectations of its current behavior

Such a library, like portlocker™️, can then do one thing and do it well - handle the happens before ordering of async i/o scheduling. This would allow risk free iteration on current and future needs, anything from single threaded async i/o to multi (worker or process) async i/o could be explored. There has been some interest in this by others, in various forms, none of which are core to portfinder's original goals or intents, but which could easily consume portfinder and add such things.

If this proposal gains traction, I will consider. Provide a 👍, and I'll tally the priority and interest.>

Keeps the comments light, but feel free to weigh in

better docs

great tool, thanks for the code but i had to find out myself by navigating your source that it does have option to define preferred port. Please add at least config options to readme.

const preferredPort = process.env.PORT || 3003;
portfinder.getPortPromise({port: preferredPort})
  .then((port) => {
...

Port in TIME_WAIT state should not be returned

I used portfinder.getPortPromise({port: startRangePortToUse}) in order to get free port but getPortPromise does not filter out ports stuck in TIME_WAIT status -which mean that the port is not really "free"

can't find correct port in window 10

node : v8.9.4
window10

when start server(http or socket) without host binding , i find module can't detect the port is using .

## server
var http = require('http');
var server = http.createServer(function(req, resp) {
  resp.end('hello');
})
server.listen(8080); // no host 

## test 
var portfinder = require('portfinder');
portfinder.basePort = 8080;
portfinder.getPort(function (err, port) {
  console.log(port); // return 8080 in window10 
});

and it work well in macos and linux.

How can I call getPort() and just have it return an open port?

Hi,

I'm afraid this is an extremely stupid question, but I'm coming at this with a Pythonic brain and I can't figure out from your documentation how I'm supposed to return an openPort from a call to getPort without having to rearrange all of my code inside of its scope.

Join http-party Github organization

Over the years I've contributed to / started / taken over several of TCP / HTTP(S) related node libraries. Each of these libraries has matured and gotten a set of independent maintainers – each with their own ebb & flow of maintenance.

In an effort to make maintaining all of these easier I created the http-party Github organization which I would like to add this project to.

I've invited the current maintainer, @eriktrom, to the org and unless he feels strongly it should stay here once he accepts I'll migrate the repository over.

All ports lower than 1024 are closed

I'm trying to inspect if port 123 (NTP Server) is available but I only get as response 1024 (that's the next available port) or if I use stopPort (and startPort) I receive an error: 'No open ports found in between XX and YY'.

I have tested some ports lower than 1024 and all of them either returns 1024 or an error. Any idea why or a possible solution?

image

Find port on remote machine

Would be curious if this can be adapted to find an available port on a remote machine, rather than localhost.

Option to provide a blacklist of ports while finding available port.

I am running into scenario where it would be nice to have a blacklist of ports (which should not be returned by portfinder, even if there are available).

I am not sure how to achieve this.

Let me know what you think of adding this option to the current api.

happy to submit a PR.

Why don't use net.connect

I use net.connect() to write same function. It is faster than use net.createServer.

const net = require('net');

exports.basePort = 8000
exports.highestPort = 65535

let port = exports.basePort
const internals = {}

internals.nextPort = () => {
    port++
    return port
}


exports.getPort = (callback) => {
    const c = net.connect({ port }, '127.0.0.1')
    c.once('error', (e) => {
        callback(null, port)
    })
    c.once('connect', () => {
        c.destroy();
        if (port < exports.highestPort) {
            port = internals.nextPort()
            exports.getPort(callback)
        } else {
            callback(new Error('No open ports available'));
        }
    })
}

image

can i disable the options.startPort >1024 check?

when i developing front end pages,i usually set webpack dev port to 80,with hosting 127.0.0.1:80 to a fake
domain,because some modules need to validate the domain name ,such as login module,so i think it would be more easy to use if this '1024' check can be disabled or default disabled.
Still thanks for this awesome module.

Correctly catch EADDRNOTAVAIL

largely copied from ember-cli/ember-cli#6083

  • In portfinder 1.0.3 there we're 2 issues
    1. Starting in a recent version of MacOS the interfaces that will bind when starting a node server grew dramatically. To solve this portfinder 1.0.4 uses the built in node method os.networkInterfaces(), loops through the hosts found and (semi-smartly) filters out the hosts that are bindable.
    2. People wanted this to work within a VM. In other words, if running a VM that is bound to a shared or host only interface, handle accordingly(this is the same issue really as the mac os issue, so I wont elaborate)
  • in portfinder 1.0.4 a new issue arrises, mainly the conjunction of:
    1. the netmask 255.255.255.0 was used in conjunction with internal: true when looping through os.networkInterfaces() to find hosts that will bind.
    2. When that netmask does not represent the 'what is bindable for a given computer' and when err.address is not available, a server will not start. (whether those two are related is YTBD)

I need to look back through the issue list as there was a similar issue about when err.address was and was not being thrown that came up previously.

Free port still in use

Hello together,

I am facing the problem that portfinder is blocking a free port because the callback is called directly after calling server.close().

The problem is that server.close() is an asynchronous operation and as long as the close event is not emitted the port is still used by the server (Node API docs: https://nodejs.org/docs/latest/api/net.html#net_server_close_callback):

server.close([callback])[src]#
Added in: v0.1.90
callback <Function> Called when the server is closed
Returns: <net.Server>
Stops the server from accepting new connections and keeps existing connections.
This function is asynchronous, the server is finally closed when all connections are
ended and the server emits a 'close' event. The optional callback will be called once
the 'close' event occurs. Unlike that event, it will be called with an Error as its only
argument if the server was not open when it was closed.

This is where the problem happens:
https://github.com/http-party/node-portfinder/blob/master/lib/portfinder.js#L42

With regards,
Stefan

Not detecting touchbar macbook pro process

Related to ember-cli/ember-cli#6513

It seems that the new Touchbar Macbook Pros use port 49152 for something related to the touchbar. portfinder still returns this port as available when it's in use by (what we think is) the touchbar.

> sudo lsof -i:49152
COMMAND  PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
eoshostd 183 root    3u  IPv6 0x6598d6d8df58d085      0t0  TCP [fe80:4::aede:48ff:fe00:1122]:49152->[fe80:4::aede:48ff:fe33:4455]:61000 (ESTABLISHED)
> portfinder.getPort(console.log)
undefined
> null 49152

> portfinder.getPort({ host: '0.0.0.0' }, console.log)
undefined
> null 49152

> portfinder.getPort({ host: 'localhost' }, console.log)
undefined
> null 49152

# Seems to work when the host from above is specified
> portfinder.getPort({ host: 'fe80:4::aede:48ff:fe00:1122' }, console.log)
undefined
> null 49153

portfinder yields a port that is already in use

So, this issue might be related to #9. I'm seeing this on Mac OS X:

~/.local/android-sdk-macosx/platform-tools/adb forward --list
3739ced5 tcp:8000 localfilesystem:/data/local/debugger-socket
➜  curl http://127.0.0.1:8000
(expected output from the android device)
➜  node -e 'require("portfinder").getPort(console.log)'
null 8000

In other words, I have port 8000 forwarded to an Android device via adb and there's a service running that responds to curl. But, portfinder does not detect it, and it offers 8000 as a free port.

This doesn't seem limited to adb. Per #9, I tried running a PHP dev server and got similar results:

➜ php -S 127.0.0.1:8000
PHP 5.5.14 Development Server started at Thu Mar 19 15:41:33 2015
Listening on http://127.0.0.1:8000
Document root is /Users/lmorchard/devel/mozilla/node-firefox/node-firefox-forward-ports
Press Ctrl-C to quit.

(switch to another shell)

➜ curl -si http://127.0.0.1:8000 | head -1
HTTP/1.1 404 Not Found
➜ node -e 'require("portfinder").getPort(console.log)'
null 8000

In other words, there's an HTTP server running on port 8000 via php -S and it responds to curl. But, portfinder offers up its port as free.

But then, for the hell of it, I tried running a SimpleHTTPServer with Python.

This time, portfinder worked as expected:

➜ python -m'SimpleHTTPServer'
Serving HTTP on 0.0.0.0 port 8000 ...

(switch to another shell)

➜ curl -si http://127.0.0.1:8000 | head -1
HTTP/1.0 200 OK
➜ node -e 'require("portfinder").getPort(console.log)'
null 8001

So, I guess I'm wondering what are adb and php doing differently from the Python server that causes portfinder to not detect the occupied port?

Expose testPort to public

Hi @indexzero and thanks for the great job !

It would be nice to export testPort.

Why ?
I'am using node-portfinder to start a web server. I'd like to use testPort to regulary check if the port is in use to know when the web server is up.

It would be much nicer to listen for a specific signal of the child process, but all web server does not implement it.

If you like the idea, I can make a PR

Encountered an error when host [::]

When i run the code , i get the result is 8080;

portfinder.basePort = 8080; //set basePort = 8080
portfinder.getPort(function(err , port){
    console.log(port);
   //return 8080
})

here is log

in eachSeries() iteration callback: host is 0.0.0.0
in eachSeries() iteration callback: host is 0.0.0.0
entered testPort(): trying 0.0.0.0 port 8080
done w/ testPort(): OK 0.0.0.0 port 8080
in eachSeries() iteration callback testPort() callback with a success for port 8080
in eachSeries() iteration callback: host is fe80::15d0:1e6b:e232:f2b3
in eachSeries() iteration callback: host is fe80::15d0:1e6b:e232:f2b3
entered testPort(): trying fe80::15d0:1e6b:e232:f2b3 port 8080
done w/ testPort(): OK fe80::15d0:1e6b:e232:f2b3 port 8080
in eachSeries() iteration callback testPort() callback with a success for port 8080
in eachSeries() iteration callback: host is 10.1.113.89
in eachSeries() iteration callback: host is 10.1.113.89
entered testPort(): trying 10.1.113.89 port 8080
done w/ testPort(): OK 10.1.113.89 port 8080
in eachSeries() iteration callback testPort() callback with a success for port 8080
in eachSeries() iteration callback: host is ::1
in eachSeries() iteration callback: host is ::1
entered testPort(): trying ::1 port 8080
done w/ testPort(): OK ::1 port 8080
in eachSeries() iteration callback testPort() callback with a success for port 8080
in eachSeries() iteration callback: host is 127.0.0.1
in eachSeries() iteration callback: host is 127.0.0.1
entered testPort(): trying 127.0.0.1 port 8080
done w/ testPort(): OK 127.0.0.1 port 8080
in eachSeries() iteration callback testPort() callback with a success for port 8080
in eachSeries() result callback: openPorts is [ 8080, 8080, 8080, 8080, 8080 ]

Here is my system net information

>node
> os.networkInterfaces()
{ '以太网':
   [ { address: 'fe80::15d0:1e6b:e232:f2b3',
       netmask: 'ffff:ffff:ffff:ffff::',
       family: 'IPv6',
       mac: '08:9e:01:d0:95:14',
       scopeid: 17,
       internal: false },
     { address: '10.1.113.89',
       netmask: '255.255.255.0',
       family: 'IPv4',
       mac: '08:9e:01:d0:95:14',
       internal: false } ],
  'Loopback Pseudo-Interface 1':
   [ { address: '::1',
       netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
       family: 'IPv6',
       mac: '00:00:00:00:00:00',
       scopeid: 0,
       internal: true },
     { address: '127.0.0.1',
       netmask: '255.0.0.0',
       family: 'IPv4',
       mac: '00:00:00:00:00:00',
       internal: true } ] }

but the 8080 Port is occupied

PS D:\> netstat -ano | findstr "8080"
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING       54108
  TCP    [::]:8080              [::]:0                 LISTENING       54108
  TCP    [::1]:8080             [::1]:51001            ESTABLISHED     54108
  TCP    [::1]:8080             [::1]:51544            ESTABLISHED     54108
  TCP    [::1]:51001            [::1]:8080             ESTABLISHED     11256
  TCP    [::1]:51544            [::1]:8080             ESTABLISHED     11256

and there have a host [::] , then i change the code portfinder.js

//line 444 , insert "::" to the array
      results = [hiddenButImportantHost , '::'];

it's OK and Get the right results I want 8081

i don't know why , but i think it's the ipv6 address of '0.0.0.0'

      hiddenButImportantHost = '0.0.0.0', // !important - dont remove, hence the naming :)

and how fix it?

Does not work if the given base port is already taken

The test script below allocates port 3000, then calls portfinder with basePort set to 3000.
With the old version 0.4.0 it works correctly, i.e. prints "1 2 3".
With portfinder 1.0.0., it does not output "3", i.e. it never calls the callback given to getPort.

http = require('http');
portfinder = require('portfinder');
handler = function(_, res) {
  return res.end('existing server');
};

console.log(1);
server = http.createServer(handler).listen(3000, 'localhost', function() {
  console.log(2);
  portfinder.basePort = 3000;
  portfinder.getPort(function(err, port) {
    console.log(3);
  });
});

My setup:

  • OS X 10.11.3
  • Node v5.3.0

Request release sources on github also

tarballs uploaded in npmjs does not contain any tests directory and I need them for Fedora packaging. Therefore I generally pick tarballs from github only. This project does not contain any recent tarballs.

Can you please release the recent release tarball?

Create code of conduct

We don't have a code of conduct, free speech welcome, but derogatory comments towards individuals (not ideas) will not be tolerated.

  • Make a code of conduct file, follow community norms (ideally, I like the way rust has handled this, see their's. Copy it or similar).

Comment - Semantic Versioning

@eriktrom Thanks for giving this package some attention. The 1.0.8 patch release was a bit unfortunate. I would argue that in the future things like the windows 10 support work should bump the minor and not the patch part of the version number.

Thanks again!

1.0.1 breaks with EADDRNOTAVAIL

On updating to 1.0.1 of portfinder, I started getting the following error:

{ [Error: listen EADDRNOTAVAIL ::1:8000]
  code: 'EADDRNOTAVAIL',
  errno: 'EADDRNOTAVAIL',
  syscall: 'listen',
  address: '::1',
  port: 8000 }

Reverting to 1.0.0 fixes the issue.

stopPort is now exclusive since 1.0.22 (Breaking change?)

Before, if stopPort is 9000, portfinder will try up to 9000 and see if it is open. With the new 1.0.22 release, portfinder seems to exclude 9000. This is seen in the code to generate candidatePorts, where it now reads i < options.stopPort instead of <=.

This is especially troublesome in firebase-tools, where we use the same port and stopPort (effectively only check if a single port number is open or not). The change in 1.0.22 completely broke firebase-tools where portfinder is used. See
firebase/firebase-tools#1606 (comment)

Discussion: portfinder v2, foster community, docs and general guidelines

This issue serves to document features requested by community members, and how we should manage such needs.

tl;dr - this lib at v1 is largely frozen, code wise. It needs major help though with communication of it's intent and guidelines for extending it for individual use cases.

The following outlines those current needs. At the bottom I've added some notes about v2, however unlikely it is to happen. (I'd rather call into this lib than change its implementation as well, if possible for the last bullet under v2 section, meaning contributors should consider this the norm when thinking about their use individual use cases, given I'm thinking about it for the general use case mentioned in that bullet, due to minut edge cases currently encoded into the logic of the current stable release. FYI - i'm not rejecting ideas, just working on how to allow them by extension, not modification, of this lib. Ideas welcome).

Current Needs:

  • write docs, including emphasis on development port finding, stability over speed, and stability over features that don't serve the larger portion of the consumer base (aka, wrap this lib if you want to extend it, provide examples and how to's for those in need).

  • Foster community involvement, be kind, but push back, link pr's that don't follow above guidelines to the docs that (need to be written) on how to wrap this library for single purpose needs. Example: random ports could be passed in to this lib from a wrapper lib that deals with which random port to check, leaving portfinder simple, encapsulated and stable (cc @BarthesSimpson I think this is your best option for #86)

  • Add changelog and release tool (it should give credit to author, provide link to the pr merged, wiith description (ideally pr title, which means the only thing we need to manually ensure is that PR titles are accurate descriptions prior to merge) (#99)

We don't have a code of conduct, free speech welcome, but derogatory comments towards individuals (not ideas) will not be tolerated.

  • Make a code of conduct file, follow community norms (ideally, I like the way rust has handled this, see. Copy their statement or similar). [Good for new contributor] (issue #98)

V2

The following features would be released in a new semver major version of portfinder, 2.x.

Note: v2 is not likely, but here is what would go into it, bullet 3, CATALYST, being the most important, if needed, it is the only reason to pursue a new major version)

  • Use neo-async: #91 EDIT: upgraded to async v2.

    • In general don't use new libraries due to security, with maybe the exception someday of a new testing library (which is not included in dist npm package anyway).
  • Use randomized ports: #86 EDIT: this changes the behavior, and breaks the rule of refactoring in additive changes, aka, "underlying changes to implementation of a consumer facing <app|lib> should not change it observed behavior. The change that this introduces is 2 fold:

    1. ports are randomized - there may be consumers that don't expect this, example: ember-cli's ember s when run in 2 terminals, is expected to increase the 2nd applications test port sequentially -- for many, myself included, I have bookmarks for 7200, 7202, etc on mobile devices that reload and run the tests on each device for each app, especially when an addon is involved(which when changed, runs the tests for the yarn linked ember addon, and the consuming app that uses the yarn linked dep I'm working on.

    2. This can be observed without that explanation in the tests for #86, which was reverted due to a minor but far reaching error in when to terminate the algo it updated. (on that note, the tests are cleaner, they just changed the behavior, something I was nervous about when merging. In theory, randomizing should not matter, but in practice people may depend on such subtle bugs, which over time, become 'the outward behavior of the code, as perceived by the consumer, whether a user or a developer of a downstream codebase'. (quoting martin fowler, kent beck, in a hurry, forgive where mis-quoted).

  • CATALYST: use echo server to ensure port is not being used by a privileged user or group (I tried this couple years ago, most obvious breaking change was when it bound to bluetooth and/or mac os touch bar ports, both owned by root:wheel. Node docs do have privileged error code (as ERR* constant). I was trying to avoid checking every possible error and basically catch all but the ones we currently catch(if that), iterate to next port regardless of what that error was. Also, bound the range to be > 1024 and < 40000(apple uses this for touch bar, and you'd be surprised how often people hit that when using ember-cli in practice - they had to restart their computer or pass cli option for a lower port to iterate from for use with live reload in ember-cli. I changed the default to 7020 as a result, thus this issue exists, but hidden, meaning until substantial bug reports come in, 2.x is not a priority, as this is the single feature/bug fix that really requires changing an otherwise stable code base.



TODO: this list was written fast, it may lack clarity, please ask or comment where confused. I'll probably clean it up in later, but wanted to braindump while I was in the neighborhood. Related to http-party/node-http-proxy#1383 - and should reflect the tersness of that bullet point list ideally. ([but] "time keeps on ticking, ticking, ticking into the future.... 🎵" )

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.