Skip to content

Conversation

juliusgeo
Copy link
Contributor

No description provided.

Copy link
Member

@behackett behackett left a comment

Choose a reason for hiding this comment

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

You need to add documentation for the new option in the docstring for MongoClient, and a mention in the changelog.

try:
results = _resolve('_mongodb._tcp.' + self.__fqdn, 'SRV',
lifetime=self.__connect_timeout)
results = _resolve('_'+str(self.__srv)+'._tcp.' + self.__fqdn,
Copy link
Member

Choose a reason for hiding this comment

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

Add spaces around the '+' characters. Also, why do you have to wrap self.__srv in str? Is it being converted to a bytes before it gets here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you are right and we can remove that.

options[opt] = val
if "tls" not in options and "ssl" not in options:
options["tls"] = True if validate else 'true'
#elif not is_srv and options.get("srvServiceName", None) is not None:
Copy link
Member

Choose a reason for hiding this comment

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

Remove the dead code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This isn't dead code, it was to fix the test that was testing for a configuration to be raised under those conditions. So I restored it.

Copy link
Member

@ShaneHarvey ShaneHarvey left a comment

Choose a reason for hiding this comment

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

From a grep through the codebase we also need to pass the new option to the _SrvResolver in pymongo/monitor.py. It's somewhat concerning that the tests pass without this change (but not your fault at all of course). Does the spec change have any test coverage for mongos SRV polling?

Starting in version 4.0 you can pass a custom SRV service name by
using the ``srvServiceName`` option like so::
MongoClient("mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname")
Copy link
Member

Choose a reason for hiding this comment

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

This should be documented at the bottom of the **Other optional parameters can be passed as keyword arguments:** section below. Please also note the new parameter name in the existing versonchanged:: 4.0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

nodes = [
(maybe_decode(res.target.to_text(omit_final_dot=True)), res.port)
for res in results]

Copy link
Member

Choose a reason for hiding this comment

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

This change is uneeded.

class _SrvResolver(object):
def __init__(self, fqdn, connect_timeout=None):
def __init__(self, fqdn,
connect_timeout=None, srv_service_name="mongodb"):
Copy link
Member

Choose a reason for hiding this comment

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

It looks like we should always pass connect_timeout and srv_service_name when creating a _SrvResolver. Can you make both of them required arguments?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I'm not sure how to get the value of srv_service_name from within monitor.py where _SrvResolver is called, so I don't know how to make them required arguments because I don't know where the values that should go in those arguments are stored.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nevermind I figured out the plumbing. However, I don't think that connect_timeout is always passed when creating a _SrvResolver.

Copy link
Member

Choose a reason for hiding this comment

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

connect_timeout needs to always be passed. The fact that it's not already is an oversight. Please update SrvMonitor to get the timeout from topology_settings (self._settings).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

results = _resolve('_mongodb._tcp.' + self.__fqdn, 'SRV',
lifetime=self.__connect_timeout)
results = _resolve('_' + self.__srv+'._tcp.' + self.__fqdn,
'SRV', lifetime=self.__connect_timeout)
Copy link
Member

Choose a reason for hiding this comment

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

Please match the surrounding code style. Second line is indented too much. Spaces around +.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


# get the srvservicename from options so that we can pass it to
# _SrvResolver
# constructor below
Copy link
Member

@ShaneHarvey ShaneHarvey Oct 5, 2021

Choose a reason for hiding this comment

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

This comment is unneeded. Writing useful comments is a tough skill to learn. Usually you want a comment to explain some tricky or non-obvious code (which this is not) or to explain why the code is needed (which is obvious here). Please read this blog for some good guidelines: https://stackoverflow.blog/2021/07/05/best-practices-for-writing-code-comments/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

options[opt] = val
if "tls" not in options and "ssl" not in options:
options["tls"] = True if validate else 'true'
elif not is_srv and options.get("srvServiceName", None) is not None:
Copy link
Member

Choose a reason for hiding this comment

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

.get("srvServiceName", None) is the same as .get("srvServiceName"). Let's use the second.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

options["tls"] = True if validate else 'true'
elif not is_srv and options.get("srvServiceName", None) is not None:
raise ConfigurationError("You cannot use the srvServiceName option "
"with non-SRV URIs.")
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 suggest: "The srvServiceName option is only allowed with 'mongodb+srv://' URIs"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

There is a new parameter for SRV URIs ``srvServiceName`` which
can be used like so::
MongoClient("mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname")
Copy link
Member

Choose a reason for hiding this comment

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

We should not repeat the docs here. We should just say:

Added the ``srvServiceName`` URI and keyword argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

- Starting in version 4.0 you can pass a custom SRV service name by
using the ``srvServiceName`` option like so::
MongoClient("mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname")
Copy link
Member

Choose a reason for hiding this comment

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

Let's move this to the bottom of this list (under unicode_decode_error_handler). Also please match the doc formatting and style of the other options here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

dbase = res["database"] or dbase
opts = res["options"]
fqdn = res["fqdn"]
srv_service_name = opts.get("srvServiceName", "mongodb")
Copy link
Member

Choose a reason for hiding this comment

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

Please refactor the default "mongodb" value into a global variable. You can add it to common.py next to the other default global settings.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

seedlist, ttl = _SrvResolver(self._fqdn).get_hosts_and_min_ttl()
seedlist, ttl = _SrvResolver(self._fqdn,
srv_service_name=self._srv_service_name
).get_hosts_and_min_ttl()
Copy link
Member

Choose a reason for hiding this comment

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

The style here would be cleaner like this:

        try:
            resolver = _SrvResolver(
                self._fqdn, 
                srv_service_name=self._srv_service_name)
            seedlist, ttl = resolver.get_hosts_and_min_ttl()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

class _SrvResolver(object):
def __init__(self, fqdn, connect_timeout=None):
def __init__(self, fqdn,
connect_timeout=None, srv_service_name="mongodb"):
Copy link
Member

Choose a reason for hiding this comment

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

connect_timeout needs to always be passed. The fact that it's not already is an oversight. Please update SrvMonitor to get the timeout from topology_settings (self._settings).

results = _resolve('_mongodb._tcp.' + self.__fqdn, 'SRV',
lifetime=self.__connect_timeout)
results = _resolve('_' + self.__srv + '._tcp.' + self.__fqdn,
'SRV', lifetime=self.__connect_timeout)
Copy link
Member

Choose a reason for hiding this comment

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

The indentation here still looks off, should be:

            results = _resolve('_' + self.__srv + '._tcp.' + self.__fqdn,
                               'SRV', lifetime=self.__connect_timeout)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

- The ``hint`` option is now required when using ``min`` or ``max`` queries
with :meth:`~pymongo.collection.Collection.find`.
- ``name`` is now a required argument for the :class:`pymongo.driver_info.DriverInfo` class.
- When providing a URI to the :class:`~pymongo.mongo_client.MongoClient`
Copy link
Member

Choose a reason for hiding this comment

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

Suggest: When providing a "mongodb+srv://" URI to :class:...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

_MAX_END_SESSIONS = 10000

# Default value for srvServiceName
SRV_SERVICE_NAME_DEFAULT = "mongodb"
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 the _DEFAULT because none of the other constants have it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Comment on lines 335 to 336
- Starting in version 4.0 you can pass a custom SRV service name by
using the ``srvServiceName`` option like so::
Copy link
Member

Choose a reason for hiding this comment

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

This does not match how we document the other options. The line needs to start with:

- `<option name>`: description.

There's also no need to mention the Starting in version 4.0 part.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

from urllib.parse import unquote_plus

from pymongo.common import (
from pymongo.common import (SRV_SERVICE_NAME_DEFAULT,
Copy link
Member

Choose a reason for hiding this comment

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

This import should be on a new line to match the existing style.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

client = MongoClient('mongodb+srv://test22.test.build.10gen.cc',
srvServiceName='namefromkwarg')
self.assertEqual(client._topology_settings._srv_service_name,
'namefromkwarg')
Copy link
Member

Choose a reason for hiding this comment

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

Indentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


def test_service_name_from_kwargs(self):
client = MongoClient('mongodb+srv://test22.test.build.10gen.cc',
srvServiceName='namefromkwarg')
Copy link
Member

Choose a reason for hiding this comment

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

Please add connect=False since this test doesn't need to open the topology.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

with self.assertRaisesRegex(AutoReconnect, expected):
client.pymongo_test.test.find_one({})

def test_service_name_from_kwargs(self):
Copy link
Member

Choose a reason for hiding this comment

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

This needs:

    @unittest.skipUnless(
        _HAVE_DNSPYTHON, "DNS-related tests need dnspython to be installed")
    def test_service_name_from_kwargs(self):

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

'/?srvServiceName=customname',
connect=False)
self.assertEqual(client._topology_settings._srv_service_name,
'customname')
Copy link
Member

Choose a reason for hiding this comment

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

We need a test which actually checks that the kwarg overrides the URI. Like this:

        client = MongoClient(
             'mongodb+srv://user:[email protected]'
             '/?srvServiceName=shouldBeOverridden',
             srvServiceName='customname',
             connect=False)
        self.assertEqual(client._topology_settings._srv_service_name,
                         'customname')

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


def parse_uri(uri, default_port=DEFAULT_PORT, validate=True, warn=False,
normalize=True, connect_timeout=None):
normalize=True, connect_timeout=None, srv_service_name=None):
Copy link
Member

Choose a reason for hiding this comment

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

Please update the docstring below to reflect the new srv_service_name param.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@juliusgeo juliusgeo requested a review from ShaneHarvey October 7, 2021 18:09
and decoding of custom types.
| **Other optional parameters can be passed as keyword arguments:**
Copy link
Member

Choose a reason for hiding this comment

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

Please undo this change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

a Unicode-related error occurs during BSON decoding that would
otherwise raise :exc:`UnicodeDecodeError`. Valid options include
'strict', 'replace', and 'ignore'. Defaults to 'strict'.
- `srvServiceName`: A custom SRV service name. Use it like so::
Copy link
Member

Choose a reason for hiding this comment

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

I suggest:

`srvServiceName`: (string) The SRV service name to use for "mongodb+srv://" URIs. Defaults to "mongodb". Use it like so::

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@ShaneHarvey
Copy link
Member

From a grep through the codebase we also need to pass the new option to the _SrvResolver in pymongo/monitor.py. It's somewhat concerning that the tests pass without this change (but not your fault at all of course). Does the spec change have any test coverage for mongos SRV polling?

I know you've already addressed the option plumbing but do you have any thoughts on the test coverage issue?

@juliusgeo
Copy link
Contributor Author

From a grep through the codebase we also need to pass the new option to the _SrvResolver in pymongo/monitor.py. It's somewhat concerning that the tests pass without this change (but not your fault at all of course). Does the spec change have any test coverage for mongos SRV polling?

I know you've already addressed the option plumbing but do you have any thoughts on the test coverage issue?

I'm not sure about the test coverage. I think that our new tests cover most of the behavior, but I didn't see anything else in the spec tests besides the ones for this PR. I think one thing we could do is maybe check and make sure that the value of self.__srv is the correct value for _SrvResolver, but I'm not sure how to do that.

@juliusgeo juliusgeo requested a review from ShaneHarvey October 7, 2021 22:21
Copy link
Member

@ShaneHarvey ShaneHarvey left a comment

Choose a reason for hiding this comment

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

LGTM!

I'm not sure about the test coverage. ...

Please file a DRIVERS ticket to request test coverage here. The problem is that there is no test coverage for SRV polling with a custom service name.

@juliusgeo juliusgeo merged commit 6bb8a1f into mongodb:master Oct 8, 2021
juliusgeo added a commit to juliusgeo/mongo-python-driver that referenced this pull request Apr 5, 2022
juliusgeo added a commit to juliusgeo/mongo-python-driver that referenced this pull request Apr 6, 2022
juliusgeo added a commit to juliusgeo/mongo-python-driver that referenced this pull request Apr 7, 2022
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