http-party / node-portfinder

A simple tool to find an open port or domain socket on the current machine
https://github.com/http-party/node-portfinder
Other
882 stars 95 forks source link

Cluster apps are all on same port instead of different ports #118

Closed BillyCottrell closed 3 years ago

BillyCottrell commented 3 years ago

Hi there,

First time I am using this library, but I am trying to run 3 instances of the same application, but on different ports. The problem is that all instances are executed simultaneously, meaning that they all take up the same port. I am using this library to let my express servers listen to different ports, so my gateway can load balance them.

Is there any way to solve this?

Thanks in advance,

Billy Cottrell

eriktrom commented 3 years ago

yeah so how do i explain this in 3 words or less - wait for the kernel to release the lock on the file descriptor before starting the next server and it'll work (i don't recall but on intel 2015 macbook when I wrote the tests, it varied between something like 1-3 seconds.

otherwise, the port is not released until the OS gets around to it as there is no "happens before" guarantee lock I can add without calling into the os via Node-API (formerly N-API) which would be the riskiest thing I've ever done with this lib and I don't do anything like that now given its been stable and working for 99% of uses cases out there for a number of years now. (when i first took on a bug with os syscall errors I learned operating systems the hard way - by breaking half of github, all of ember, angular and circle ci. Now react uses this too, so the stakes are even higher...

that said - you are not the first person to file this issue - would u be open to adding something to the README in regards to os synchronization being indeterminate and based on the underlying kernel, what else is running and what your seeing as far as how long an avg setTimeout value is that your seeing (if u try that it will work, you'll have to fiddle with the timer though and also the event loop will not itself be the same every time either given the nature of setTimeout and how the task queue works..

^^ this is why there are no docs on this, its likely to scare people away rather than help them in most cases but worded well, would be helpful -- im not a wordsmith but I totally understand your pain - it plagued the tests (and if your read them, still does, the setTimeout is just set very high otherwise random tests failures in CI were happening.

hope that sheds light.. i do keep answering this question... hmm

pr for docs totally wanted :)

BillyCottrell commented 3 years ago

Hi @eriktrom,

My apologies for not answering sooner but I was on holiday, anyways I understand what you are saying and I can feel the pain just from reading it.

Except, the reason for my question is slightly different. I am using pm2 to (re)start/stop/update my API's so I can easily manage them. Now when you use pm2 to startup your API's it gives a certain port, but that is when your using pm2 in the standard or fork mode. When you start it up in cluster mode they all receive the same port as they share the resources and such, and when updating the API it just stops the first instance to update it till it's finished and then it moves on to the next one which is not the case when being in fork mode. So I was hoping to start up the API in cluster mode (to use that update functionality) but to overwrite the PORT within the API itself using this library. Then again they all work simultaneously so even giving them a timeout would give the same result as you would be delaying the result itself.

I am willing to add documentation about this, but I doubt that this library would work in this scenario in the first place but could be wrong.

Nonetheless thx for the help!