Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dns: add setDefaultResolver and getDefaultResolver #14620

Closed

Conversation

XadillaX
Copy link
Contributor

@XadillaX XadillaX commented Aug 4, 2017

Since dns.Resolver was added, it gives a chance to manage the default
resolver by ourselves. So dns.setDefaultResolver and
dns.getDefaultResolver is added here.

Checklist
  • make -j4 test (UNIX)
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

dns

Since `dns.Resolver` was added, it gives a chance to manage the default
resolver by ourselves. So `dns.setDefaultResolver` and
`dns.getDefaultResolver` is added here.
@nodejs-github-bot nodejs-github-bot added dns Issues and PRs related to the dns subsystem. errors Issues and PRs related to JavaScript errors originated in Node.js core. labels Aug 4, 2017
@Trott
Copy link
Member

Trott commented Aug 4, 2017

semver-minor?

@mscdex mscdex added semver-minor PRs that contain new features and should be released in the next minor version. and removed errors Issues and PRs related to JavaScript errors originated in Node.js core. labels Aug 4, 2017
@XadillaX
Copy link
Contributor Author

XadillaX commented Aug 4, 2017

@Trott yep

@tniessen
Copy link
Member

tniessen commented Aug 4, 2017

As far as I know, the only difference between channels is the set of DNS servers, so which advantage does this API offer, compared to modifying the default channel using dns.setServers()? Maybe I am simply missing the big picture.

Adding getDefaultResolver() kind of makes sense to expose the cancel() function for requests in the default channel, but I am not sure we want to give users the ability to do that. A lot of modules might use the default channel at the same time, and if one of them decides to cancel all outstanding requests, this will be difficult to debug and most probably not what the user wanted, so it might be a good idea to prevent people from calling cancel on resolvers they did not create themselves.

It might be a better approach to be able to pass Resolver instances to those parts of our API which need to resolve hostnames.

@XadillaX
Copy link
Contributor Author

XadillaX commented Aug 4, 2017

@tniessen If we have several DNS servers to be candidates and we sometime choose one of them, I think this will be much more convenient.

const resolvers = {
    google: new Resolver(), // assume we've already `setServer([ '8.8.8.8', '8.8.4.4' ])`
    other: new Resolver()
};

// some logic
function changeDefaultResolver(name) {
    dns.setDefaultResolver(resolvers[name]);
}

And if no this function, we should do this:

const servers = {
    google: [ '8.8.8.8', '8.8.4.4' ],
    other: [ ... ]
};

function changeServer(name) {
    dns.setServer(servers[name]);
}

And what's more, if we add the timeout options in Resolver's constructor on later versions, the resolver's difference will be not only name servers.


function setDefaultResolver(resolver) {
if (!(resolver instanceof Resolver)) {
throw new errors.TypeError('ERR_INVALID_DNS_RESOLVER');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just reuse the existing ERR_INVALID_ARG_TYPE?

-->

Get the default resolver which may used by Node.js modules such as `http` and
provides functions like `dns.resolve()`, `dns.setServers()`, etc.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps just...

Returns the default `dns.Resolver` used by Node.js.

-->

Set the default resolver which may used by Node.js modules such as `http` and
provides functions like `dns.resolve()`, `dns.setServers()`, etc.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps just...

Changes the default `Resolver` used by Node.js.

Set the default resolver which may used by Node.js modules such as `http` and
provides functions like `dns.resolve()`, `dns.setServers()`, etc.

The only parameter must be a `dns.Resolver` instance that to replace the default
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd omit this sentence.

Get the default resolver which may used by Node.js modules such as `http` and
provides functions like `dns.resolve()`, `dns.setServers()`, etc.

## dns.setDefaultResolver()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

### dns.setDefaultResolver(resolver)
<!-- YAML
added: REPLACEME
-->

* `resolver` {dns.Resolver}

defaultResolver = resolver;
DEFAULT_RESOLVER_EXPORTED_FUNCTIONS.forEach((key) => {
module.exports[key] = defaultResolver[key].bind(defaultResolver);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels... hackish. Perhaps changing the module.exports properties into getters that return the equivalent method from defaultResolver would be a cleaner approach?

e.g.

module.exports = {
  /** ... **/
  get getServers() {
    return defaultResolver.getServers.bind(defaultResolver);
  }
  /** ... **/
}

That way the module's exported properties never change.

@tniessen
Copy link
Member

tniessen commented Aug 4, 2017

IMO we should minimize the side effects of our API, and certainly not encourage using APIs with side effects. Having a default channel is unavoidable both for convenience and backward compatibility, but promoting its use (and primarily reconfiguration) does not seem like a good idea to me.

If multiple modules try to configure the default channel or even attempt to replace it, just to enforce specific options for their DNS requests, they will interfere with each other. Instead, if a module requires the resolver to have specific properties, it should create a new resolver and either use it directly or pass it to the respective API (which we would need to adapt accordingly, e.g. by adding a resolver option, or figuring out how to glue resolve to lookup).

cc @addaleax for designing the Resolver API

@addaleax
Copy link
Member

addaleax commented Aug 4, 2017

@tniessen I’m already 👍ing your comments because I really have nothing to add, I just very plainly agree with you. :)

@jasnell
Copy link
Member

jasnell commented Aug 4, 2017

Thinking about it further, I agree. Rather than allowing the default to be overridden, I'd prefer to make it easier / possible to use specific Resolver instances where necessary.

@XadillaX
Copy link
Contributor Author

XadillaX commented Aug 6, 2017

So does this PR still need opening?

@jasnell
Copy link
Member

jasnell commented Aug 8, 2017

Let's leave it open for the time being. We should investigate how feasible it would be to support the other option of passing in Resolver instances where appropriate.

@jasnell jasnell added the blocked PRs that are blocked by other issues or PRs. label Aug 8, 2017
@BridgeAR
Copy link
Member

@jasnell what should be done here? I am not certain how we will progress with it and is just keeping it open the right thing?

@jasnell jasnell self-assigned this Sep 20, 2017
@jasnell
Copy link
Member

jasnell commented Sep 20, 2017

I'm assigning myselfto this. I'll be able to look at it in detail in the next week or so.

@BridgeAR
Copy link
Member

Closing due to long inactivity. If anyone thinks this should be reopened, please feel free to do so.

@BridgeAR BridgeAR closed this Nov 22, 2017
@jasnell
Copy link
Member

jasnell commented Nov 22, 2017

ping ... perhaps @addaleax has some thoughts?

@addaleax
Copy link
Member

Yeah, like I said above, I don’t think we want this. @XadillaX also opened #14891, which seems like a better way of basically achieving the same thing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked PRs that are blocked by other issues or PRs. dns Issues and PRs related to the dns subsystem. semver-minor PRs that contain new features and should be released in the next minor version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants