| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Sorry, something went wrong.
|
The test sequential/test-net-server-address.js failed, because of the first functional difference mentioned above. The solution is either to change the failing test, or reintroduce the inconsistency. |
Sorry, something went wrong.
There was a problem hiding this comment.
I understand why you made the changes, but it seems odd that this function accepts undefined as a valid port, and also that sometimes it returns a boolean and other times throws.
Sorry, something went wrong.
There was a problem hiding this comment.
It could be split into two functions: One that checks the type and one that does the coercion to number (port | 0) and throws if not valid.
Sorry, something went wrong.
|
I made some updates, the CI should pass now. |
Sorry, something went wrong.
|
This change would remove a test introduced in 57c56558. /cc @indutny @raymondfeng Even if the change should happen (about which I have no opinion, at least right now), the test should probably be modified so that it checks the new expected behavior rather than deleting it. |
Sorry, something went wrong.
|
But then I think it should be moved to parallel/test-net-listen-port-option.js. |
Sorry, something went wrong.
|
The problem is this: listen(port) treated illegal ports differently than listen({port: port}), connect(port) and connect({port: port}). This PR makes listen(port) behave like the others, but that is a breaking change. I don't believe this is a big deal. I don't think anybody uses fractions in the port, and I guess that most people don't want to listen on a random port. And if they do, they will probably omit the port or use 0 as the docs say. But if they use something else, it should be easy to fix, as you get a clear error message and can simply follow the stack trace. What do you think? |
Sorry, something went wrong.
|
The isLegalPort() function that you wish to change appears to have been authored by @bnoordhuis in 480b48244 in order to deal with an API inconsistency. Since that also is the motivation for your proposed change, perhaps he can offer an opinion as to the risk and value of the modifications here. |
Sorry, something went wrong.
|
Marking as semver-major because of the functional changes. It's possible we can downgrade this to semver-minor tho. |
Sorry, something went wrong.
|
rebased |
Sorry, something went wrong.
|
@jscissr ... thank you :-) I'll queue this up for a review shortly. Sorry that it's taken so long :-/ |
Sorry, something went wrong.
|
Thanks @jasnell! In case you don't make a new major version anytime soon, I could also split the refactoring from the (breaking) consistency improvement, which means just a few extra lines that could be removed in the next major. |
Sorry, something went wrong.
* move `listenAfterLookup` out of `Server.prototype.listen` * rename `listenAfterLookup` to `lookupAndListen` for consistency with `lookupAndConnect` * self -> this
This is mostly preparation, `options` will be used later.
This removes the ifs directly dealing with arguments.
|
@nodejs/collaborators Can we get some other quick LGTM? New CI: https://ci.nodejs.org/job/node-test-pull-request/4017/ @jasnell I'll like to get this landed for v7. |
Sorry, something went wrong.
|
CI is passing. |
Sorry, something went wrong.
| // Returns an array [options, cb], where cb can be null. | ||
| // It is the same as the argument of Socket.prototype.connect(). | ||
| function normalizeConnectArgs(args) { | ||
| // This is also used by Server.prototype.listen(). |
There was a problem hiding this comment.
This should probably say that it is used by listen() and connect(). Just saying "also" doesn't mean much when the "connect" part is removed.
Sorry, something went wrong.
There was a problem hiding this comment.
@cjihrig I can fix the comment when I land. Is LGTM apart from this?
Sorry, something went wrong.
|
This is getting a LGTM from me, if @mcollina will fix the comment when landing |
Sorry, something went wrong.
|
@mcollina ... ok, I'll be cutting the branch right about at noon pacific today so there's still some time. the change LGTM |
Sorry, something went wrong.
This PR simplifies Server.prototype.listen, removing some redundancy and inconsistency. Because listen and connect have a similar function signature, normalizeConnectArgs can be reused for listen. listenAfterLookup renamed to lookupAndListen for consistency with lookupAndConnect, and moved out of Server.prototype.listen. PR-URL: #4039 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Glen Keane <glenkeane.94@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
|
It would appear this has broken passing null to listen https://github.com/yoshuawuyts/crash-reporter-service/blob/master/tests/lib.js#L40 Was that intended behavior? If not we should land a fix edit: ref --> https://twitter.com/yoshuawuyts/status/820527120740913154 |
Sorry, something went wrong.
|
The main discussion is in: #4039 (comment). Yes it was a wanted fix, as I think that we should validate ports in a consistent manner. Specifically, in node v6 passing null as a port in the option object throws, but not when passing it as an argument. It has also passed a long amount of CITGM runs for all the v7 releases. |
Sorry, something went wrong.
|
+1 for consistency in validation, but I think passing null as port in option object should not throw. I would expect calling .listen(function(){}), .listen(null, function(){}) , .listen(undefined, function(){}) , .listen({}, function(){}), .listen({port: null}, function(){}), .listen({port: undefined}, function(){})`, and all the previous when called without a callback, should have same behaviour, and the behaviour should be to treat it as "port argument was not provided (use default)". Basically, in an options object, we should not distinguish between o{}, o={opt:null}, and o={opt:undefined}, since in all those three, o == null and o == undefined. |
Sorry, something went wrong.
|
@sam-github I'm not convinced about that. We support undefined, because that's what we get when something is not specified. In order to get null, it would have to be explicitly set. IMHO it's more robust against programmer errors in this way. It didn't break a lot of the community either, as what was mentioned was new software. |
Sorry, something went wrong.
|
@mcollina Imagine configuration coming out of node-config YAML files, and default.yaml has a port which is overridden by mcollina.yaml (NODE_ENV=mcollina) which sets port to null in order to turn off the default. Very normal use case imho. |
Sorry, something went wrong.
|
@ronkorving why do not set it to 0? For all valid use cases, this is typed by a human. And 0 is a much more sensible value than null from a SO perspective. |
Sorry, something went wrong.
|
@mcollina its easy to get keys set, config files, default handling, etc. Object.assign, util._extend can both clear keys by setting them to undefined, for example, but can't delete keys. Can you explain why you think its more robust? I've found the exact opposite. In Javascript, o={}, o={opt:null}, and o={opt:undefined}, o.opt == null and o.opt == undefined. Its is possible to distinguish between property not set, and property set with value of undefined, but you have to write extra code to do so, so APIs that distinguish between them are harder to document, implement, and use, and lead to subtle faillures in my experience. |
Sorry, something went wrong.
|
@mcollina Setting it to 0 is very explicitly setting it to that value. Trying to unset it so it uses whatever the default may be (in this case 0) has different semantics. You can state the first is always superior, but I guess my point is that there are various ways to look at this (of which at least one case can run into the null problem). |
Sorry, something went wrong.
|
@sam-github I generally think that massively overloaded method are extremely hard to maintain, optimize and keep secure. In this particular case, null was never documented as a possible value in the first place, and an accident of our implementation. If it was for me, I would remove the default value for port, because it just leads to confusion. Having said so, fire a PR and we will discuss it there. Even if I disagree, it seems a lot of people care about passing null as a port, so I'll be happy to review that change. |
Sorry, something went wrong.
|
Much of node's API is undocumented, unfortunately, so its hard to argue intentions. I agree with you on massively overloaded methods, but not here. if ("PORT" in process.env)
server.listen(process.env.PORT, ...) // use the port
else
server.listen(...) // use the defaultis, IMO, unfortunate, I'd rather server.listen(process.env.PORT, ...) // if the env var is not defined, you get the default behaviourThis pattern shows up quite often when loading config, not just env vars, which is why its important to base behaviour on a key's value, not its presence, its why: var config = {}; // probably read from a config file or DB, note there is no PORT
server.listen({port: config.port}, .. // options.port exists, but value is undefinedshould be the same as server.listen({}, .. // options.port key does not exist |
Sorry, something went wrong.
|
Just to clarify, this does not work in v6, but it does in v7 with this very change: var net = require('net')
net.createServer().listen(process.env.PORT, function () {
console.log('server listening on', this.address())
})also var config = {}
console.log(config.port) // => undefined
server.listen(config.port) // you get the default behavior
config.port = null
console.log(config.port) // => null
server.listen(config.port) // it throws, because null is not a valid portIMHO it's working as you want, with the added benefit of preventing bad values you would have to come from somewhere unexpectedly. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
This PR simplifies Server.prototype.listen, removing some redundancy and inconsistency.
Because listen and connect have a similar function signature, normalizeConnectArgs can be reused for listen.
listenAfterLookup renamed to lookupAndListen for consistency with lookupAndConnect, and moved out of Server.prototype.listen.
Functional differences
To improve consistency, I actually made some small functional changes:
port was checked with this complicated code if set in a config object:
if (typeof h.port === 'number' || typeof h.port === 'string' || (typeof h.port === 'undefined' && 'port' in h)) { // Undefined is interpreted as zero (random port) for consistency // with net.connect(). if (typeof h.port !== 'undefined' && !isLegalPort(h.port)) throw new RangeError('"port" option should be >= 0 and < 65536: ' + h.port); …But if set as first argument, it was only coerced to a number with var port = toNumber(arguments[0]);.
Now, it is consistently using the first way, toNumber is not used anymore.
However this is a breaking change, because before invalid ports resulted in using a random port instead of throwing.
addressType was sometimes null and sometimes 4, if no address is given.
Now it is always 4.
host was checked like this:
if (arguments[1] !== undefined && typeof arguments[1] !== 'function' && typeof arguments[1] !== 'number')Now it is checked with if (typeof arguments[1] === 'string'), this is consistent with connect.