Skip to content

RUBY-2746 RUBY-2851 RUBY-2737 Provide options to limit number of mongos servers used in connecting to sharded clusters #2380

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

Merged
merged 22 commits into from
Dec 15, 2021

Conversation

neilshweky
Copy link
Contributor

@neilshweky neilshweky commented Dec 9, 2021

Adding ticket RUBY-2851 to this PR. This ticket is for removing the DNS spec tests that conflict with url-options spec tests.
Also adding RUBY-2737 to this PR. This ticket is for adding the srvServiceName option, and is completely implemented by this ticket.

Copy link
Contributor

@p-mongo p-mongo left a comment

Choose a reason for hiding this comment

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

Is there a test that specifying srv_max_hosts actually reduces the number of seeds compared to what is in the DNS? Apologies if I missed it, if not it should be added.

@@ -1226,6 +1228,12 @@ def validate_new_options!(opts)
end

_options[key] = compressors unless compressors.empty?
elsif key == :srv_max_hosts
if v && (!v.is_a?(Integer) || v < 0)
log_warn("#{v} is not a valid integer for srvMaxHosts")
Copy link
Contributor

Choose a reason for hiding this comment

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

srv_max_hosts is I would say more appropriate here.

@@ -1239,7 +1247,7 @@ def validate_new_options!(opts)
# Validates all options after they are set on the client.
# This method is intended to catch combinations of options which are
# not allowed.
def validate_options!(addresses = nil)
def validate_options!(addresses = nil, is_srv = nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use the keyword argument syntax for is_srv: is_srv: nil.


if options[:srv_max_hosts] && options[:srv_max_hosts] > 0
if options[:replica_set]
raise ArgumentError, ":srv_max_hosts > 0 cannot be used with replica_set option"
Copy link
Contributor

Choose a reason for hiding this comment

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

The options should all be referenced the same way, i.e. either with leading colons or without (preferably in the way that is most similar to other validators).


unless is_srv.nil? || is_srv
if options[:srv_max_hosts]
raise ArgumentError, "srvMaxHosts cannot be used on non-SRV URI"
Copy link
Contributor

Choose a reason for hiding this comment

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

srv_max_hosts

@@ -92,6 +92,8 @@ class Client
:server_api,
:server_selection_timeout,
:socket_timeout,
:srv_max_hosts,
:srv_service_name,
Copy link
Contributor

Choose a reason for hiding this comment

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

These options should be documented on the Client constructor. If they are used only internally by the driver, they should be annotated as such.

Copy link
Contributor

Choose a reason for hiding this comment

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

This still needs to be done right?

# @param [ String | nil ] srv_service_name The SRV service name for the DNS query.
# If nil, 'mongodb' is used.
# @param [ Integer | nill ] srv_max_hosts The maximum number of records to return.
# If this value is zero or nil, return all of the records.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be better to change zero to nil sometime during client construction and everywhere downstream of the client require and expect (with validation, if necessary) that the value is either nil or a positive integer.

lib/mongo/uri.rb Outdated
# byebug
if uri_options[:srv_max_hosts] && uri_options[:srv_max_hosts] > 0
if uri_options[:replica_set]
raise_invalid_error_no_fmt!(":srv_max_hosts > 0 cannot be used with replica_set option")
Copy link
Contributor

Choose a reason for hiding this comment

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

These messages should use the URI option names, e.g. srvMaxHosts, replicaSet.

end
end

context 'srv_max_hosts > 0 and replicaSet' do
Copy link
Contributor

Choose a reason for hiding this comment

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

replica_set, please check the naming of other options in this file too.

@neilshweky
Copy link
Contributor Author

Is there a test that specifying srv_max_hosts actually reduces the number of seeds compared to what is in the DNS? Apologies if I missed it, if not it should be added.

There are spec tests that do it (srvMaxHosts-less_than_srv_records.yml) but I didn't write any Ruby tests. Should I?

@p-mongo
Copy link
Contributor

p-mongo commented Dec 13, 2021

The srvMaxHosts-less_than_srv_records.yml test doesn't assert the resulting seed list, therefore I expect it to pass if the driver e.g. happens to replace the seed list with a single bogus value. Looking at the test runner implementation, as far as I can tell that test would also be silently not performed if the file format changed (as opposed to producing an error due to unexpected test format).

Based on this, I suggest adding a test which uses one of the test URIs, create a client with it, then inspect the seed list and verify that the seed is one of expected values.

@neilshweky neilshweky changed the title RUBY-2746 Provide options to limit number of mongos servers used in connecting to sharded clusters RUBY-2746 RUBY-2851 Provide options to limit number of mongos servers used in connecting to sharded clusters Dec 13, 2021
@neilshweky
Copy link
Contributor Author

neilshweky commented Dec 13, 2021

The srvMaxHosts-less_than_srv_records.yml test doesn't assert the resulting seed list, therefore I expect it to pass if the driver e.g. happens to replace the seed list with a single bogus value. Looking at the test runner implementation, as far as I can tell that test would also be silently not performed if the file format changed (as opposed to producing an error due to unexpected test format).

Based on this, I suggest adding a test which uses one of the test URIs, create a client with it, then inspect the seed list and verify that the seed is one of expected values.

It's difficult to assert the actual seedlist, since if max hosts is less than the number of hosts, it selects a random subset of hosts of size srv_max_hosts. I can assert that the hosts that it does come up with are valid, though.

EDIT: done!

@neilshweky neilshweky requested a review from p-mongo December 13, 2021 18:49
@neilshweky neilshweky changed the title RUBY-2746 RUBY-2851 Provide options to limit number of mongos servers used in connecting to sharded clusters RUBY-2746 RUBY-2851 RUBY-2737 Provide options to limit number of mongos servers used in connecting to sharded clusters Dec 13, 2021
- 0

* - ``:srv_service_name``
- The SRV service name to use in the DNS query.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think "The service name to use in the SRV DNS query" would be more clear.

for sharded topologies. If this option is set to 0, there will
be no maximum number of connections. If the given URI resolves
to more hosts than ``:srv_max_hosts``, the client will ramdomly
choose an ``:srv_max_hosts`` sized subset of hosts.
Copy link
Contributor

Choose a reason for hiding this comment

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

I would add here a note that the hosts that the driver ignores during client construction will never be used, i.e., if a deployment has 10 total mongoses and this option limits them to 5, and those 5 happen to become unavailable, the client will quit working completely even though the deployment overall still has 5 functional mongoses elsewhere.

Comment on lines 698 to 699
- The maximum number of mongos connections that may be created
for sharded topologies. If this option is set to 0, there will
Copy link
Contributor

Choose a reason for hiding this comment

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

I would adjust the first sentence to something like "The maximum number of mongoses that the driver will communicate with", because the number of connections is controlled by pool size and can exceed 1 per mongos.

@@ -92,6 +92,8 @@ class Client
:server_api,
:server_selection_timeout,
:socket_timeout,
:srv_max_hosts,
:srv_service_name,
Copy link
Contributor

Choose a reason for hiding this comment

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

This still needs to be done right?

let(:options) { '/?srvMaxHosts=1' }
it 'returns an array with only one of the parsed servers' do
expect(uri.servers.length).to eq 1
expect(hosts.include?(uri.servers.first)).to be true
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@neilshweky neilshweky requested a review from p-mongo December 14, 2021 15:13
@neilshweky neilshweky requested a review from comandeo December 14, 2021 17:45
Copy link

@comandeo comandeo left a comment

Choose a reason for hiding this comment

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

👍

@neilshweky neilshweky merged commit 4f5e06d into mongodb:master Dec 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants