Skip to content

feat: expose environmentId on EvaluationSeriesContext#242

Merged
keelerm84 merged 1 commit intomainfrom
mk/sdk-2257/env-id
Apr 27, 2026
Merged

feat: expose environmentId on EvaluationSeriesContext#242
keelerm84 merged 1 commit intomainfrom
mk/sdk-2257/env-id

Conversation

@keelerm84
Copy link
Copy Markdown
Member

@keelerm84 keelerm84 commented Apr 27, 2026

Captures the X-Ld-Envid header from LaunchDarkly polling responses and
surfaces the resulting environment ID on EvaluationSeriesContext so
downstream hooks (notably the future OpenTelemetry tracing hook) can
implement OTEL Integration spec §1.2.2.9.2.

Implementation:

  • New internal EnvironmentIdProvider value holder, owned by LDClient and
    injected into the feature requester via $options['_environment_id_provider'].
  • GuzzleFeatureRequester reads X-Ld-Envid on each response (success and
    BadResponseException paths — LD's polling endpoints emit the header on
    4xx/5xx too) and writes it into the holder.
  • LDClient builds EvaluationSeriesContext twice per variation call: once
    before evaluation (env ID may be null on the very first variation in a
    process; populated on subsequent calls) and once after (always sees the
    env ID captured by the call's own fetch).

Caveats baked in:

  • Persistent-store feature requesters (Redis, Consul, DynamoDB) never
    write to the holder, so environmentId stays null when the SDK isn't
    fetching directly from LaunchDarkly.
  • The first variation in a PHP process sees null in beforeEvaluation; the
    fetch happens during evaluation, so the value is only known by the time
    afterEvaluation runs.
  • environmentId on TrackSeriesContext is intentionally deferred; can be
    added later using the same holder if needed.

The FeatureRequester subsystem interface is unchanged — third-party
persistent-store packages do not need to be updated.


Note

Medium Risk
Medium risk because it changes hook context construction during every flag evaluation and adds header-capture behavior to the HTTP feature requester; mistakes could affect hook consumers or error-handling paths.

Overview
Surfaces the LaunchDarkly environmentId to evaluation hooks by adding an optional environmentId field to EvaluationSeriesContext and documenting when it may be null.

Adds an internal EnvironmentIdProvider owned by LDClient, injects it into the feature requester via options, and updates GuzzleFeatureRequester to capture X-Ld-Envid from all polling responses (success and error) so subsequent hook contexts can observe it.

Updates LDClient to build separate EvaluationSeriesContext instances for beforeEvaluation and afterEvaluation, re-reading the provider after evaluation so afterEvaluation can see an env ID captured during the same call. Includes new unit tests covering provider behavior, header capture, and hook-stage visibility across first vs subsequent evaluations.

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

Captures the X-Ld-Envid header from LaunchDarkly polling responses and
surfaces the resulting environment ID on EvaluationSeriesContext so
downstream hooks (notably the future OpenTelemetry tracing hook) can
implement OTEL Integration spec §1.2.2.9.2.

Implementation:

- New internal EnvironmentIdProvider value holder, owned by LDClient and
  injected into the feature requester via $options['_environment_id_provider'].
- GuzzleFeatureRequester reads X-Ld-Envid on each response (success and
  BadResponseException paths — LD's polling endpoints emit the header on
  4xx/5xx too) and writes it into the holder.
- LDClient builds EvaluationSeriesContext twice per variation call: once
  before evaluation (env ID may be null on the very first variation in a
  process; populated on subsequent calls) and once after (always sees the
  env ID captured by the call's own fetch).

Caveats baked in:

- Persistent-store feature requesters (Redis, Consul, DynamoDB) never
  write to the holder, so environmentId stays null when the SDK isn't
  fetching directly from LaunchDarkly.
- The first variation in a PHP process sees null in beforeEvaluation; the
  fetch happens during evaluation, so the value is only known by the time
  afterEvaluation runs.
- environmentId on TrackSeriesContext is intentionally deferred; can be
  added later using the same holder if needed.

The FeatureRequester subsystem interface is unchanged — third-party
persistent-store packages do not need to be updated.
@keelerm84 keelerm84 requested a review from a team as a code owner April 27, 2026 19:01
@keelerm84 keelerm84 merged commit 5fcbce4 into main Apr 27, 2026
46 of 56 checks passed
@keelerm84 keelerm84 deleted the mk/sdk-2257/env-id branch April 27, 2026 19:31
keelerm84 pushed a commit that referenced this pull request Apr 28, 2026
🤖 I have created a release *beep* *boop*
---


##
[6.8.0](6.7.0...6.8.0)
(2026-04-28)


### Features

* add hooks support
([#240](#240))
([77a644d](77a644d))
* expose environmentId on EvaluationSeriesContext
([#242](#242))
([5fcbce4](5fcbce4))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

2 participants