Repository navigation
feat: conform FDv1 streaming and polling data sources to the RETRY spec - #2059
Conversation
|
@launchdarkly/js-sdk-common size report |
|
@launchdarkly/js-client-sdk-common size report |
Drive the server SDK's FDv1 streaming and polling reconnection from the reusable retry controller via an injected retry-delay strategy: - Classify HTTP and transport failures per the RETRY table; no failure is terminal, so 401/403 now retry in the extended regime instead of permanently stopping. - Surface data-source failures as logs only, keeping the error-event channel reserved for terminal conditions. - Restart the stream and reschedule polling on malformed or empty payloads, recording them as normal failures and guarding against a duplicate reconnect when several arrive in one parse pass. - Wrap deserialization so structurally invalid data cannot escape and stall the data source. - Advertise FDv1 retry-conformance contract-test capabilities and add a nightly workflow that runs the long-running suite.
b77a558 to
f1af537
Compare
…classification Add unit coverage for RETRY behaviors that the shared contract tests do not exercise: - A scheduled reconnect (streaming) and the next poll (polling) are cancelled when the data source is stopped before the timer fires. - A transport error with no HTTP status is classified as a normal, retryable failure and logged at warn level, for both data sources. - A self-initiated stream restart after malformed data records exactly one failure, so the SDK's own close is not counted a second time.
… optional The shared EventSourceInitDict now makes initialRetryDelayMillis and retryResetIntervalMillis optional, since an injected retryDelayStrategy can replace the built-in backoff. The browser event source still uses the built-in backoff, so default those bounds to the standard streaming values (1s initial, 60s reset) where DefaultBackoff is constructed. The browser always supplies concrete values, so behavior is unchanged; the defaults only satisfy the widened type.
|
@launchdarkly/js-client-sdk size report |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9fbd27a. Configure here.
joker23
left a comment
There was a problem hiding this comment.
We should bump the eventsource package version.
…eedback - Restore maxBackoffMillis/jitterRatio in NodeRequests.createEventSource. These configure the built-in (default) backoff that the FDv2 streaming source relies on, since it injects no custom retryDelayStrategy; removing them regressed its 30s cap and jitter. - Bump the launchdarkly-eventsource pin to 2.3.0 (the release that consumes the injected retryDelayStrategy for FDv1 streaming). - Make _retryAndHandleError return void; the errorFilter callback returns a literal true, since the transport still needs a boolean to decide whether to reconnect and every failure is now recoverable. - Document the reserved, currently-unused _errorHandler on both processors. - Reword the EventSource init-dict docs: the built-in options configure the default retry-delay strategy and are ignored when a custom one is injected. - Drop RETRY-spec requirement numbers from test comments. Note: yarn.lock is intentionally not yet updated to 2.3.0 (registry propagation is still catching up), so CI's install step will fail until it is. That red is deliberate: it keeps the PR from being merged while the streaming path is still pinned to a version that ignores the injected strategy.
npmMinimalAgeGate (72h) blocks installing any package version published within the last three days, which prevents the launchdarkly-eventsource 2.3.0 pin (and every future release) from installing until it ages out. Exempt the first-party launchdarkly-eventsource package from the gate by exact name, covering all versions. An exact name is used rather than a launchdarkly-* glob so the exemption cannot match an attacker-squatted unscoped package.
The #2059 squash commit touched a browser file, so release-please attributed its RETRY feat note to js-client-sdk. The actual browser change was defaulting the built-in EventSource backoff bounds; reclassify it as a Bug Fix with an accurate note.
🤖 I have created a release *beep* *boop* --- <details><summary>akamai-edgeworker-sdk-common: 2.0.38</summary> ## [2.0.38](akamai-edgeworker-sdk-common-v2.0.37...akamai-edgeworker-sdk-common-v2.0.38) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from ^2.21.6 to ^2.22.0 </details> <details><summary>akamai-server-base-sdk: 3.0.39</summary> ## [3.0.39](akamai-server-base-sdk-v3.0.38...akamai-server-base-sdk-v3.0.39) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/akamai-edgeworker-sdk-common bumped from ^2.0.37 to ^2.0.38 </details> <details><summary>akamai-server-edgekv-sdk: 1.4.41</summary> ## [1.4.41](akamai-server-edgekv-sdk-v1.4.40...akamai-server-edgekv-sdk-v1.4.41) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/akamai-edgeworker-sdk-common bumped from ^2.0.37 to ^2.0.38 * @launchdarkly/js-server-sdk-common bumped from ^2.21.6 to ^2.22.0 </details> <details><summary>client-testing-plugin: 1.0.20</summary> ## [1.0.20](client-testing-plugin-v1.0.19...client-testing-plugin-v1.0.20) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk-common bumped from 1.32.2 to 1.32.3 * devDependencies * @launchdarkly/js-client-sdk bumped from 4.10.4 to 4.11.0 * @launchdarkly/react-sdk bumped from 4.1.21 to 4.1.22 * peerDependencies * @launchdarkly/js-client-sdk bumped from ^4.9.1 to ^4.11.0 * @launchdarkly/react-sdk bumped from ^4.1.4 to ^4.1.22 </details> <details><summary>cloudflare-server-sdk: 2.7.40</summary> ## [2.7.40](cloudflare-server-sdk-v2.7.39...cloudflare-server-sdk-v2.7.40) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common-edge bumped from 2.6.35 to 2.6.36 </details> <details><summary>fastly-server-sdk: 0.2.30</summary> ## [0.2.30](fastly-server-sdk-v0.2.29...fastly-server-sdk-v0.2.30) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from 2.21.6 to 2.22.0 </details> <details><summary>jest: 1.0.32</summary> ## [1.0.32](jest-v1.0.31...jest-v1.0.32) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/react-native-client-sdk bumped from ~10.20.4 to ~10.20.5 </details> <details><summary>js-client-sdk: 4.11.0</summary> ## [4.11.0](js-client-sdk-v4.10.4...js-client-sdk-v4.11.0) (2026-09-30) ### Bug Fixes * default the built-in EventSource backoff bounds when they are omitted ([#2059](#2059)) ([a80e7ee](a80e7ee)) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk-common bumped from 1.32.2 to 1.32.3 </details> <details><summary>js-client-sdk-common: 1.32.3</summary> ## [1.32.3](js-client-sdk-common-v1.32.2...js-client-sdk-common-v1.32.3) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-sdk-common bumped from 2.27.0 to 2.28.0 </details> <details><summary>js-sdk-common: 2.28.0</summary> ## [2.28.0](js-sdk-common-v2.27.0...js-sdk-common-v2.28.0) (2026-09-30) ### Features * conform FDv1 streaming and polling data sources to the RETRY spec ([#2059](#2059)) ([a80e7ee](a80e7ee)) </details> <details><summary>js-server-sdk-common: 2.22.0</summary> ## [2.22.0](js-server-sdk-common-v2.21.6...js-server-sdk-common-v2.22.0) (2026-09-30) ### Features * conform FDv1 streaming and polling data sources to the RETRY spec ([#2059](#2059)) ([a80e7ee](a80e7ee)) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-sdk-common bumped from 2.27.0 to 2.28.0 </details> <details><summary>js-server-sdk-common-edge: 2.6.36</summary> ## [2.6.36](js-server-sdk-common-edge-v2.6.35...js-server-sdk-common-edge-v2.6.36) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from 2.21.6 to 2.22.0 </details> <details><summary>node-client-sdk: 4.1.5</summary> ## [4.1.5](node-client-sdk-v4.1.4...node-client-sdk-v4.1.5) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk-common bumped from 1.32.2 to 1.32.3 </details> <details><summary>node-server-sdk: 9.14.0</summary> ## [9.14.0](node-server-sdk-v9.13.8...node-server-sdk-v9.14.0) (2026-09-30) ### Features * conform FDv1 streaming and polling data sources to the RETRY spec ([#2059](#2059)) ([a80e7ee](a80e7ee)) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from 2.21.6 to 2.22.0 </details> <details><summary>node-server-sdk-dynamodb: 6.2.45</summary> ## [6.2.45](node-server-sdk-dynamodb-v6.2.44...node-server-sdk-dynamodb-v6.2.45) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/node-server-sdk bumped from 9.13.8 to 9.14.0 * peerDependencies * @launchdarkly/node-server-sdk bumped from >=9.11.3 to >=9.14.0 </details> <details><summary>node-server-sdk-otel: 1.3.32</summary> ## [1.3.32](node-server-sdk-otel-v1.3.31...node-server-sdk-otel-v1.3.32) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/node-server-sdk bumped from 9.13.8 to 9.14.0 * peerDependencies * @launchdarkly/node-server-sdk bumped from >=9.11.3 to >=9.14.0 </details> <details><summary>node-server-sdk-redis: 4.2.44</summary> ## [4.2.44](node-server-sdk-redis-v4.2.43...node-server-sdk-redis-v4.2.44) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/node-server-sdk bumped from 9.13.8 to 9.14.0 * peerDependencies * @launchdarkly/node-server-sdk bumped from >=9.11.3 to >=9.14.0 </details> <details><summary>openfeature-cloudflare-server: 1.0.3</summary> ## [1.0.3](openfeature-cloudflare-server-v1.0.2...openfeature-cloudflare-server-v1.0.3) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/openfeature-js-server-common bumped from 2.0.3 to 2.0.4 * devDependencies * @launchdarkly/cloudflare-server-sdk bumped from 2.7.39 to 2.7.40 * peerDependencies * @launchdarkly/cloudflare-server-sdk bumped from ^2.7.0 to ^2.7.40 </details> <details><summary>openfeature-js-server-common: 2.0.4</summary> ## [2.0.4](openfeature-js-server-common-v2.0.3...openfeature-js-server-common-v2.0.4) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-sdk-common bumped from 2.27.0 to 2.28.0 </details> <details><summary>openfeature-node-server: 2.0.8</summary> ## [2.0.8](openfeature-node-server-v2.0.7...openfeature-node-server-v2.0.8) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/openfeature-js-server-common bumped from 2.0.3 to 2.0.4 * devDependencies * @launchdarkly/node-server-sdk bumped from 9.13.8 to 9.14.0 * peerDependencies * @launchdarkly/node-server-sdk bumped from ^9.0.0 to ^9.14.0 </details> <details><summary>react-native-client-sdk: 10.20.5</summary> ## [10.20.5](react-native-client-sdk-v10.20.4...react-native-client-sdk-v10.20.5) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk-common bumped from 1.32.2 to 1.32.3 </details> <details><summary>react-sdk: 4.1.22</summary> ## [4.1.22](react-sdk-v4.1.21...react-sdk-v4.1.22) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk bumped from ^4.10.4 to ^4.11.0 * @launchdarkly/js-server-sdk-common bumped from ^2.21.6 to ^2.22.0 </details> <details><summary>server-sdk-ai: 2.0.9</summary> ## [2.0.9](server-sdk-ai-v2.0.8...server-sdk-ai-v2.0.9) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/js-server-sdk-common bumped from 2.21.6 to 2.22.0 * peerDependencies * @launchdarkly/js-server-sdk-common bumped from ^2.0.0 to ^2.22.0 </details> <details><summary>server-sdk-ai-langchain: 0.8.19</summary> ## [0.8.19](server-sdk-ai-langchain-v0.8.18...server-sdk-ai-langchain-v0.8.19) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/server-sdk-ai bumped from ^2.0.8 to ^2.0.9 * peerDependencies * @launchdarkly/server-sdk-ai bumped from ^1.1.1 to ^2.0.9 </details> <details><summary>server-sdk-ai-openai: 0.7.19</summary> ## [0.7.19](server-sdk-ai-openai-v0.7.18...server-sdk-ai-openai-v0.7.19) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/js-server-sdk-common bumped from 2.21.6 to 2.22.0 * @launchdarkly/server-sdk-ai bumped from ^2.0.8 to ^2.0.9 * peerDependencies * @launchdarkly/server-sdk-ai bumped from ^1.1.1 to ^2.0.9 </details> <details><summary>server-sdk-ai-vercel: 0.7.19</summary> ## [0.7.19](server-sdk-ai-vercel-v0.7.18...server-sdk-ai-vercel-v0.7.19) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/server-sdk-ai bumped from ^2.0.8 to ^2.0.9 * peerDependencies * @launchdarkly/server-sdk-ai bumped from ^1.1.1 to ^2.0.9 </details> <details><summary>shopify-oxygen-sdk: 0.1.28</summary> ## [0.1.28](shopify-oxygen-sdk-v0.1.27...shopify-oxygen-sdk-v0.1.28) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from 2.21.6 to 2.22.0 </details> <details><summary>vercel-server-sdk: 1.3.63</summary> ## [1.3.63](vercel-server-sdk-v1.3.62...vercel-server-sdk-v1.3.63) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common-edge bumped from 2.6.35 to 2.6.36 </details> <details><summary>vue-client-sdk: 3.0.3</summary> ## [3.0.3](vue-client-sdk-v3.0.2...vue-client-sdk-v3.0.3) (2026-09-30) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk bumped from 4.10.4 to 4.11.0 </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > This is a **Release Please** cut that bumps versions across the monorepo (manifest, `package.json`, changelogs, and embedded `x-release-please-version` strings) so previously merged work ships under new package versions. > > The **functional theme** behind the bumps is [#2059](#2059): **FDv1 streaming and polling** in `@launchdarkly/js-sdk-common` / `@launchdarkly/js-server-sdk-common` now follow the **RETRY** reconnect/backoff spec, carried into **`@launchdarkly/node-server-sdk` 9.14.0** and client stacks via `@launchdarkly/js-client-sdk-common` **1.32.3**. **`@launchdarkly/js-client-sdk` 4.11.0** also documents a fix to **default built-in EventSource backoff bounds** when options omit them. > > Everything else in the diff is **dependency alignment and patch/minor releases** (React/Vue/RN wrappers, edge SDKs, OpenFeature providers, AI providers, DynamoDB/Redis/OTel plugins, examples)—no additional application logic beyond version metadata in this PR. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit dd6076f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Todd Anderson <tanderson@launchdarkly.com>

Summary
Wires the reusable retry controller (added to
@launchdarkly/js-sdk-commonin #2045) into the Node server SDK's FDv1 streaming and polling data sources, bringing them into conformance with the RETRY spec. Streaming injects the controller through the js-eventsourceretryDelayStrategyseam; polling drives the controller from its own scheduled loop. This replaces the old recoverable / permanent-stop model.Scope is FDv1 streaming + polling in the Node server SDK only. FDv2 (the composite data source and its synchronizers) is intentionally untouched and will be conformed in a future effort.
Behavior changes (operator-facing)
waitForInitialization()resolves on success and rejects only on its own timeout or onclose(); it no longer rejects immediately with "Authentication failed…" on a 401. A misconfigured client keeps retrying and stays uninitialized until the timeout.warnfor normal,error-level for unexpected/invalid-data), with the reconnect delay in the streamingonretryinginfo line. The'error'/'failed'events and init-rejection remain reserved for genuinely terminal conditions (today, only the untouched FDv2 composite reaches them).Versioning:
feat:/ minor for all affected packages — matching how Go (7.16.0), Java (7.16.0), and .NET (8.17.0) each shipped RETRY conformance (minor, behavior changes documented in the PR, not marked breaking).What's here
packages/shared/common—EventSourceRetryDelayStrategytype + optionalretryDelayStrategyon the platformEventSourceInitDict(the injection seam;initialRetryDelayMillis/retryResetIntervalMillismade optional since they're unused under injection).packages/shared/sdk-server—StreamingProcessorandPollingProcessorrewired to the controller (classification, always-retry, malformed-data recovery via a guarded close-and-recreate, completion-anchored polling).LDClientImplis intentionally left unchanged; the reserved'error'/'failed'/init-reject path is untouched.packages/sdk/server-node—NodeRequestspasses the strategy through; contract-test capabilitiesretry-conformance-fdv1-streaming/-polling; a nightly workflow (server-node-nightly.yaml) that runs the long-running RETRY suite (schedule + manual dispatch, no push trigger).Testing
Unit suites green:
@launchdarkly/js-server-sdk-common(1053 pass) and@launchdarkly/node-server-sdk(70 pass), covering the classification ladders (via the controller), the streaming close+recreate on malformed data (including a guard against a duplicate reconnect and a deserialization that throws), polling recovery,stop()-cancels-a-pending-retry interruptibility, status-less transport-error classification, single-failure accounting for a self-initiated restart, the reserved terminal'error'/'failed'/init-reject path, and the restoredonretryingdelay log. The behavioral RETRY conformance itself is validated by the harness in the nightly (long-running), which is a post-merge / manual-dispatch activity.Part of SDK-2790.
Note
Overview
Brings FDv1 streaming and polling in the Node server SDK in line with the RETRY spec by driving reconnect/poll timing from shared
RetryStateinstead of permanent vs recoverable stops.Streaming injects that state through a new
EventSourceRetryDelayStrategyon the platformEventSourceInitDict(optionalinitialRetryDelayMillis/retryResetIntervalMillis; browser defaults when omitted). Polling schedules the next request from the same controller with completion-anchored delays. 401/403, transport errors, and bad JSON are logged and retried (extended cadence for “unexpected” HTTP); they no longer surface data-source'error'events or stop the loop. Malformed stream payloads trigger a guarded close-and-reconnect; poll deserialization failures keep polling.Also bumps
launchdarkly-eventsourceto 2.3.0, preapproves it in.yarnrc.ymlfor the npm age gate, advertisesretry-conformance-fdv1-*contract capabilities, and adds a nightly GitHub workflow for the long-running RETRY harness (--enable-long-running-tests).Reviewed by Cursor Bugbot for commit 54ba5dd. Bugbot is set up for automated code reviews on this repo. Configure here.