Skip to content

PYTHON-4703 MongoClient should default to connect=False on FaaS environments #1844

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 4 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,20 @@ PyMongo 4.9 brings a number of improvements including:
- Fixed a bug where PyMongo would raise ``InvalidBSON: date value out of range``
when using :attr:`~bson.codec_options.DatetimeConversion.DATETIME_CLAMP` or
:attr:`~bson.codec_options.DatetimeConversion.DATETIME_AUTO` with a non-UTC timezone.
- The default value for ``connect`` in ``MongoClient`` is changed to ``False`` when running on
unction-as-a-service (FaaS) like AWS Lambda, Google Cloud Functions, and Microsoft Azure Functions.
On some FaaS systems, there is a ``fork()`` operation at function
startup. By delaying the connection to the first operation, we avoid a deadlock. See
`Is PyMongo Fork-Safe`_ for more information.


Issues Resolved
...............

See the `PyMongo 4.9 release notes in JIRA`_ for the list of resolved issues
in this release.

.. _Is PyMongo Fork-Safe : https://www.mongodb.com/docs/languages/python/pymongo-driver/current/faq/#is-pymongo-fork-safe-
.. _PyMongo 4.9 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=39940


Expand Down
9 changes: 8 additions & 1 deletion pymongo/asynchronous/mongo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,10 @@ def __init__(

.. versionchanged:: 4.7
Deprecated parameter ``wTimeoutMS``, use :meth:`~pymongo.timeout`.

.. versionchanged:: 4.9
The default value of ``connect`` is changed to ``False`` when running in a
Function-as-a-service environment.
"""
doc_class = document_class or dict
self._init_kwargs: dict[str, Any] = {
Expand Down Expand Up @@ -803,7 +807,10 @@ def __init__(
if tz_aware is None:
tz_aware = opts.get("tz_aware", False)
if connect is None:
connect = opts.get("connect", True)
# Default to connect=True unless on a FaaS system, which might use fork.
Copy link
Member

Choose a reason for hiding this comment

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

Suggest adding a versionchanged and updating the docstring for connect.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

from pymongo.pool_options import _is_faas

connect = opts.get("connect", not _is_faas())
keyword_opts["tz_aware"] = tz_aware
keyword_opts["connect"] = connect

Expand Down
12 changes: 10 additions & 2 deletions pymongo/synchronous/mongo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ def __init__(
aware (otherwise they will be naive)
:param connect: If ``True`` (the default), immediately
begin connecting to MongoDB in the background. Otherwise connect
on the first operation.
on the first operation. The default value is ``False`` when
running in a Function-as-a-service environment.
:param type_registry: instance of
:class:`~bson.codec_options.TypeRegistry` to enable encoding
and decoding of custom types.
Expand Down Expand Up @@ -719,6 +720,10 @@ def __init__(

.. versionchanged:: 4.7
Deprecated parameter ``wTimeoutMS``, use :meth:`~pymongo.timeout`.

.. versionchanged:: 4.9
The default value of ``connect`` is changed to ``False`` when running in a
Function-as-a-service environment.
"""
doc_class = document_class or dict
self._init_kwargs: dict[str, Any] = {
Expand Down Expand Up @@ -802,7 +807,10 @@ def __init__(
if tz_aware is None:
tz_aware = opts.get("tz_aware", False)
if connect is None:
connect = opts.get("connect", True)
# Default to connect=True unless on a FaaS system, which might use fork.
from pymongo.pool_options import _is_faas

connect = opts.get("connect", not _is_faas())
keyword_opts["tz_aware"] = tz_aware
keyword_opts["connect"] = connect

Expand Down
4 changes: 4 additions & 0 deletions test/lambda/mongodb/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import json
import os
import warnings

from bson import has_c as has_bson_c
from pymongo import MongoClient
Expand All @@ -18,6 +19,9 @@
ServerHeartbeatListener,
)

# Ensure there are no warnings raised in normal operation.
warnings.simplefilter("error")
Copy link
Member

Choose a reason for hiding this comment

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

Nice!


open_connections = 0
heartbeat_count = 0
streaming_heartbeat_count = 0
Expand Down
3 changes: 2 additions & 1 deletion tools/synchro.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
docstring_replacements: dict[tuple[str, str], str] = {
("MongoClient", "connect"): """If ``True`` (the default), immediately
begin connecting to MongoDB in the background. Otherwise connect
on the first operation.""",
on the first operation. The default value is ``False`` when
running in a Function-as-a-service environment.""",
("Collection", "create"): """If ``True``, force collection
creation even without options being set.""",
("Collection", "session"): """A
Expand Down
Loading