From c88db01c63283c165112e93e73e15cd530aa3726 Mon Sep 17 00:00:00 2001 From: Kseniia Antonova Date: Fri, 22 Jul 2022 13:08:55 +0300 Subject: [PATCH 1/4] Add draft --- doc/dev_guide/internals/box_protocol.rst | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/doc/dev_guide/internals/box_protocol.rst b/doc/dev_guide/internals/box_protocol.rst index 4f92264afa..251ebe1c91 100644 --- a/doc/dev_guide/internals/box_protocol.rst +++ b/doc/dev_guide/internals/box_protocol.rst @@ -1610,6 +1610,41 @@ In other words, there should be a full-mesh connection between the nodes. }) +.. _box-protocol-watchers: + +Watchers +-------- + +The commands below support asynchronous server-client +notifications signaled with ``box.broadcast()``. +Servers that support the new feature set the ``IPROTO_FEATURE_WATCHERS`` +feature bit (bit 3) in reply to the ``IPROTO_ID`` command. +When a connection is closed, all watchers registered for it are unregistered. + +IPROTO_WATCH (code 74) +~~~~~~~~~~~~~~~~~~~~~~ + +Registers a new watcher for the given notification key or acknowledges a notification if a watcher is +already subscribed. +The key name is passed in ``IPROTO_EVENT_KEY`` (code 0x56). +The watcher will be notified unconditionally after registration and then every time the key is updated with +``box.broadcast()`` provided the last notification was acknowledged. +The server doesn't reply to the request unless it fails to parse the packet. + +IPROTO_UNWATCH (code 75) +~~~~~~~~~~~~~~~~~~~~~~~~ + +Unregisters a watcher subscribed for the given notification key. +The key name is passed in ``IPROTO_EVENT_KEY`` (code 0x56). +A server doesn't reply to the request unless it fails to parse the packet. + +IPROTO_EVENT (code 76) +~~~~~~~~~~~~~~~~~~~~~~ + +Sent by the server to notify a client about a key update. +The key name is passed in ``IPROTO_EVENT_KEY`` (code 0x56). +The key data (optional) is passed in ``IPROTO_EVENT_DATA`` (code 0x57). + .. _box_protocol-illustration: Examples From 93cd850c3dadee0072e8676ae9c23698c67a344d Mon Sep 17 00:00:00 2001 From: Kseniia Antonova Date: Fri, 29 Jul 2022 13:34:52 +0300 Subject: [PATCH 2/4] Update iproto watchers --- doc/dev_guide/internals/box_protocol.rst | 160 +++++++++++++++++------ 1 file changed, 120 insertions(+), 40 deletions(-) diff --git a/doc/dev_guide/internals/box_protocol.rst b/doc/dev_guide/internals/box_protocol.rst index 251ebe1c91..6d68597ca7 100644 --- a/doc/dev_guide/internals/box_protocol.rst +++ b/doc/dev_guide/internals/box_protocol.rst @@ -81,6 +81,10 @@ The IPROTO constants that identify requests that we will mention in this section IPROTO_FETCH_SNAPSHOT=0x45 IPROTO_REGISTER=0x46 IPROTO_ID=0x49 + IPROTO_WATCH=0x4a + IPROTO_UNWATCH=0x4b + IPROTO_EVENT=0x4c + The IPROTO constants that appear within requests or responses that we will describe in this section are: @@ -146,7 +150,9 @@ The IPROTO constants that appear within requests or responses that we will descr IPROTO_VERSION=0x54 IPROTO_FEATURES=0x55 IPROTO_TIMEOUT=0x56 - IPROTO_TXN_ISOLATION = 0x59 + IPROTO_EVENT_KEY=0x57 + IPROTO_EVENT_DATA=0x58 + IPROTO_TXN_ISOLATION=0x59 To denote message descriptions we will say ``msgpack(...)`` and within it we will use modified @@ -935,13 +941,122 @@ Available IPROTO_FEATURES are the following: MsgPack extension support. Clients that don't support this feature will receive error responses for :ref:`IPROTO_EVAL ` and :ref:`IPROTO_CALL ` encoded to string error messages. -- ``IPROTO_FEATURE_WATCHERS = 3`` -- remote watchers support: IPROTO_WATCH, - IPROTO_UNWATCH, and IPROTO_EVENT commands. - -.. // TODO: document remote watchers commands +- ``IPROTO_FEATURE_WATCHERS = 3`` -- remote watchers support: :ref:`IPROTO_WATCH `, + :ref:`IPROTO_UNWATCH `, and :ref:`IPROTO_EVENT ` commands. IPROTO_ID requests can be processed without authentication. +.. _box-protocol-watchers: + +Watchers +-------- + +The commands below support asynchronous server-client notifications signaled +with :ref:`box.broadcast() `. +Servers that support the new feature set the ``IPROTO_FEATURE_WATCHERS`` feature in reply to the ``IPROTO_ID`` command. +When a connection is closed, all watchers registered for it are unregistered. + +The remote :ref:`watcher ` protocol works in the following way: + +#. The client sends an ``IPROTO_WATCH`` packet to subscribe to the updates of a specified key defined on the server. + +#. The server sends an ``IPROTO_EVENT`` packet to the subscribed client with the key name and + its current value unconditionally after registration. + After that, the packet is sent every time the key value is updated provided the last notification + was acknowledged (see below). + +#. After receiving a notification, the client sends an ``IPROTO_WATCH`` packet to acknowledge the notification. + +#. If the client doesn't want to receive any more notifications, it unsubscribes by sending + an ``IPROTO_UNWATCH`` packet. + +All the three request types are fully asynchronous -- a receiving end doesn't send a packet in reply to any of them. +Therefore, neither of them has a sync number. + +.. _box_protocol-watch: + +IPROTO_WATCH = 0x4a +~~~~~~~~~~~~~~~~~~~ + +Registers a new watcher for the given notification key or confirms a notification if a watcher is +already subscribed. +The watcher is notified unconditionally after registration. +After that, the notification is sent every time the key is updated with +``box.broadcast()`` provided the last notification was acknowledged. +The server doesn't reply to the request unless it fails to parse the packet. + +The body is a 2-item map: + +.. cssclass:: highlight +.. parsed-literal:: + + # + msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) + #
+ msgpack({ + IPROTO_REQUEST_TYPE: IPROTO_WATCH + }) + # + msgpack({ + IPROTO_EVENT_KEY: :samp:`{{MP_STR string}}}` + }) + +``IPROTO_EVENT_KEY`` (code 0x56) contains a key name. + +.. _box_protocol-unwatch: + +IPROTO_UNWATCH = 0x4b +~~~~~~~~~~~~~~~~~~~~~ + +Unregisters a watcher subscribed to the given notification key. +A server doesn't reply to the request unless it fails to parse the packet. + +The body is a 2-item map: + +.. cssclass:: highlight +.. parsed-literal:: + + # + msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) + #
+ msgpack({ + IPROTO_REQUEST_TYPE: IPROTO_UNWATCH + }) + # + msgpack({ + IPROTO_EVENT_KEY: :samp:`{{MP_STR string}}}` + }) + +``IPROTO_EVENT_KEY`` (code 0x56) contains a key name. + +.. _box_protocol-event: + +IPROTO_EVENT = 0x4c +~~~~~~~~~~~~~~~~~~~~ + +Sent by the server to notify a client about a key update. + +The body is a 2-item map: + +.. cssclass:: highlight +.. parsed-literal:: + + # + msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) + #
+ msgpack({ + IPROTO_REQUEST_TYPE: IPROTO_EVENT + }) + # + msgpack({ + IPROTO_EVENT_KEY: :samp:`{{MP_STR string}}}`, + IPROTO_EVENT_DATA: :samp:`{{MP_NIL nil}}}` + }) + +``IPROTO_EVENT_KEY`` (code 0x56) contains a key name. + +``IPROTO_EVENT_DATA`` (code 0x57) contains data sent to a remote watcher. +The parameter is optional, the default value is ```nil``. .. _box_protocol-responses: @@ -1610,41 +1725,6 @@ In other words, there should be a full-mesh connection between the nodes. }) -.. _box-protocol-watchers: - -Watchers --------- - -The commands below support asynchronous server-client -notifications signaled with ``box.broadcast()``. -Servers that support the new feature set the ``IPROTO_FEATURE_WATCHERS`` -feature bit (bit 3) in reply to the ``IPROTO_ID`` command. -When a connection is closed, all watchers registered for it are unregistered. - -IPROTO_WATCH (code 74) -~~~~~~~~~~~~~~~~~~~~~~ - -Registers a new watcher for the given notification key or acknowledges a notification if a watcher is -already subscribed. -The key name is passed in ``IPROTO_EVENT_KEY`` (code 0x56). -The watcher will be notified unconditionally after registration and then every time the key is updated with -``box.broadcast()`` provided the last notification was acknowledged. -The server doesn't reply to the request unless it fails to parse the packet. - -IPROTO_UNWATCH (code 75) -~~~~~~~~~~~~~~~~~~~~~~~~ - -Unregisters a watcher subscribed for the given notification key. -The key name is passed in ``IPROTO_EVENT_KEY`` (code 0x56). -A server doesn't reply to the request unless it fails to parse the packet. - -IPROTO_EVENT (code 76) -~~~~~~~~~~~~~~~~~~~~~~ - -Sent by the server to notify a client about a key update. -The key name is passed in ``IPROTO_EVENT_KEY`` (code 0x56). -The key data (optional) is passed in ``IPROTO_EVENT_DATA`` (code 0x57). - .. _box_protocol-illustration: Examples From 5fe7a0703f8f8677618d329533b4228db8472917 Mon Sep 17 00:00:00 2001 From: Kseniia Antonova Date: Mon, 1 Aug 2022 09:50:09 +0300 Subject: [PATCH 3/4] Minor additions --- doc/dev_guide/internals/box_protocol.rst | 25 ++++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/doc/dev_guide/internals/box_protocol.rst b/doc/dev_guide/internals/box_protocol.rst index 6d68597ca7..88a5199f78 100644 --- a/doc/dev_guide/internals/box_protocol.rst +++ b/doc/dev_guide/internals/box_protocol.rst @@ -81,9 +81,9 @@ The IPROTO constants that identify requests that we will mention in this section IPROTO_FETCH_SNAPSHOT=0x45 IPROTO_REGISTER=0x46 IPROTO_ID=0x49 - IPROTO_WATCH=0x4a - IPROTO_UNWATCH=0x4b - IPROTO_EVENT=0x4c + IPROTO_WATCH=0x4a + IPROTO_UNWATCH=0x4b + IPROTO_EVENT=0x4c The IPROTO constants that appear within requests or responses that we will describe in this section are: @@ -150,8 +150,8 @@ The IPROTO constants that appear within requests or responses that we will descr IPROTO_VERSION=0x54 IPROTO_FEATURES=0x55 IPROTO_TIMEOUT=0x56 - IPROTO_EVENT_KEY=0x57 - IPROTO_EVENT_DATA=0x58 + IPROTO_EVENT_KEY=0x57 + IPROTO_EVENT_DATA=0x58 IPROTO_TXN_ISOLATION=0x59 @@ -960,17 +960,17 @@ The remote :ref:`watcher ` protocol works in the following way: #. The client sends an ``IPROTO_WATCH`` packet to subscribe to the updates of a specified key defined on the server. -#. The server sends an ``IPROTO_EVENT`` packet to the subscribed client with the key name and - its current value unconditionally after registration. - After that, the packet is sent every time the key value is updated provided the last notification - was acknowledged (see below). +#. The server sends an ``IPROTO_EVENT`` packet to the subscribed client after registration. + The packet contains the key name and its current value. + After that, the packet is sent every time the key value is updated with + ``box.broadcast()`` provided that the last notification was acknowledged (see below). #. After receiving a notification, the client sends an ``IPROTO_WATCH`` packet to acknowledge the notification. #. If the client doesn't want to receive any more notifications, it unsubscribes by sending an ``IPROTO_UNWATCH`` packet. -All the three request types are fully asynchronous -- a receiving end doesn't send a packet in reply to any of them. +All the three request types are asynchronous -- a receiving end doesn't send a packet in reply to any of them. Therefore, neither of them has a sync number. .. _box_protocol-watch: @@ -980,9 +980,8 @@ IPROTO_WATCH = 0x4a Registers a new watcher for the given notification key or confirms a notification if a watcher is already subscribed. -The watcher is notified unconditionally after registration. -After that, the notification is sent every time the key is updated with -``box.broadcast()`` provided the last notification was acknowledged. +The watcher is notified after registration. +After that, the notification is sent every time the key is updated. The server doesn't reply to the request unless it fails to parse the packet. The body is a 2-item map: From e35bae1b57750b94ee5b9e63a776238c9fdd2709 Mon Sep 17 00:00:00 2001 From: Patience Daur Date: Fri, 5 Aug 2022 14:58:25 +0300 Subject: [PATCH 4/4] Apply suggestions from review and proofread text --- doc/dev_guide/internals/box_protocol.rst | 42 ++++++++++++++++-------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/doc/dev_guide/internals/box_protocol.rst b/doc/dev_guide/internals/box_protocol.rst index 88a5199f78..a4c6d84906 100644 --- a/doc/dev_guide/internals/box_protocol.rst +++ b/doc/dev_guide/internals/box_protocol.rst @@ -946,15 +946,31 @@ Available IPROTO_FEATURES are the following: IPROTO_ID requests can be processed without authentication. +IPROTO_WATCH = 0x4a +~~~~~~~~~~~~~~~~~~~ + +See the :ref:`Watchers ` section below. + +IPROTO_UNWATCH = 0x4b +~~~~~~~~~~~~~~~~~~~~~ + +See the :ref:`Watchers ` section below. + +IPROTO_EVENT = 0x4c +~~~~~~~~~~~~~~~~~~~ + +See the :ref:`Watchers ` section below. + + .. _box-protocol-watchers: Watchers -------- -The commands below support asynchronous server-client notifications signaled +The commands below support asynchronous server-client notifications signalled with :ref:`box.broadcast() `. Servers that support the new feature set the ``IPROTO_FEATURE_WATCHERS`` feature in reply to the ``IPROTO_ID`` command. -When a connection is closed, all watchers registered for it are unregistered. +When the connection is closed, all watchers registered for it are unregistered. The remote :ref:`watcher ` protocol works in the following way: @@ -963,14 +979,14 @@ The remote :ref:`watcher ` protocol works in the following way: #. The server sends an ``IPROTO_EVENT`` packet to the subscribed client after registration. The packet contains the key name and its current value. After that, the packet is sent every time the key value is updated with - ``box.broadcast()`` provided that the last notification was acknowledged (see below). + ``box.broadcast()``, provided that the last notification was acknowledged (see below). -#. After receiving a notification, the client sends an ``IPROTO_WATCH`` packet to acknowledge the notification. +#. After receiving the notification, the client sends an ``IPROTO_WATCH`` packet to acknowledge the notification. #. If the client doesn't want to receive any more notifications, it unsubscribes by sending an ``IPROTO_UNWATCH`` packet. -All the three request types are asynchronous -- a receiving end doesn't send a packet in reply to any of them. +All the three request types are asynchronous -- the receiving end doesn't send a packet in reply to any of them. Therefore, neither of them has a sync number. .. _box_protocol-watch: @@ -978,7 +994,7 @@ Therefore, neither of them has a sync number. IPROTO_WATCH = 0x4a ~~~~~~~~~~~~~~~~~~~ -Registers a new watcher for the given notification key or confirms a notification if a watcher is +Registers a new watcher for the given notification key or confirms a notification if the watcher is already subscribed. The watcher is notified after registration. After that, the notification is sent every time the key is updated. @@ -1000,7 +1016,7 @@ The body is a 2-item map: IPROTO_EVENT_KEY: :samp:`{{MP_STR string}}}` }) -``IPROTO_EVENT_KEY`` (code 0x56) contains a key name. +``IPROTO_EVENT_KEY`` (code 0x56) contains the key name. .. _box_protocol-unwatch: @@ -1008,7 +1024,7 @@ IPROTO_UNWATCH = 0x4b ~~~~~~~~~~~~~~~~~~~~~ Unregisters a watcher subscribed to the given notification key. -A server doesn't reply to the request unless it fails to parse the packet. +The server doesn't reply to the request unless it fails to parse the packet. The body is a 2-item map: @@ -1031,9 +1047,9 @@ The body is a 2-item map: .. _box_protocol-event: IPROTO_EVENT = 0x4c -~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~ -Sent by the server to notify a client about a key update. +Sent by the server to notify a client about an update of a key. The body is a 2-item map: @@ -1049,13 +1065,13 @@ The body is a 2-item map: # msgpack({ IPROTO_EVENT_KEY: :samp:`{{MP_STR string}}}`, - IPROTO_EVENT_DATA: :samp:`{{MP_NIL nil}}}` + IPROTO_EVENT_DATA: :samp:`{{MP_OBJECT value}}}` }) -``IPROTO_EVENT_KEY`` (code 0x56) contains a key name. +``IPROTO_EVENT_KEY`` (code 0x56) contains the key name. ``IPROTO_EVENT_DATA`` (code 0x57) contains data sent to a remote watcher. -The parameter is optional, the default value is ```nil``. +The parameter is optional, the default value is ``nil``. .. _box_protocol-responses: