@@ -81,6 +81,10 @@ The IPROTO constants that identify requests that we will mention in this section
81
81
IPROTO_FETCH_SNAPSHOT=0x45
82
82
IPROTO_REGISTER=0x46
83
83
IPROTO_ID=0x49
84
+ IPROTO_WATCH=0x4a
85
+ IPROTO_UNWATCH=0x4b
86
+ IPROTO_EVENT=0x4c
87
+
84
88
85
89
The IPROTO constants that appear within requests or responses that we will describe in this section are:
86
90
@@ -146,7 +150,9 @@ The IPROTO constants that appear within requests or responses that we will descr
146
150
IPROTO_VERSION=0x54
147
151
IPROTO_FEATURES=0x55
148
152
IPROTO_TIMEOUT=0x56
149
- IPROTO_TXN_ISOLATION = 0x59
153
+ IPROTO_EVENT_KEY=0x57
154
+ IPROTO_EVENT_DATA=0x58
155
+ IPROTO_TXN_ISOLATION=0x59
150
156
151
157
152
158
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:
935
941
MsgPack extension support. Clients that don't support this feature will receive
936
942
error responses for :ref: `IPROTO_EVAL <box_protocol-eval >` and
937
943
:ref: `IPROTO_CALL <box_protocol-call >` encoded to string error messages.
938
- - ``IPROTO_FEATURE_WATCHERS = 3 `` -- remote watchers support: IPROTO_WATCH,
939
- IPROTO_UNWATCH, and IPROTO_EVENT commands.
940
-
941
- .. // TODO: document remote watchers commands
944
+ - ``IPROTO_FEATURE_WATCHERS = 3 `` -- remote watchers support: :ref: `IPROTO_WATCH <box_protocol-watch >`,
945
+ :ref: `IPROTO_UNWATCH <box_protocol-unwatch >`, and :ref: `IPROTO_EVENT <box_protocol-event >` commands.
942
946
943
947
IPROTO_ID requests can be processed without authentication.
944
948
949
+ IPROTO_WATCH = 0x4a
950
+ ~~~~~~~~~~~~~~~~~~~
951
+
952
+ See the :ref: `Watchers <box-protocol-watchers >` section below.
953
+
954
+ IPROTO_UNWATCH = 0x4b
955
+ ~~~~~~~~~~~~~~~~~~~~~
956
+
957
+ See the :ref: `Watchers <box-protocol-watchers >` section below.
958
+
959
+ IPROTO_EVENT = 0x4c
960
+ ~~~~~~~~~~~~~~~~~~~
961
+
962
+ See the :ref: `Watchers <box-protocol-watchers >` section below.
963
+
964
+
965
+ .. _box-protocol-watchers :
966
+
967
+ Watchers
968
+ --------
969
+
970
+ The commands below support asynchronous server-client notifications signalled
971
+ with :ref: `box.broadcast() <box-broadcast >`.
972
+ Servers that support the new feature set the ``IPROTO_FEATURE_WATCHERS `` feature in reply to the ``IPROTO_ID `` command.
973
+ When the connection is closed, all watchers registered for it are unregistered.
974
+
975
+ The remote :ref: `watcher <box-watchers >` protocol works in the following way:
976
+
977
+ #. The client sends an ``IPROTO_WATCH `` packet to subscribe to the updates of a specified key defined on the server.
978
+
979
+ #. The server sends an ``IPROTO_EVENT `` packet to the subscribed client after registration.
980
+ The packet contains the key name and its current value.
981
+ After that, the packet is sent every time the key value is updated with
982
+ ``box.broadcast() ``, provided that the last notification was acknowledged (see below).
983
+
984
+ #. After receiving the notification, the client sends an ``IPROTO_WATCH `` packet to acknowledge the notification.
985
+
986
+ #. If the client doesn't want to receive any more notifications, it unsubscribes by sending
987
+ an ``IPROTO_UNWATCH `` packet.
988
+
989
+ All the three request types are asynchronous -- the receiving end doesn't send a packet in reply to any of them.
990
+ Therefore, neither of them has a sync number.
991
+
992
+ .. _box_protocol-watch :
993
+
994
+ IPROTO_WATCH = 0x4a
995
+ ~~~~~~~~~~~~~~~~~~~
996
+
997
+ Registers a new watcher for the given notification key or confirms a notification if the watcher is
998
+ already subscribed.
999
+ The watcher is notified after registration.
1000
+ After that, the notification is sent every time the key is updated.
1001
+ The server doesn't reply to the request unless it fails to parse the packet.
1002
+
1003
+ The body is a 2-item map:
1004
+
1005
+ .. cssclass :: highlight
1006
+ .. parsed-literal ::
1007
+
1008
+ # <size>
1009
+ msgpack(:samp: `{ {MP_UINT unsigned integer = size(<header>) + size(<body>) } } `)
1010
+ # <header>
1011
+ msgpack({
1012
+ IPROTO_REQUEST_TYPE: IPROTO_WATCH
1013
+ })
1014
+ # <body>
1015
+ msgpack({
1016
+ IPROTO_EVENT_KEY: :samp: `{ {MP_STR string } }} `
1017
+ })
1018
+
1019
+ ``IPROTO_EVENT_KEY `` (code 0x56) contains the key name.
1020
+
1021
+ .. _box_protocol-unwatch :
1022
+
1023
+ IPROTO_UNWATCH = 0x4b
1024
+ ~~~~~~~~~~~~~~~~~~~~~
1025
+
1026
+ Unregisters a watcher subscribed to the given notification key.
1027
+ The server doesn't reply to the request unless it fails to parse the packet.
1028
+
1029
+ The body is a 2-item map:
1030
+
1031
+ .. cssclass :: highlight
1032
+ .. parsed-literal ::
1033
+
1034
+ # <size>
1035
+ msgpack(:samp: `{ {MP_UINT unsigned integer = size(<header>) + size(<body>) } } `)
1036
+ # <header>
1037
+ msgpack({
1038
+ IPROTO_REQUEST_TYPE: IPROTO_UNWATCH
1039
+ })
1040
+ # <body>
1041
+ msgpack({
1042
+ IPROTO_EVENT_KEY: :samp: `{ {MP_STR string } }} `
1043
+ })
1044
+
1045
+ ``IPROTO_EVENT_KEY `` (code 0x56) contains a key name.
1046
+
1047
+ .. _box_protocol-event :
1048
+
1049
+ IPROTO_EVENT = 0x4c
1050
+ ~~~~~~~~~~~~~~~~~~~
1051
+
1052
+ Sent by the server to notify a client about an update of a key.
1053
+
1054
+ The body is a 2-item map:
1055
+
1056
+ .. cssclass :: highlight
1057
+ .. parsed-literal ::
1058
+
1059
+ # <size>
1060
+ msgpack(:samp: `{ {MP_UINT unsigned integer = size(<header>) + size(<body>) } } `)
1061
+ # <header>
1062
+ msgpack({
1063
+ IPROTO_REQUEST_TYPE: IPROTO_EVENT
1064
+ })
1065
+ # <body>
1066
+ msgpack({
1067
+ IPROTO_EVENT_KEY: :samp: `{ {MP_STR string } }} `,
1068
+ IPROTO_EVENT_DATA: :samp: `{ {MP_OBJECT value } }} `
1069
+ })
1070
+
1071
+ ``IPROTO_EVENT_KEY `` (code 0x56) contains the key name.
1072
+
1073
+ ``IPROTO_EVENT_DATA `` (code 0x57) contains data sent to a remote watcher.
1074
+ The parameter is optional, the default value is ``nil ``.
945
1075
946
1076
.. _box_protocol-responses :
947
1077
0 commit comments