Skip to content

Document IPROTO watchers #3044

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 5, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 135 additions & 5 deletions doc/dev_guide/internals/box_protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 <box_protocol-eval>` and
:ref:`IPROTO_CALL <box_protocol-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 <box_protocol-watch>`,
:ref:`IPROTO_UNWATCH <box_protocol-unwatch>`, and :ref:`IPROTO_EVENT <box_protocol-event>` commands.

IPROTO_ID requests can be processed without authentication.

IPROTO_WATCH = 0x4a
~~~~~~~~~~~~~~~~~~~

See the :ref:`Watchers <box-protocol-watchers>` section below.

IPROTO_UNWATCH = 0x4b
~~~~~~~~~~~~~~~~~~~~~

See the :ref:`Watchers <box-protocol-watchers>` section below.

IPROTO_EVENT = 0x4c
~~~~~~~~~~~~~~~~~~~

See the :ref:`Watchers <box-protocol-watchers>` section below.


.. _box-protocol-watchers:

Watchers
--------

The commands below support asynchronous server-client notifications signalled
with :ref:`box.broadcast() <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 <box-watchers>` 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IPROTO_WATCH and IPROTO_UNWATCH should probably be listed in the Requests sub-section, because they are user requests. The description could just contain a reference to the Watchers sub-section, like IPROTO_AUTH refers to the Authentication sub-section.

~~~~~~~~~~~~~~~~~~~

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::

# <size>
msgpack(:samp:`{{MP_UINT unsigned integer = size(<header>) + size(<body>)}}`)
# <header>
msgpack({
IPROTO_REQUEST_TYPE: IPROTO_WATCH
})
# <body>
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::

# <size>
msgpack(:samp:`{{MP_UINT unsigned integer = size(<header>) + size(<body>)}}`)
# <header>
msgpack({
IPROTO_REQUEST_TYPE: IPROTO_UNWATCH
})
# <body>
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::

# <size>
msgpack(:samp:`{{MP_UINT unsigned integer = size(<header>) + size(<body>)}}`)
# <header>
msgpack({
IPROTO_REQUEST_TYPE: IPROTO_EVENT
})
# <body>
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:

Expand Down