Fixes user agent feature flags#4635
Conversation
There was a problem hiding this comment.
Pull request overview
This PR brings the Rust Cosmos driver's User-Agent header into line with the cross-language Cosmos SDK contract by advertising enabled client features as a trailing |F<HEX> token (e.g. |F12 for PPCB + HTTP/2). It introduces a new public UserAgentFeatureFlags bitmask type, threads the flags through UserAgent construction and the runtime/driver wiring, and preserves the feature token over the operator suffix when truncating to the 255-byte limit. Drivers share the runtime's Arc<UserAgent> when their computed flags match the runtime baseline, and otherwise recompute their own (e.g. when a driver disables PPCB).
Changes:
- Add public
UserAgentFeatureFlags(bit values consistent with .NET/Java) plusUserAgent::feature_flags()andCosmosDriverRuntime::user_agent_feature_flags(), and append the|F<HEX>token duringUser-Agentconstruction with truncation that protects the token. - Compute runtime-baseline flags from connection-pool HTTP/2 + default PPCB, and recompute per-driver flags from each driver's effective config, sharing the runtime UA only when they match.
- Extensive unit tests and on-the-wire emulator integration tests, plus a driver CHANGELOG entry.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
sdk/cosmos/azure_data_cosmos_driver/src/models/user_agent.rs |
New UserAgentFeatureFlags type/encoding; UserAgent::new/from_* take feature flags and append the token with token-preserving truncation; unit tests. |
sdk/cosmos/azure_data_cosmos_driver/src/models/mod.rs |
Re-exports UserAgentFeatureFlags publicly. |
sdk/cosmos/azure_data_cosmos_driver/src/driver/runtime.rs |
Computes baseline flags, stores them on the runtime, adds user_agent_with_feature_flags, and factors a shared compute_user_agent helper. |
sdk/cosmos/azure_data_cosmos_driver/src/driver/cosmos_driver.rs |
Per-driver flag computation and share-vs-recompute logic in CosmosDriver::new; recompute-branch test. |
sdk/cosmos/azure_data_cosmos/tests/in_memory_emulator_tests/user_agent.rs |
On-the-wire tests asserting the ` |
sdk/cosmos/azure_data_cosmos_driver/CHANGELOG.md |
Documents the feature-flag token and the new public UserAgentFeatureFlags type. |
|
/azp run rust - cosmos - weekly |
|
Azure Pipelines successfully started running 1 pipeline(s). |
| /// assert_eq!(flags.to_string(), "|F12"); // 0x2 | 0x10 == 0x12 | ||
| /// ``` | ||
| #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] | ||
| pub struct UserAgentFeatureFlags(u32); |
There was a problem hiding this comment.
Why does this have to be public? It gets serialized on the wire - so, pub crate shoudl be sufficient?
| /// assert_eq!(flags.to_string(), "|F12"); // 0x2 | 0x10 == 0x12 | ||
| /// ``` | ||
| #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] | ||
| pub struct UserAgentFeatureFlags(u32); |
There was a problem hiding this comment.
Also, why don't you use bitflags - I saw it in the cargo.lock - so, it is used already anyway in the repo? If for aosme reason you want to avoid bitflags - consider also implementing BitAnd and BitAndAssign - also a union like below?
pub const fn union(self, other: Self) -> Self {
Self(self.0 | other.0)
}
FabianMeiswinkel
left a comment
There was a problem hiding this comment.
LGTM except for few NITs
kundadebdatta
left a comment
There was a problem hiding this comment.
LGTM. If you are planning to address the nits, let me know and I should be able to re-approve.
Every Cosmos request sends a User-Agent header that identifies the client. This change adds a small token to that header describing which optional client features are turned on, so the service can understand how clients are configured. The token has the form |F, where each feature is a single bit and the hex value is the sum of all the enabled bits. For example, when HTTP/2 and the per-partition circuit breaker are both on, the header ends with |F12.
At the heart of the change is a new feature-flags type that holds which features are enabled and knows how to render itself as the |F token. It only advertises features whose state is known when the header is built, and the token is appended to the very end of the User-Agent — right after any custom suffix the user configured, with no separating space. Header length is capped at 255 characters; if that limit is reached, the suffix is shortened first so the feature token is always preserved.
The flags are figured out from the client's real settings at two levels. The runtime computes a base set once and reuses it across clients, and each client recomputes from its own configuration. When a client's settings match the defaults (the common case), it reuses the shared header for efficiency; when a client changes a relevant setting, it builds its own header with the correct token. Features that are decided later by the server, rather than at startup, are intentionally left out of the token.