Skip to content

Conversation

@keelerm84
Copy link
Member

@keelerm84 keelerm84 commented Dec 4, 2025

Note

Introduce an offline-mode DataSynchronizer that loads archive data without network calls, integrate it into relay environment setup/updates, and bump go-server-sdk to v7.14.3.

  • Offline mode data sync:
    • Add internal/filedata/offline_mode_synchronizer.go implementing subsystems.DataSynchronizer for offline mode (fetches from archive via channel; broadcasts ChangeSet/status; supports UpdateData).
  • Relay integration:
    • In relay/filedata_actions.go, replace stub data source with custom DataSystem using OfflineModeSynchronizer; manage per-environment synchronizers; send initial SDKData; apply updates via UpdateData; clean up on delete.
  • Tests:
    • Update relay/filedata_actions_test.go to align with new offline environment creation/update flow (adjust sequencing in delete test).
  • Deps/infra:
    • Bump github.com/launchdarkly/go-server-sdk/v7 to v7.14.3.
    • Minor refactors/formatting in relay/relay.go (error var grouping, signature wrap).

Written by Cursor Bugbot for commit 2d754cc. This will update automatically on new commits. Configure here.

@keelerm84 keelerm84 requested a review from a team as a code owner December 4, 2025 17:58
@keelerm84
Copy link
Member Author

This is going to fail until I merge a pending feature and cut a release for the go sdk.

case <-s.quit:
return nil, context.Canceled
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Single-use data channel shared across synchronizer calls

The dataCh channel is read from by both the Fetch() and Sync() methods, but only a single data item is ever sent to this channel (in AddEnvironment). Additionally, the same OfflineModeSynchronizer instance is used for both primary and fallback synchronizers via Synchronizers(syncFactory, syncFactory). If the SDK calls Sync() on both (or calls both Fetch() and Sync()), multiple goroutines will race to receive from dataCh. Only one will succeed; the others will block forever waiting for data that never arrives, potentially causing initialization hangs.

Additional Locations (2)

Fix in Cursor Fix in Web

}
result.ChangeSet = &changeSet
result.State = interfaces.DataSourceStateValid
resultChan <- result
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Error state persists incorrectly across result updates

The result struct is reused across loop iterations in Sync(). When a changeSet is received (lines 150-156), the code sets result.ChangeSet and result.State but does not clear result.Error. If a previous status change set an error, that stale error will be included when sending subsequent valid changeSet updates. Consumers may incorrectly interpret the result as containing an error when the data is actually valid.

Fix in Cursor Fix in Web


p.updateHandler.AddEnvironment(testFileDataEnv2)
client2 := p.awaitClient()
assert.Equal(t, testFileDataEnv2.Params.SDKKey, client2.Key)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Test awaits wrong environment ID after adding second env

After adding testFileDataEnv2, the test calls awaitEnvironment(testFileDataEnv1.Params.EnvID) instead of awaitEnvironment(testFileDataEnv2.Params.EnvID). This means the test doesn't actually verify that the second environment was properly initialized - it just re-checks the first environment. The test will pass even if adding the second environment fails to complete.

Fix in Cursor Fix in Web

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