Skip to content

chore: bump SDK deps for EasyJSON removal (v4 cascade)#666

Draft
aaron-zeisler wants to merge 3 commits into
v8from
aaronz/SDK-2119/remove-easyjson-build-tag
Draft

chore: bump SDK deps for EasyJSON removal (v4 cascade)#666
aaron-zeisler wants to merge 3 commits into
v8from
aaronz/SDK-2119/remove-easyjson-build-tag

Conversation

@aaron-zeisler
Copy link
Copy Markdown
Contributor

@aaron-zeisler aaron-zeisler commented May 19, 2026

Summary

Updates the LaunchDarkly Go SDK ecosystem dependencies to /v4 development pseudo-versions that ship the EasyJSON removal:

  • go-jsonstream /v3/v4 (dev pseudo, ships easyjson removal)
  • go-sdk-common /v3/v4 (dev pseudo, ships easyjson removal)
  • go-server-sdk-evaluation /v3/v4 (dev pseudo, ships easyjson removal)
  • go-sdk-events /v3 (dev pseudo, transitively pins /v4 cores)
  • go-server-sdk /v7 (dev pseudo, transitively pins /v4 cores)
  • go-server-sdk-consul /v3 (dev pseudo, has /v4 deps)
  • go-server-sdk-dynamodb /v4 (dev pseudo, has /v4 deps)
  • go-server-sdk-redis-redigo /v3 (dev pseudo, has /v4 deps)

All .go imports of go-jsonstream, go-sdk-common, and go-server-sdk-evaluation are rewritten /v3/v4.

Dependency Chain (v4 cascade)

go-jsonstream/v4 (#39)        <- feat!:
└─ go-sdk-common/v4 (#50)     <- feat!:
   ├─ go-server-sdk-evaluation/v4 (#51) <- feat!:
   ├─ go-sdk-events/v3 (#43)  <- chore:
   └─ go-server-sdk/v7 (#380) <- chore: (also bumps ldotel sub-module)
      ├─ ld-relay (this PR)   <- chore:
      ├─ go-server-sdk-redis-redigo/v3 (#42) <- chore:
      ├─ go-server-sdk-consul/v3 (#34) <- chore:
      ├─ go-server-sdk-dynamodb/v4 (#36) <- chore:
      └─ launchdarkly/opentelemetry (#10) <- chore:
         └─ foundation (#8924) <- chore:
            └─ internal services (6 PRs) <- chore:

Pseudo-versions pinned in this PR:

Library Pseudo
go-jsonstream/v4 v4.0.0-20260526224546-8bf6dec4a0c8
go-sdk-common/v4 v4.0.0-20260526225240-97f2812dbb86
go-server-sdk-evaluation/v4 v4.0.0-20260526225518-f16d37cc6c94
go-sdk-events/v3 v3.6.1-0.20260526230019-c1af04865d66
go-server-sdk/v7 v7.14.8-0.20260526234754-18487da78db5
go-server-sdk-consul/v3 v3.0.1-0.20260527002707-c05fd21843ee
go-server-sdk-dynamodb/v4 v4.0.2-0.20260527002808-ce09408bf893
go-server-sdk-redis-redigo/v3 v3.0.3-0.20260526235028-6a50b0b3b185

Test plan

  • go build ./... clean
  • go vet ./... clean
  • go mod tidy clean
  • No /v3 imports of bumped libs remaining

Context

Part of SDK-2113 (epic). Tracks SDK-2119 (cascade).

Stage 5 cleanup

Once go-sdk-common@v4.0.0, go-jsonstream@v4.0.0, go-server-sdk-evaluation@v4.0.0, and a real go-server-sdk@v7.x.y tag exist, this PR's pseudo-versions should be flipped to those real versions before merge — or merge as-is and follow up.

via LD Research 🤖

@aaron-zeisler
Copy link
Copy Markdown
Contributor Author

CI Investigation: TestOfflineModeInit failure (Go 1.25.9)

Root cause: Non-deterministic map iteration order

The test at relay/filedata_actions_test.go:110-117 adds two environments and then asserts clients arrive in a specific order:

p.updateHandler.AddEnvironment(testFileDataEnv1)
p.updateHandler.AddEnvironment(testFileDataEnv2)

client1 := p.awaitClient()
client2 := p.awaitClient()
assert.Equal(t, testFileDataEnv1.Params.SDKKey, client1.Key)  // line 116
assert.Equal(t, testFileDataEnv2.Params.SDKKey, client2.Key)  // line 117

The test assumes clients are created in insertion order, but internally the environments are stored in a map. Go's map iteration order is non-deterministic and can change between runs or when the hash seed changes (which happens when dependency versions change).

Why it surfaces now: The SDK dependency bump likely changed the internal map structure or hash seed, flipping the iteration order on Go 1.25.9. It passes on Go 1.26.2 by luck.

Recommended fix: Make the assertion order-independent:

client1 := p.awaitClient()
client2 := p.awaitClient()
keys := []config.SDKKey{client1.Key, client2.Key}
assert.Contains(t, keys, testFileDataEnv1.Params.SDKKey)
assert.Contains(t, keys, testFileDataEnv2.Params.SDKKey)

Or sort the clients by key before asserting.

This is a latent test bug, not a regression in behavior.

via LD Research 🤖

@aaron-zeisler
Copy link
Copy Markdown
Contributor Author

CI Investigation: TestChangeSDKKey failure (Go 1.25.9)

Root cause: Race condition in client lifecycle during key rotation

The test at internal/relayenv/env_context_impl_test.go:274 asserts that after an SDK key's deprecation period expires, the old client should be nil. Instead, it gets the new client (*testclient.FakeLDClient{Key:"key2"}).

From the test logs:

Info: Initialized LaunchDarkly client for "envname" (SDK key ...42d0)
Info: New primary SDK key is ...key2
Info: SDK key ...42d0 was marked for deprecation [...]
Info: Initialized LaunchDarkly client for "envname" (SDK key ...key2)
Info: Deprecated SDK key ...42d0 has expired [...]
--- FAIL: TestChangeSDKKey (2.00s)
    expected: <nil>(<nil>)
    actual  : *testclient.FakeLDClient{Key:"key2", initialized:true}

The sequence is correct (key rotates, old key expires, old client closes). But at line 274, the test expects something to be nil and instead receives the new client for key2. This suggests a timing issue where the test reads the client reference before the expiration handler has fully cleaned up — or the assertion is checking the wrong slot.

Why it surfaces now: The new SDK version may have changed the timing of internal goroutines or channel operations around key rotation lifecycle, making this race condition more likely on Go 1.25.9 (but not Go 1.26.2, which may have faster scheduling).

Recommended investigation:

  1. Check what exactly line 274 is asserting (may need to look at what getter is being called — GetClient(), GetDeprecatedClient(), or similar)
  2. Add a brief helpers.AssertChannelClosed(t, client1.CloseCh, ...) wait before the nil assertion to ensure the cleanup goroutine has completed
  3. Confirm whether this also fails on Go 1.26.2 if run with -count=100 (race condition may be timing-sensitive)

This is likely a pre-existing race condition exposed by the SDK version bump changing goroutine scheduling.

via LD Research 🤖

@aaron-zeisler aaron-zeisler force-pushed the aaronz/SDK-2119/remove-easyjson-build-tag branch from 1c51f8f to f43cf88 Compare May 27, 2026 00:36
@aaron-zeisler aaron-zeisler changed the title chore: bump SDK deps for EasyJSON removal chore: bump SDK deps for EasyJSON removal (v4 cascade) May 27, 2026
Comment thread go.mod Outdated
Comment thread go.mod Outdated
Updates the LaunchDarkly Go SDK ecosystem dependencies to /v4
development pseudo-versions that ship the EasyJSON removal:

  go-jsonstream            /v3 -> /v4 (dev pseudo)
  go-sdk-common            /v3 -> /v4 (dev pseudo)
  go-server-sdk-evaluation /v3 -> /v4 (dev pseudo)
  go-sdk-events            /v3 (dev pseudo, has /v4 deps)
  go-server-sdk            /v7 (dev pseudo, has /v4 deps)
  go-server-sdk-consul     /v3 (dev pseudo, has /v4 deps)
  go-server-sdk-dynamodb   /v4 (dev pseudo, has /v4 deps)
  go-server-sdk-redis-redigo /v3 (dev pseudo, has /v4 deps)

All `.go` imports of the three v4 libraries are rewritten /v3 -> /v4.

Part of the SDK-2113 EasyJSON removal project.

Co-authored-by: Cursor <cursoragent@cursor.com>
@aaron-zeisler aaron-zeisler force-pushed the aaronz/SDK-2119/remove-easyjson-build-tag branch from f43cf88 to 581978b Compare May 27, 2026 17:46
…119/remove-easyjson-build-tag

# Conflicts:
#	.release-please-manifest.json
#	CHANGELOG.md
#	go.mod
#	go.sum
#	relay/version/version.go
…ases

- go directive: 1.25.5 → 1.25.10 (matches v8)
- go-versions.env: 1.26.2/1.25.9 → 1.26.3/1.25.10 (matches v8)
- go-jsonstream/v4, go-sdk-common/v4, go-sdk-events/v3: pseudo → real release
- go-server-sdk-evaluation/v4, go-server-sdk/v7: refresh stale pseudo-versions
- Regenerate go.sum
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