From: Daniele Varrazzo Date: Sat, 6 Sep 2025 21:44:42 +0000 (+0200) Subject: docs: document the changes to notifies generator X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=700d535ffe3a2d31372fcd88f3f86c5d7218b6db;p=thirdparty%2Fpsycopg.git docs: document the changes to notifies generator --- diff --git a/docs/advanced/async.rst b/docs/advanced/async.rst index 177075681..289287b83 100644 --- a/docs/advanced/async.rst +++ b/docs/advanced/async.rst @@ -325,17 +325,34 @@ Because of the way transactions interact with notifications (see |NOTIFY|_ documentation), you should keep the connection in `~Connection.autocommit` mode if you wish to receive or send notifications in a timely manner. -Notifications are received as instances of `Notify`. If you are reserving a -connection only to receive notifications, the simplest way is to consume the -`Connection.notifies` generator. The generator can be stopped using -`!close()`. Starting from Psycopg 3.2, the method supports options to receive -notifications only for a certain time or up to a certain number. - .. note:: You don't need an `AsyncConnection` to handle notifications: a normal blocking `Connection` is perfectly valid. +Notifications are received as instances of the `Notify` object. You can +receive notifications using either the :ref:`notifies generator +` or a :ref:`notifies handler `. + +.. warning:: + + You should use only one of the two methods to receive notifications. + + Since Psycopg 3.2.10 using the generator and handlers at the same time + raises a runtime warning. + + +.. _notifies-generator: + +Notifies generator +^^^^^^^^^^^^^^^^^^ + +If you are reserving a connection only to receive notifications, the simplest +way to receive them is to consume the `Connection.notifies()` generator. The +generator can be stopped using its `!close()` method, or using the parameters +`!timeout` or `!stop_after` to receive notifications only for a certain time +or up to a certain number. + The following example will print notifications and stop when one containing the ``"stop"`` message is received. @@ -369,6 +386,31 @@ You may get output from the Python process such as:: Notify(channel='mychan', payload='stop', pid=961823) there, I stopped +.. warning:: + + The behaviour of the notifies generator has changed slightly as problems + were found: + + - Before Psycopg 3.2.4, notification received between calling + :sql:`LISTEN` and starting the generator were lost. + + - Since :ref:`psycopg-3.2.4` such notifications are captured and yielded + by the generator once it is started. However this introduced a leak + (:ticket:`#1091`) and, if the generator is not regularly used, some + memory is allocated indefinitely. + + - Since :ref:`psycopg-3.2.10` if a handler is registered then + notifications are not captured when the generator is not running. So the + behaviour is similar to pre-3.2.4 but *only if a handler is registered + too*. Therefore, using handlers and generators together starts seeming a + bad idea, hence it is since deprecated. + + +.. _notifies-handlers: + +Notifies handlers +^^^^^^^^^^^^^^^^^ + Alternatively, you can use `~Connection.add_notify_handler()` to register a callback function, which will be invoked whenever a notification is received, during the normal query processing; you will be then able to use the diff --git a/docs/news.rst b/docs/news.rst index bacf4fc01..67f16c51d 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -31,6 +31,8 @@ Psycopg 3.3.0 (unreleased) - Drop support for Python 3.8 (:ticket:`#976`) and 3.9 (:ticket:`#1056`). +.. _psycopg-3.2.10: + Psycopg 3.2.10 (unreleased) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,6 +43,24 @@ Psycopg 3.2.10 (unreleased) (:ticket:`#1108`). - Fix coordination of `~Cursor.executemany()` with other concurrent operations on other cursors (:ticket:`#1130`). +- Fix leak receiving notifications if the `~Connection.notifies()` generator + is not called (:ticket:`#1091`). + + .. warning:: + + This bugfix required the introduction of a change in :ref:`notifies + reception ` behaviour. + + If a notification is received when a handler is registered via + `~Connection.add_notify_handler()` and the `~Connection.notifies()` + generator is not running the notification will not be yielded by the + generator. This is a behaviour similar to before `Psycopg 3.2.4`_, but + *notifications are not lost if no handler is registered*. + + Using both the generator and handlers to receive notifications on the same + connection is therefore deprecated and will now generate a runtime + warning. + - Add support for Python 3.14 (:ticket:`#1053`). - Fix `psycopg_binary.__version__`. @@ -97,11 +117,20 @@ Psycopg 3.2.5 - 3x faster UUID loading thanks to C implementation (:tickets:`#447, #998`). +.. _psycopg-3.2.4: + Psycopg 3.2.4 ^^^^^^^^^^^^^ - Don't lose notifies received whilst the `~Connection.notifies()` iterator is not running (:ticket:`#962`). + + .. warning:: + + If you were using notifications to bridge the time between issuing a LISTEN + on a channel and starting the iterator you might receive duplicate + notifications. + - Make sure that the notifies callback is called during the use of the `~Connection.notifies()` generator (:ticket:`#972`). - Raise the correct error returned by the database (such as `!AdminShutdown`