@@ -199,6 +199,9 @@ child process.
199
199
a high probability of deadlock among ``MongoClient`` instances in the child process.
200
200
{+driver-short+} tries to issue a warning if this deadlock might occur.
201
201
202
+ For more information about deadlock in forked processes, see
203
+ :ref:`pymongo-fork-deadlock`.
204
+
202
205
Multiprocessing
203
206
~~~~~~~~~~~~~~~
204
207
@@ -223,6 +226,93 @@ To use multiprocessing with {+driver-short+}, write code similar to the followin
223
226
Do not copy an instance of the ``MongoClient`` class from the parent process to a child
224
227
process.
225
228
229
+ Type Hints
230
+ ----------
231
+
232
+ If you're using Python v3.5 or later, you can add type hints to your Python code.
233
+
234
+ The following code example shows how to declare a type hint for a ``MongoClient``
235
+ object:
236
+
237
+ .. code-block:: python
238
+
239
+ client: MongoClient = MongoClient()
240
+
241
+ In the previous example, the code doesn't specify a type for the documents that the
242
+ ``MongoClient`` object will work with. To specify a document type,
243
+ include the ``Dict[str, Any]`` type when you
244
+ create the ``MongoClient`` object, as shown in the following example:
245
+
246
+ .. code-block:: python
247
+
248
+ from typing import Any, Dict
249
+ client: MongoClient[Dict[str, Any]] = MongoClient()
250
+
251
+ Troubleshooting
252
+ ---------------
253
+
254
+ MongoClient Fails ConfigurationError
255
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
256
+
257
+ Providing invalid keyword argument names causes the driver to raise this error.
258
+
259
+ Ensure that the keyword arguments that you specify exist and are
260
+ spelled correctly.
261
+
262
+ .. _pymongo-fork-deadlock:
263
+
264
+ Forking a Process Causes a Deadlock
265
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
266
+
267
+ A ``MongoClient`` instance spawns multiple threads to run background tasks, such as
268
+ monitoring connected servers. These threads share state that is protected by instances
269
+ of the ``threading.Lock`` class, which are themselves
270
+ `not fork-safe <http://bugs.python.org/issue6721>`__.
271
+ {+driver-short+} is subject to the same limitations as any other multithreaded
272
+ code that uses the ``threading.Lock`` class, or any mutexes.
273
+
274
+ One of these limitations is that the locks become useless after calling the
275
+ ``fork()`` method. When ``fork()`` executes, the driver copies all the parent process's locks to
276
+ the child process in the same state as they were in the parent. If they are
277
+ locked in the parent process, they are also locked in the child process. The child process
278
+ created by ``fork()`` has only one thread, so any locks created by
279
+ other threads in the parent process are never released in the child process.
280
+ The next time the child process attempts to acquire one of these locks, deadlock occurs.
281
+
282
+ Starting in {+driver-short+} version 4.3, after you call the ``os.fork()`` method, the
283
+ driver uses the ``os.register_at_fork()`` method to reset its locks and other shared state
284
+ in the child process. Although this reduces the likelihood of a deadlock,
285
+ {+driver-short+} depends
286
+ on libraries that aren't fork-safe in multithreaded applications, including
287
+ `OpenSSL <https://github.com/openssl/openssl/issues/19066>`__ and
288
+ `getaddrinfo(3). <https://man7.org/linux/man-pages/man3/gai_strerror.3.html>`__
289
+ Therefore, a deadlock can still occur.
290
+
291
+ The Linux manual page for `fork(2) <https://man7.org/linux/man-pages/man2/fork.2.html>`__
292
+ also imposes the following restriction:
293
+
294
+ .. blockquote::
295
+
296
+ After a ``fork()`` in a multithreaded program, the child can
297
+ safely call only async-signal-safe functions (see
298
+ `signal-safety(7) <https://man7.org/linux/man-pages/man7/signal-safety.7.html>`__)
299
+ until such time as it calls
300
+ `execve(2) <https://man7.org/linux/man-pages/man2/execve.2.html>`__.
301
+
302
+ Because {+driver-short+} relies on functions that are *not*
303
+ async-signal-safe, it can cause deadlocks or crashes when running in a child
304
+ process.
305
+
306
+ .. tip::
307
+
308
+ For an example of a deadlock in a child process, see
309
+ `PYTHON-3406 <https://jira.mongodb.org/browse/PYTHON-3406>`__ in Jira.
310
+
311
+ For more information about the problems caused by Python locks in
312
+ multithreaded contexts with ``fork()``, see `Issue 6721 <http://bugs.python.org/issue6721>`__
313
+ in the Python Issue Tracker.
314
+
315
+
226
316
API Documentation
227
317
-----------------
228
318
0 commit comments