-
Notifications
You must be signed in to change notification settings - Fork 17
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
feat: client identification headers #89
base: main
Are you sure you want to change the base?
Conversation
@@ -36,10 +43,15 @@ where | |||
Ok(HTTP { | |||
client: C::default(), | |||
app_name, | |||
sdk_version: get_sdk_version(), | |||
connection_id: Uuid::new_v4().into(), | |||
instance_id, | |||
authorization, | |||
authorization_header: C::build_header("authorization")?, | |||
app_name_header: C::build_header("appname")?, |
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 header will be deprecated in the next version since we're moving towards standardized x-unleash
headers
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.
I haven't seen these headers before. Are they already in production somewhere?
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.
If not, please see https://datatracker.ietf.org/doc/html/rfc6648 - x- is a deprecated pattern and we SHOULD NOT introduce it now.
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.
We started adding them 2 weeks ago for our internal purposes. Those are not useful to Unleash users and only used internally so we have more freedom in changing them in future. You raise a good point with the x-prefix. I'll discuss it with the team tomorrow (if it's worth changing it given all other SDKs already support it). We may have some legacy users who require the x- prefix in their network infra.
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.
Update: after internal discussions we decided to drop the x- prefix and we'll stick to unleash-. The spec link you sent is convincing :)
@@ -101,7 +102,7 @@ impl Default for Registration { | |||
Self { | |||
app_name: "".into(), | |||
instance_id: "".into(), | |||
sdk_version: "unleash-client-rust-0.1.0".into(), |
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 version was out of sync with the cargo version
- also in out backend we assume a different format
unleash-client-rust:version
I decided to create a function capturing those requirements
src/version.rs
Outdated
@@ -0,0 +1,23 @@ | |||
use std::env; | |||
|
|||
// include version into the binary at compile time |
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.
It is very important to read the version env var at compile time so that it's hardcoded into the final binary for predictability and reading the library version and not the version of the application using this library
src/http.rs
Outdated
@@ -36,10 +43,15 @@ where | |||
Ok(HTTP { | |||
client: C::default(), | |||
app_name, | |||
sdk_version: get_sdk_version(), | |||
connection_id: Uuid::new_v4().into(), |
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.
I decided to instantiate the UUID when we create our HTTP client since we don't need it anywhere else. Since this is intended for internal tracking purposes of SDK HTTP connection and users should not override it I put it here instead of passing it from the outside.
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.
Does this make sense for the Rust SDK as-is? A new UUID every process restart doesn't provide much value. (And indeed for k8s we'd see 10's of thousands of clients a week...
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.
We've been using it for 2 weeks already and it provides a lot of value to us on the server side. We want to know how many instances are created. We track it in hourly buckets with hyperloglog so very high numbers are not a problem and they help us in capacity planning and debugging of misconfigured SDK clients (with per request scope objects)
Cargo.toml
Outdated
@@ -62,6 +62,7 @@ rustversion = "1.0.7" | |||
serde_json = "1.0.68" | |||
serde_plain = "1.0.0" | |||
surf = { version = "2.3.1", optional = true } | |||
uuid = { version = "0.8.2", features = ["v4"] } |
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.
highest version running on rustc 1.60.0. I also considered embedding uuid generation function into the library itself but my first option is to use a lib.
@@ -62,6 +62,7 @@ rustversion = "1.0.7" | |||
serde_json = "1.0.68" | |||
serde_plain = "1.0.0" | |||
surf = { version = "2.3.1", optional = true } | |||
uuid = { version = "1.11.0", features = ["v4"] } |
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.
latest 1.60.0 supported version
@@ -91,6 +92,7 @@ futures = "0.3.17" | |||
maplit = "1.0.2" | |||
num_cpus = "1.13.0" | |||
simple_logger = "2.1.0" | |||
regex = "1.9.6" |
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.
latest 1.60.0 supported version
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.
I'm a 👍 here.
but we will have to hash out the MSRV details. I know @sighphyre is already looking |
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.
I will read the code more shortly, but a quick note:
x- headers are deprecated.
x-unleash-appname: the name of the application that is using the client.
x-unleash-connection-id: a unique identifier for the current instance of the client generated by the built-in UUID lib
x-unleash-sdk: sdk information in the format unleash-client-android:
should instead be something without x-.
instance_id: String, | ||
connection_id: String, |
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 is being used as a client id, not per-connection
connection_id: String, | |
client_id: String, |
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.
We have an established convention across all SDKs so I'd prefer to have one name for this. We call it connection_id because we're also adding streaming support and we want to treat a long lived SSE stream and interval/polling connections from the same instance as one logical connection.
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.
I agree that consistency matters, however it is still mismatched with the code behaviour.
Personally, I would name it differently to capture these nuances in the other clients, but thats out of my hands :)
I will ask for a comment though, explaining why this is considered a 'connection id', even though its not per HTTP connection, and not unique per process.
This has no test coverage; someone could change it later and we'd have nothing capturing what or why they shouldn't. |
@rbtcollins Thanks for a thorough review. |
About the changes
This PR adds standardised client identification headers to the feature and metrics calls that the client makes to Unleash. The headers are:
x-unleash-appname
: the name of the application that is using the client.x-unleash-connection-id
: a unique identifier for the current instance of the client generated by the built-in UUID libx-unleash-sdk
: sdk information in the formatunleash-client-android:<version>
All the headers are intended for the Unleash team so clients should not be affected.
The main use cases we have are:
Important files
Discussion points
I added 2 new dependencies deliberately choosing versions that work on 1.60.0. However some transitive dependencies of existing dependencies have changed and require 1.60.3. I found that any dependency update will trigger this error. Maybe we can update MSRV?
Also we have a new way of adding library version at compile time from the Cargo file.