Skip to content

feat: add X-LaunchDarkly-Instance-Id header (SDK-2359)#170

Open
keelerm84 wants to merge 2 commits into
mainfrom
mk/sdk-2359-instance-id
Open

feat: add X-LaunchDarkly-Instance-Id header (SDK-2359)#170
keelerm84 wants to merge 2 commits into
mainfrom
mk/sdk-2359-instance-id

Conversation

@keelerm84
Copy link
Copy Markdown
Member

@keelerm84 keelerm84 commented May 13, 2026

Summary

Adds the X-LaunchDarkly-Instance-Id header to every outbound polling, streaming, and event request. Value is a v4 UUID generated once per SDK instance in ConfigBuilder::build and stable for that instance's lifetime.

The UUID is stored on Config (exposed via Config::instance_id() for diagnostics) and threaded into LD's own builders via a new set_instance_id setter on the DataSourceFactory and EventProcessorFactory traits. The setter has a default no-op implementation, so adding it is non-breaking for external implementors of those traits — only LD's own builders (Streaming/Polling/Event) override it.

`Client::build` calls `.to_owned().set_instance_id(id)` on each factory before invoking `.build()`. `HttpFeatureRequesterBuilder` likewise keeps its original `::new()` signature; the instance id is applied via a fluent `with_instance_id()` setter.

`StreamingDataSource::new` and the polling feature requester now treat the instance id as `Option<&str>` and simply skip the header when absent — consistent with the no-op default on the trait setter.

Test plan

  • `cargo fmt --check` — clean
  • `cargo clippy --all-targets -- -D warnings` — clean
  • `cargo test` — 304 unit tests + 12 doctests pass; streaming + polling + event-post instance-id assertions all green
  • Registered `instance-id` capability with the contract-test service
  • CI green

Note

Medium Risk
Touches client construction and request-building for streaming, polling, and event delivery; mistakes could break network communication or tests, but the change is additive and guarded with optional/no-op defaults.

Overview
Adds a per-SDK-instance UUID (X-LaunchDarkly-Instance-Id) to all outbound streaming, polling, and event HTTP requests.

ConfigBuilder::build now generates and stores a stable v4 UUID on Config (exposed via Config::instance_id()), and Client::build injects it into the data source and event processor via new default-no-op set_instance_id hooks on DataSourceFactory and EventProcessorFactory (implemented by LD’s built-in builders). Contract tests register the new instance-id capability, and new unit tests assert the header is present and UUID-v4-shaped for streaming/polling and propagated for event POSTs.

Reviewed by Cursor Bugbot for commit 3fa8c78. Bugbot is set up for automated code reviews on this repo. Configure here.

keelerm84 added 2 commits May 12, 2026 16:29
Generate a v4 UUID once per SDK instance in ConfigBuilder::build and
stamp it on the X-LaunchDarkly-Instance-Id header sent by the streaming
data source, polling feature requester, and event processor. The header
value is stable for the lifetime of the SDK instance and unique across
instances, satisfying SCMP-server-connection-minutes-polling section 1.1.

The instance id is plumbed through the existing DataSourceFactory,
FeatureRequesterFactory (via HttpFeatureRequesterBuilder), and
EventProcessorFactory build paths so streaming, polling, and event
requests all carry the same identifier without per-channel plumbing.
Registers the "instance-id" capability with the contract-test service
so the cross-SDK harness can verify the header on each request type.
DataSourceFactory::build and EventProcessorFactory::build are public
traits; adding an `instance_id` parameter is a breaking change for any
external implementor. This commit reverts that and instead adds a
`set_instance_id(&mut self, String)` method on each trait with a default
no-op implementation, so external implementors are unaffected.

LD-owned builders (StreamingDataSourceBuilder, PollingDataSourceBuilder,
EventProcessorBuilder) override the setter to store the value, and use
it in build() to stamp the `X-LaunchDarkly-Instance-Id` header on
outbound requests. Client::build calls `.to_owned().set_instance_id(id)`
on each builder before invoking build().

HttpFeatureRequesterBuilder::new also reverted to its prior signature;
the instance id is now applied via a fluent with_instance_id() setter.

StreamingDataSource::new and the polling feature requester now treat
the instance id as Option<&str> and skip the header when absent --
consistent with the no-op default on the trait setter.

cargo fmt --check / clippy --all-targets -- -D warnings / cargo test
(304 unit + 12 doctests) all pass.
@keelerm84 keelerm84 requested a review from a team as a code owner May 13, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant