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
API to read event data without making a subscription #6493
Comments
We could add a flag to IPROTO_WATCH request. UNSUBSCRIBE: true
If the flag is true, tarantool doesn't add the client to the subscriber's list. Cases:
So algo: IPROTO_WATCH[unsubscribe = true] -> return state[IPROTO_EVENT_KEY] |
locker
added a commit
to locker/tarantool
that referenced
this issue
Jun 6, 2023
Straightforward line-by-line rewrite of the local and remote watcher tests from diff to luatest. Needed to add test cases for watch_once. Needed for tarantool#6493 NO_DOC=test NO_CHANGELOG=test
locker
added a commit
to locker/tarantool
that referenced
this issue
Jun 6, 2023
Part of tarantool#6493 @TarantoolBot document Title: Document `box.watch_once()` The function takes a notification key and returns the value currently associated with it. ```yaml tarantool> box.watch_once('foo') --- ... tarantool> box.broadcast('foo', {a = 1, b = 2}) --- ... tarantool> box.watch_once('foo') --- - {'a': 1, 'b': 2} ... ``` The new function can be used instead of `box.watch()` in case the caller only needs to retrieve the current value without subscribing to future changes.
locker
added a commit
to locker/tarantool
that referenced
this issue
Jun 6, 2023
Part of tarantool#6493 @TarantoolBot document Title: Document `IPROTO_WATCH_ONCE` The new request type `IPROTO_WATCH_ONCE` has code 77 and can be used to synchronously fetch the value currently associated with a specified notification key. You can use it instead of `IPROTO_WATCH` if you just need to get the current value without subscribing to future changes. The new request is a standard synchronous request. Like any other synchronous request (for example, `IPROTO_SELECT`), it takes a sync number (`IPROTO_SYNC`) and optionally the desired schema version (`IPROTO_SCHEMA_VERSION`) in the header. The same sync number and the actual schema version are returned in the response header. The request body is supposed to contain a single key `IPROTO_EVENT_KEY` (which is also used by `IPROTO_WATCH`) with a string value that stores the notification key of interest. The actual value is returned in the response body, in the first entry of the `IPROTO_DATA` array. If there's no value associated with a notification key (the key has never been broadcast or was last set to nil), the `IPROTO_DATA` array will be empty. (Note that `IPROTO_DATA` is also used by most other synchronous requests. For example, `IPROTO_SELECT` returns the selected tuple array in it.) For example, suppose a key was broadcast with the following command on the server: ```Lua box.broadcast('foo', {1, 2, 3}) ``` Then `IPROTO_WATCH_ONCE` for `IPROTO_EVENT_KEY` equal to 'foo' will return `IPROTO_DATA' equal to `[[1, 2, 3]]` (an array of one entry containing the current value). If the key didn't exist or was set to nil with ```Lua box.broadcast('foo', nil) ``` then `IPROTO_WATCH_ONCE` would return `IPROTO_DATA` equal to `[]` (an empty array). The request shouldn't normally fail. It may fail only on some sort of system error (out of memory; socket error), on schema version mismatch, or on invalid input. Like `IPROTO_WATCH`, the new request doesn't require authentication. If a server supports the `IPROTO_WATCH_ONCE` request, it'll set the `IPROTO_FEATURE_WATCH_ONCE = 6` bit in the protocol feature mask and report the protocol version >= 6 in response to `IPROTO_ID`.
locker
added a commit
to locker/tarantool
that referenced
this issue
Jun 6, 2023
Duplicating the net.box method constant enum in C and Lua is inconvenient and error-prone. Let's export it to Lua automatically, like we do with IPROTO constants. This will simplify addition of new net.box methods (for example, WATCH_ONCE). While we are at it, - move NETBOX_SELECT_WITH_POS closer to NETBOX_SELECT because they are related so better be defined together; - replace spaces with tabs in the encode/decode method tables for consistency. Needed for tarantool#6493 NO_DOC=refactoring NO_CHANGELOG=refactoring
locker
added a commit
to locker/tarantool
that referenced
this issue
Jun 6, 2023
Closes tarantool#6493 @TarantoolBot document Title: Document `conn:watch_once()` net.box connection method The new method takes a notification key and returns the value currently associated with it. For example, let's assume that a Tarantool server was started with the following script: ```lua box.cfg{listen = 3301} box.broadcast('foo', {1, 2, 3}) ``` Then the `conn:watch_once()` method would yield the following results: ```yaml tarantool> conn = require('net.box').connect(3301) --- ... tarantool> conn:watch_once('foo') --- - [1, 2, 3] ... tarantool> conn:watch_once('bar') --- - null ... ``` The new method can be used instead of `conn:watch()` in case the caller only needs to retrieve the current associated with a notification key value without subscribing to future changes. The method can also take a net.box options table as a second argument. It supports all the standard request options: `is_async`, `return_raw`, `timeout`, and others. They work exactly in the same way as with other net.box method, for example `conn:call`. For example, ```lua local future = conn:watch_once('foo', {is_async = true}) future:wait_result() local obj = conn:watch_once('foo', {return_raw = true}) require('msgpack').is_object(obj) ``` Like `conn:watch()`, the new method doesn't require authentication. Like `conn:watch()`, the new method can be executed in a stream (see `conn:new_stream()`), but it isn't streamlined (i.e. calling it as a stream method has the same effect as calling it as a connection method). The net.box connection will set `conn.peer_protocol_features.watch_once` to true if the remote end supports `conn:watch_once()`. The new method is implemented using the `IPROTO_WATCH_ONCE` request.
locker
added a commit
to locker/tarantool
that referenced
this issue
Jun 6, 2023
Part of tarantool#6493 @TarantoolBot document Title: Document `IPROTO_WATCH_ONCE` The new request type `IPROTO_WATCH_ONCE` has code 77 and can be used to synchronously fetch the value currently associated with a specified notification key. You can use it instead of `IPROTO_WATCH` if you just need to get the current value without subscribing to future changes. The new request is a standard synchronous request. Like any other synchronous request (for example, `IPROTO_SELECT`), it takes a sync number (`IPROTO_SYNC`) and optionally the desired schema version (`IPROTO_SCHEMA_VERSION`) in the header. The same sync number and the actual schema version are returned in the response header. The request body is supposed to contain a single key `IPROTO_EVENT_KEY` (which is also used by `IPROTO_WATCH`) with a string value that stores the notification key of interest. The actual value is returned in the response body, in the first entry of the `IPROTO_DATA` array. If there's no value associated with a notification key (the key has never been broadcast or was last set to nil), the `IPROTO_DATA` array will be empty. (Note that `IPROTO_DATA` is also used by most other synchronous requests. For example, `IPROTO_SELECT` returns the selected tuple array in it.) For example, suppose a key was broadcast with the following command on the server: ```Lua box.broadcast('foo', {1, 2, 3}) ``` Then `IPROTO_WATCH_ONCE` for `IPROTO_EVENT_KEY` equal to 'foo' will return `IPROTO_DATA' equal to `[[1, 2, 3]]` (an array of one entry containing the current value). If the key didn't exist or was set to nil with ```Lua box.broadcast('foo', nil) ``` then `IPROTO_WATCH_ONCE` would return `IPROTO_DATA` equal to `[]` (an empty array). The request shouldn't normally fail. It may fail only on some sort of system error (out of memory; socket error), on schema version mismatch, or on invalid input. Like `IPROTO_WATCH`, the new request doesn't require authentication. Like `IPROTO_WATCH`, the new request can't processed in a stream (`IPROTO_STREAM_ID` must not be set in the request header). If a server supports the `IPROTO_WATCH_ONCE` request, it'll set the `IPROTO_FEATURE_WATCH_ONCE = 6` bit in the protocol feature mask and report the protocol version >= 6 in response to `IPROTO_ID`.
locker
added a commit
to locker/tarantool
that referenced
this issue
Jun 6, 2023
Duplicating the net.box method constant enum in C and Lua is inconvenient and error-prone. Let's export it to Lua automatically, like we do with IPROTO constants. This will simplify addition of new net.box methods (for example, WATCH_ONCE). While we are at it, - move NETBOX_SELECT_WITH_POS closer to NETBOX_SELECT because they are related so better be defined together; - replace spaces with tabs in the encode/decode method tables for consistency. Needed for tarantool#6493 NO_DOC=refactoring NO_CHANGELOG=refactoring
locker
added a commit
to locker/tarantool
that referenced
this issue
Jun 6, 2023
Closes tarantool#6493 @TarantoolBot document Title: Document `conn:watch_once()` net.box connection method The new method takes a notification key and returns the value currently associated with it. For example, let's assume that a Tarantool server was started with the following script: ```lua box.cfg{listen = 3301} box.broadcast('foo', {1, 2, 3}) ``` Then the `conn:watch_once()` method would yield the following results: ```yaml tarantool> conn = require('net.box').connect(3301) --- ... tarantool> conn:watch_once('foo') --- - [1, 2, 3] ... tarantool> conn:watch_once('bar') --- - null ... ``` The new method can be used instead of `conn:watch()` in case the caller only needs to retrieve the current associated with a notification key value without subscribing to future changes. The method can also take a net.box options table as a second argument. It supports all the standard request options: `is_async`, `return_raw`, `timeout`, and others. They work exactly in the same way as with other net.box method, for example `conn:call`. For example, ```lua local future = conn:watch_once('foo', {is_async = true}) future:wait_result() local obj = conn:watch_once('foo', {return_raw = true}) require('msgpack').is_object(obj) ``` Like `conn:watch()`, the new method doesn't require authentication. Like `conn:watch()`, the new method can be executed in a stream (see `conn:new_stream()`), but it isn't streamlined (i.e. calling it as a stream method has the same effect as calling it as a connection method). The net.box connection will set `conn.peer_protocol_features.watch_once` to true if the remote end supports `conn:watch_once()`. The new method is implemented using the `IPROTO_WATCH_ONCE` request.
locker
added a commit
that referenced
this issue
Jun 13, 2023
Straightforward line-by-line rewrite of the local and remote watcher tests from diff to luatest. Needed to add test cases for watch_once. Needed for #6493 NO_DOC=test NO_CHANGELOG=test
locker
added a commit
that referenced
this issue
Jun 13, 2023
Part of #6493 @TarantoolBot document Title: Document `box.watch_once()` The function takes a notification key and returns the value currently associated with it. ```yaml tarantool> box.watch_once('foo') --- ... tarantool> box.broadcast('foo', {a = 1, b = 2}) --- ... tarantool> box.watch_once('foo') --- - {'a': 1, 'b': 2} ... ``` The new function can be used instead of `box.watch()` in case the caller only needs to retrieve the current value without subscribing to future changes.
locker
added a commit
that referenced
this issue
Jun 13, 2023
Part of #6493 @TarantoolBot document Title: Document `IPROTO_WATCH_ONCE` The new request type `IPROTO_WATCH_ONCE` has code 77 and can be used to synchronously fetch the value currently associated with a specified notification key. You can use it instead of `IPROTO_WATCH` if you just need to get the current value without subscribing to future changes. The new request is a standard synchronous request. Like any other synchronous request (for example, `IPROTO_SELECT`), it takes a sync number (`IPROTO_SYNC`) and optionally the desired schema version (`IPROTO_SCHEMA_VERSION`) in the header. The same sync number and the actual schema version are returned in the response header. The request body is supposed to contain a single key `IPROTO_EVENT_KEY` (which is also used by `IPROTO_WATCH`) with a string value that stores the notification key of interest. The actual value is returned in the response body, in the first entry of the `IPROTO_DATA` array. If there's no value associated with a notification key (the key has never been broadcast or was last set to nil), the `IPROTO_DATA` array will be empty. (Note that `IPROTO_DATA` is also used by most other synchronous requests. For example, `IPROTO_SELECT` returns the selected tuple array in it.) For example, suppose a key was broadcast with the following command on the server: ```Lua box.broadcast('foo', {1, 2, 3}) ``` Then `IPROTO_WATCH_ONCE` for `IPROTO_EVENT_KEY` equal to 'foo' will return `IPROTO_DATA' equal to `[[1, 2, 3]]` (an array of one entry containing the current value). If the key didn't exist or was set to nil with ```Lua box.broadcast('foo', nil) ``` then `IPROTO_WATCH_ONCE` would return `IPROTO_DATA` equal to `[]` (an empty array). The request shouldn't normally fail. It may fail only on some sort of system error (out of memory; socket error), on schema version mismatch, or on invalid input. Like `IPROTO_WATCH`, the new request doesn't require authentication. Like `IPROTO_WATCH`, the new request can't processed in a stream (`IPROTO_STREAM_ID` must not be set in the request header). If a server supports the `IPROTO_WATCH_ONCE` request, it'll set the `IPROTO_FEATURE_WATCH_ONCE = 6` bit in the protocol feature mask and report the protocol version >= 6 in response to `IPROTO_ID`.
locker
added a commit
that referenced
this issue
Jun 13, 2023
Duplicating the net.box method constant enum in C and Lua is inconvenient and error-prone. Let's export it to Lua automatically, like we do with IPROTO constants. This will simplify addition of new net.box methods (for example, WATCH_ONCE). While we are at it, - move NETBOX_SELECT_WITH_POS closer to NETBOX_SELECT because they are related so better be defined together; - replace spaces with tabs in the encode/decode method tables for consistency. Needed for #6493 NO_DOC=refactoring NO_CHANGELOG=refactoring
locker
added a commit
that referenced
this issue
Jun 13, 2023
Closes #6493 @TarantoolBot document Title: Document `conn:watch_once()` net.box connection method The new method takes a notification key and returns the value currently associated with it. For example, let's assume that a Tarantool server was started with the following script: ```lua box.cfg{listen = 3301} box.broadcast('foo', {1, 2, 3}) ``` Then the `conn:watch_once()` method would yield the following results: ```yaml tarantool> conn = require('net.box').connect(3301) --- ... tarantool> conn:watch_once('foo') --- - [1, 2, 3] ... tarantool> conn:watch_once('bar') --- - null ... ``` The new method can be used instead of `conn:watch()` in case the caller only needs to retrieve the current associated with a notification key value without subscribing to future changes. The method can also take a net.box options table as a second argument. It supports all the standard request options: `is_async`, `return_raw`, `timeout`, and others. They work exactly in the same way as with other net.box method, for example `conn:call`. For example, ```lua local future = conn:watch_once('foo', {is_async = true}) future:wait_result() local obj = conn:watch_once('foo', {return_raw = true}) require('msgpack').is_object(obj) ``` Like `conn:watch()`, the new method doesn't require authentication. Like `conn:watch()`, the new method can be executed in a stream (see `conn:new_stream()`), but it isn't streamlined (i.e. calling it as a stream method has the same effect as calling it as a connection method). The net.box connection will set `conn.peer_protocol_features.watch_once` to true if the remote end supports `conn:watch_once()`. The new method is implemented using the `IPROTO_WATCH_ONCE` request.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Design document
The ticket #6257 defines subscriptions. The other ticket #6260 defines built-in events available out of the box. One of the features of the subs is that they work without any grants. At least the built-in ones.
It might be useful to have an API to get data by a subscription key without making an actual subscription. It could be used by clients who are not able or don't want to process async events. They might want to poll the data. With the help of such API they wouldn't need to implement stored functions to get stuff like election state, some cfg options, and whatever will be exposed along.
It is possible to emulate it by sending subscribe + unsubscribe requests right after each other, but that means more network data, and more load on the server to create and drop the subscription even though it wasn't really needed.
The text was updated successfully, but these errors were encountered: