Skip to content

馃悰 fix(browser): preserve exposure cache updates across instances - #412

Merged
leoromanovsky merged 1 commit into
leo/move-assignment-cache-to-indexeddbfrom
codex/fix-exposure-cache-concurrency
Oct 8, 2026
Merged

leoromanovsky merged 1 commit into
leo/move-assignment-cache-to-indexeddbfrom
codex/fix-exposure-cache-concurrency

Conversation

@sameerank

Copy link
Copy Markdown
Contributor

Motivation

Follow-up to #188, targeting leo/move-assignment-cache-to-indexeddb.

Two tabs or hooks sharing an exposure-cache scope can overwrite each other's committed entries when they persist their own memory snapshots. A stale instance can also restore entries another instance cleared, or overwrite a newer assignment.

Changes

  • Merge only newly recorded exposures with stored entries inside one IndexedDB read/write transaction.
  • Keep the pending-key index bounded, retry failed writes using current in-memory values, and prevent locally queued pre-clear writes from consuming post-clear entries.
  • Preserve the 50,000-entry limits: memory evicts least recently used entries; persistence evicts oldest written entries.
  • Add regression coverage for separate-instance writes, concurrent transactions, stale assignments, cleared entries, capacity, and failed writes. Reload tests now wait for persistence to commit.

Implementation and tests were prepared with Codex.

Test instructions

  1. Initialize two tabs with identical cache scope settings before either evaluates a flag.
  2. Evaluate flag A in the first tab and let its cache write commit.
  3. Evaluate flag B in the second tab and let its write commit.
  4. Reload the first tab and evaluate flag A again. Its persisted entry should suppress a duplicate exposure.

Also load the same persisted entry into two cache instances, clear it through the first, then record a different exposure through the second. Reloading must retain the new exposure without restoring the cleared entry.

Run the browser suite with:

yarn workspace @datadog/openfeature-browser test --runInBand --watchman=false

Checklist

  • Updated Documentation
  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

OpenFeature Browser Provider Bundle Sizes

Measured from the Vite production output after installing packed @datadog/flagging-core and @datadog/openfeature-browser tarballs.

Both scenarios initialize an OpenFeature provider, evaluate a boolean flag, change context, and evaluate again. Telemetry is disabled for DatadogProvider; no tracking hooks are registered for DatadogCoreProvider. DatadogProvider fetches precomputed assignments for each context; DatadogCoreProvider receives rules from fetchRulesConfiguration once and evaluates locally.

Sizes include OpenFeature and the same small scenario harness. Configuration responses are supplied by Playwright and are not bundled. These are complete scenario JS sizes, not configuration payload sizes or isolated provider/Protobuf costs; the difference between rows is not a decoder-only delta.

Scenario HTML JS Assets Raw JS Gzip JS Protobuf Markers
DatadogProvider (precomputed fetching) provider.html 19 82.2 KiB 31.2 KiB no
DatadogCoreProvider + fetchRulesConfiguration core-provider.html 14 149.3 KiB 46.8 KiB yes

Dependency checks passed: no Protobuf markers in default/precomputed scenarios; markers present in rules-based scenarios.

OpenFeature Browser Tracking Hook Bundle Sizes

Synthetic entrypoints import and call tracking hook factories from the packed @datadog/openfeature-browser/rules-based ESM package. Deltas are measured against the no-hook baseline from the same Vite production build.

Scenario HTML JS Assets Raw JS Raw 螖 Gzip JS Gzip 螖
tracking hook baseline tracking-baseline.html 6 2.6 KiB 0 B 1.6 KiB 0 B
exposure logging hook tracking-exposure.html 14 56.2 KiB +53.6 KiB 21.9 KiB +20.3 KiB
evaluation logging hook tracking-evaluation.html 14 53.2 KiB +50.6 KiB 20.8 KiB +19.2 KiB
RUM tracking hook tracking-rum.html 10 5.1 KiB +2.5 KiB 3.0 KiB +1.4 KiB
all tracking hooks tracking-all.html 17 60.5 KiB +57.9 KiB 23.9 KiB +22.4 KiB

OpenFeature Node Server Bundle Sizes

Independent Webpack production builds of the installed core and Node SDK tarballs, targeting Node 18 with ESM (module export condition). Node built-ins remain external. OpenFeature, dd-trace, and configuration fixtures are not bundled.

Scenario Raw JS Gzip JS Protobuf Modules
Node provider only 36.3 KiB 11.5 KiB no
SSR helpers only (fetch client rules + serialize) 80.1 KiB 23.1 KiB yes
Node provider + SSR helpers 115.9 KiB 33.6 KiB yes

Adding SSR helpers to the provider adds 79.7 KiB raw / 22.1 KiB gzip in this build. This includes fetching, parsing, and serialization, not just the decoder. SSR helpers fetch rules for the browser, not for configuring that provider (which uses its existing JSON API).

These are bundler sizes, not npm install sizes, unbundled Node require/import costs, payload sizes, or latency. Gzip compares compressed artifacts. The browser scenarios include OpenFeature and a different harness, so their sizes are not directly comparable.

Dependency checks passed: no Protobuf runtime or generated schema modules in the provider-only bundle; present in both SSR bundles (checked using Webpack module statistics).

This report shows current PR artifact sizes only; it does not compare against the base branch.

@sameerank
sameerank marked this pull request as ready for review October 8, 2026 15:54
@sameerank
sameerank requested a review from a team as a code owner October 8, 2026 15:54
@sameerank
sameerank requested review from danyal002 and leoromanovsky and removed request for a team October 8, 2026 15:54
@leoromanovsky
leoromanovsky merged commit c105cc4 into leo/move-assignment-cache-to-indexeddb Oct 8, 2026
3 checks passed
@leoromanovsky
leoromanovsky deleted the codex/fix-exposure-cache-concurrency branch October 8, 2026 16:33
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