diff --git a/doc/dev_guide/internals/box_protocol.rst b/doc/dev_guide/internals/box_protocol.rst index 4f92264afa..a4c6d84906 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,137 @@ 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. +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 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 the 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 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 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 -- 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: + +IPROTO_WATCH = 0x4a +~~~~~~~~~~~~~~~~~~~ + +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. +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 the key name. + +.. _box_protocol-unwatch: + +IPROTO_UNWATCH = 0x4b +~~~~~~~~~~~~~~~~~~~~~ + +Unregisters a watcher subscribed to the given notification key. +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_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 an update of a key. + +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_OBJECT value}}}` + }) + +``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``. .. _box_protocol-responses: