From 06e7649da1c5772f919b15ad85142a26e25610b2 Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Mon, 15 Jun 2015 17:49:44 -0400 Subject: [PATCH] PYTHON-859 - Start dev guide with entry on PeriodicExecutor. --- doc/developer/index.rst | 9 ++++ doc/developer/periodic_executor.rst | 69 ++++++++++++++++++++++++++ doc/index.rst | 5 +- doc/static/periodic-executor-refs.dot | 16 ++++++ doc/static/periodic-executor-refs.png | Bin 0 -> 35654 bytes pymongo/periodic_executor.py | 2 +- 6 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 doc/developer/index.rst create mode 100644 doc/developer/periodic_executor.rst create mode 100644 doc/static/periodic-executor-refs.dot create mode 100644 doc/static/periodic-executor-refs.png diff --git a/doc/developer/index.rst b/doc/developer/index.rst new file mode 100644 index 000000000..2ce1e0536 --- /dev/null +++ b/doc/developer/index.rst @@ -0,0 +1,9 @@ +Developer Guide +=============== + +Technical guide for contributors to PyMongo. + +.. toctree:: + :maxdepth: 1 + + periodic_executor diff --git a/doc/developer/periodic_executor.rst b/doc/developer/periodic_executor.rst new file mode 100644 index 000000000..b794ad80a --- /dev/null +++ b/doc/developer/periodic_executor.rst @@ -0,0 +1,69 @@ +Periodic Executors +================== + +.. currentmodule:: pymongo + +PyMongo implements a :class:`~periodic_executor.PeriodicExecutor` for two +purposes: as the background thread for :class:`~monitor.Monitor`, and to +regularly check if there are `OP_KILL_CURSORS` messages that must be sent to the server. + +Monitoring +---------- + +For each server in the topology, :class:`~topology.Topology` launches a +monitor thread. This thread must not prevent the topology from being freed, +so it weakrefs the topology. Furthermore, it uses a weakref callback to close +itself promptly when the topology is freed. + +Solid lines represent strong references, dashed lines weak ones: + +.. generated with graphviz from periodic-executor-refs.dot + +.. image:: ../static/periodic-executor-refs.png + +See `Stopping Executors`_ below for an explanation of ``_EXECUTORS``. + +Killing Cursors +--------------- + +An incompletely iterated :class:`~cursor.Cursor` on the client represents an +open cursor object on the server. In code like this, we lose a reference to +the cursor before finishing iteration:: + + for doc in collection.find(): + raise Exception() + +We try to send an `OP_KILL_CURSORS` to the server to tell it to clean up the +server-side cursor. But we must not take any locks directly from the cursor's +destructor (see `PYTHON-799 `_), +so we cannot safely use the PyMongo data structures required to send a message. +The solution is to add the cursor's id to an array on the +:class:`~mongo_client.MongoClient` without taking any locks. + +Each client has a :class:`~periodic_executor.PeriodicExecutor` devoted to +checking the array for cursor ids. Any it sees are the result of cursors that +were freed while the server-side cursor was still open. The executor can safely +take the locks it needs in order to send the `OP_KILL_CURSORS` message. + +Stopping Executors +------------------ + +Just as :class:`~cursor.Cursor` must not take any locks from its destructor, +neither can :class:`~mongo_client.MongoClient` and :class:`~topology.Topology`. +Thus, although the client calls :meth:`close` on its kill-cursors thread, and +the topology calls :meth:`close` on all its monitor threads, the :meth:`close` +method cannot actually call :meth:`wake` on the executor, since :meth:`wake` +takes a lock. + +Instead, executors wake very frequently to check if ``self.close`` is set, +and if so they exit. + +A thread can log spurious errors if it wakes late in the Python interpreter's +shutdown sequence, so we try to join threads before then. Each periodic +executor (either a monitor or a kill-cursors thread) adds a weakref to itself +to a set called ``_EXECUTORS``, in the ``periodic_executor`` module. + +An `exit handler`_ runs on shutdown and tells all executors to stop, then +tries (with a short timeout) to join all executor threads. + +.. _exit handler: https://docs.python.org/2/library/atexit.html diff --git a/doc/index.rst b/doc/index.rst index 471224cd5..ada6a87ee 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -32,6 +32,9 @@ everything you need to know to use **PyMongo**. A listing of Python tools and libraries that have been written for MongoDB. +:doc:`developer/index` + Developer guide for contributors to PyMongo. + Getting Help ------------ If you're having trouble or have questions about PyMongo, the best place to ask is the `MongoDB user group `_. Once you get an answer, it'd be great if you could work it back into this documentation and contribute! @@ -88,4 +91,4 @@ Indices and tables contributors changelog python3 - + developer/index diff --git a/doc/static/periodic-executor-refs.dot b/doc/static/periodic-executor-refs.dot new file mode 100644 index 000000000..003af9f57 --- /dev/null +++ b/doc/static/periodic-executor-refs.dot @@ -0,0 +1,16 @@ +digraph "Monitor and PeriodicExecutor" { + // Strong references. + topology -> server + server -> monitor + monitor -> executor + executor -> "target()" + "target()" -> self_ref + + // Weak references + edge [style="dashed"]; + + self_ref -> monitor [curved=true] + monitor -> topology + executor -> thread + _EXECUTORS -> executor +} diff --git a/doc/static/periodic-executor-refs.png b/doc/static/periodic-executor-refs.png new file mode 100644 index 0000000000000000000000000000000000000000..9530a566978335ff005c98c4ce550b367c50bcb7 GIT binary patch literal 35654 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 literal 0 HcmV?d00001 diff --git a/pymongo/periodic_executor.py b/pymongo/periodic_executor.py index c630b9258..a71b378f0 100644 --- a/pymongo/periodic_executor.py +++ b/pymongo/periodic_executor.py @@ -70,7 +70,7 @@ class PeriodicExecutor(object): callback; see monitor.py. Since this can be called from a weakref callback during garbage - collection it must take no locks! + collection it must take no locks! That means it cannot call wake(). """ self._stopped = True