-
Notifications
You must be signed in to change notification settings - Fork 110
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
connection: expose setters for self-identity STARTUP options #1039
connection: expose setters for self-identity STARTUP options #1039
Conversation
|
6ab7774
to
bffad0d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job on adding comments to connection
module. I always feel like I'm lost trying to understand the logic that resides there.
The commit message mentions:
Settable identity include:
- DRIVER_NAME
- DRIVER_VERSION
- APPLICATION_NAME
- APPLICATION_VERSION
- CLIENT_ID
All five are visible in Cassandra's `system_views.clients` in
`client_options` column.
DRIVER_NAME & DRIVER_VERSION are visible in ScyllaDB's `system.clients`.
Maybe we should add some test cases that verify it? Especially for the newly introduced STARTUP options.
Where does
Please explain in the PR description (and maybe commit message too):
|
tracing::warn!( | ||
"Requested compression <{}> is not supported by the cluster. Falling back to no compression", | ||
compression_str | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when can this happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may happen if SUPPORTED message sent by a node does not contain the particular compression string in the value for the "COMPRESSION"
key.
This enables serializing maps with non-necessarily owned kinds of string, e.g. HashMap<&str, &str> or HashMap<Cow<str>, Cow<str>>.
Majority of, if not all, keys sent in the string map in STARTUP message by the driver are known in the compile time. Some values may not be known at compile time, but still it makes more sense to borrow them from a String rather than clone each time a connection is opened. To reduce needless allocations while preserving ability to add keys and values dynamically, the HashMap type is changed to `HashMap<Cow<'a, str>, Cow<'a, str>>`. This is going to reduce number of allocations upon opening each connection.
The tcp keepalive logic cluttered Connection::new(). I extracted it to a separate function.
bffad0d
to
a8ab3f3
Compare
Rebased on main. |
As these strings bear strict meaning specified by the CQL protocol, it makes sense to have them in one place as constants.
Before, `scylla-rust-driver` name was used. First, we should move to to ScyllaDB because of the established naming. Second, Python driver advertises itself as "ScyllaDB Python Driver", so let's be consistent.
Answering the question there: no, that logic shouldn't be in `Connection::new`. `Connection::new`'s responsibility is to create a connection and make it ready to send CQL frames. OTOH, `open_named_connection` is responsible for connection setup on CQL level, i.e. for OPTIONS/STARTUP handshake and registering for events (if this is a control connection). Informative docstrings are added that convey the above separation.
Compression's name is known in compile time, so let's not allocate it needlessly.
Before, the driver would silently fall back to no compression.
The function is quite big and at the same time crucial for driver's operation, so comments there will bring more ease to future readers.
They come directly from CPP driver. See https://github.com/scylladb/cpp-driver/blob/fa0f27069a625057984d1fa58f434ea99b86c83f/include/cassandra.h#L2916. Allowing users to set arbitrary options could break the driver by overwriting options that bear special meaning, e.g. the shard-aware port. Therefore, I'm against such liberal API. OTOH, we need to expose APPLICATION_NAME, APPLICATION_VERSION and CLIENT_ID for cpp-rust-driver. Does this convince you @Lorak-mmk? |
It does. Please include this explanation in commit message and in a comment. |
a8ab3f3
to
0ea5a4e
Compare
SelfIdentity is intended to group STARTUP options that can be used to uniquely identify driver, application and particular client instance. DRIVER_NAME and DRIVER_VERSION were already present, but they were hardcoded to "scylla-rust-driver" and current crate version, retrieved from Cargo. Now it is possible to set custom values for them, which can be useful for custom driver builds, as well as for drivers running on top of Rust driver (think cpp-rust-driver). The remaining options are inspired by cpp-driver, and added for cpp-rust-driver purposes as well: - APPLICATION_NAME and APPLICATION_VERSION identify a single build of an application using the driver. - CLIENT_ID uniquely identifies a single instance of an application. All the above information are visible in Cassandra in `system_views.clients` in `client_options` column. DRIVER_NAME and DRIVER_VERSION are visible in ScyllaDB in `system.clients`. FAQ Q: Where do APPLICATION_NAME, APPLICATION_VERSION and CLIENT_ID come from? - there are no columns in system.clients dedicated to those attributes, - APPLICATION_NAME / APPLICATION_VERSION are not present in Scylla's source code at all, - only 2 results in Cassandra source is some example in docs; APPLICATION_NAME and APPLICATION_VERSION appears in client_options which is an arbitrary dict where client can send any keys. - driver variables are mentioned in protocol v5, application variables are not. A: The following options are not exposed anywhere in Scylla tables. They come directly from CPP driver, and they are supported in Cassandra. As we want to support as big subset of its API as possible in cpp-rust-driver, I decided to expose API for setting those particular key-value pairs, similarly to what cpp-driver does, and not an API to set arbitrary key-value pairs. Allowing users to set arbitrary options could break the driver by overwriting options that bear special meaning, e.g. the shard-aware port. Therefore, I'm against such liberal API. OTOH, we need to expose APPLICATION_NAME, APPLICATION_VERSION and CLIENT_ID for cpp-rust-driver.
The exposed option enabled setting custom identity that is advertised in STARTUP message by the driver, upon opening each connection. Settable identity include: - DRIVER_NAME - DRIVER_VERSION - APPLICATION_NAME - APPLICATION_VERSION - CLIENT_ID All five are visible in Cassandra's `system_views.clients` in `client_options` column. DRIVER_NAME & DRIVER_VERSION are visible in ScyllaDB's `system.clients`.
0ea5a4e
to
9aadac8
Compare
v2:
|
Resolves: #1028
Motivation
See #1028.
What's done
Preparatory steps
Reduce allocations by using
Cow<str>
for SUPPORTED/STARTUP optionstypes::write_string_map
was genericised to acceptHashMap
s with keys and values being any form of strings, includingCow<str>
.Startup
request now holdsHashMap<Cow<str>, Cow<str>
instead ofHashMap<String, String>
to reduce needless allocations.refactors for readability
setup_tcp_keepalive()
was extracted fromConnection::new()
to reduce clutter.options
module to have them in one place and avoid using plain string literals in code.open_named_connection
should be part ofConnection::new
- answered the question, justified the answer and added docstrings to convey that answer.open_named_connection
, as the function is big and crucial for driver operation, so future readers will benefit.Compression-related small enhancements
Compression
name is now no longer allocated, as its name is a&'static str
anyway.SelfIdentity
struct and APIgrouped self-identity-related STARTUP options in
SelfIdentity
struct. It includes:DRIVER_NAME
DRIVER_VERSION
APPLICATION_NAME
APPLICATION_VERSION
CLIENT_ID
DRIVER_NAME
andDRIVER_VERSION
are set by default to "ScyllaDB Rust Driver" (previously "scylla-rust-driver", changed to be consistent with "ScyllaDB Python Driver") and Rust driver's package version as declared by Cargo. The remaining ones are unset by default.exposed
SelfIdentity
's API inSessionBuilder
, and added a docstring with an example usage.Pre-review checklist
./docs/source/
.Fixes:
annotations to PR description.