fix: Resolve initialization immediately when a start wait time was used - #66
Merged
Merged
Conversation
Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Contributor
|
@cursor review |
kinyoklion
marked this pull request as ready for review
August 31, 2026 21:16
keelerm84
approved these changes
Sep 1, 2026
jsonbailey
approved these changes
Sep 1, 2026
3 tasks
kinyoklion
added a commit
that referenced
this pull request
Sep 1, 2026
…ion (#68) Intentionally chore. I am removing the changelog as it has not been released. Reverts #60 and #66, restoring the pre-2.2.0 initialization behavior. - `StartWaitTime` is a `Configuration` property, so it belongs to the client constructor's blocking behavior; the provider no longer reuses it to bound `InitializeAsync`. - `InitializeAsync` again waits for the client to become ready or to fail permanently, with no timeout of its own; callers bound the wait by choosing whether to await `SetProviderAsync`. - README feature matrix and asynchronous-initialization section updated to describe the restored behavior. **Requirements** - [x] I have added test coverage for new or changed functionality (tests added by the reverted PRs are removed) - [x] I have followed the repository's [pull request submission guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests) - [ ] I have validated my changes against all supported platform versions <details> <summary>Implementation details</summary> **Related issues** Reverts #60 ("Stop waiting for initialization after the configured start wait time", released in 2.2.0) and #66 ("Resolve initialization immediately when a start wait time was used", pending release in 2.3.1). **Describe the solution you've provided** `git revert` of both commits, so `Provider.cs` is byte-identical to its state at ed29935 (immediately before #60): the internal `startWait` constructor parameter, the `StartWait(config)` helper, `FailInitializationIfNotReady`, and the `_initLock` around the `Valid` status transition are all gone. The README matrix row for Initialization is rewritten rather than restored verbatim, because the text #64 added described the #60 behavior. The rationale: `StartWaitTime` lives on `Configuration`, not on the provider constructor, and the LaunchDarkly client constructor has already consumed it before OpenFeature ever calls `InitializeAsync`. Deriving an OpenFeature initialization deadline from it made the same value mean two different things, and made a non-awaited `SetProviderAsync` put the provider into `ERROR` for a merely slow start. **Describe alternatives you've considered** Keeping #66 and only adjusting the messaging, or exposing an explicit provider-level initialization timeout parameter. Neither was pursued: the requested outcome is the original behavior, where the caller controls how long to wait by awaiting `SetProviderAsync` or not. **Additional context** Behavior after this revert, per registration style: - `SetProviderAsync(provider)` not awaited: initialization runs in the background and waits for readiness; a `PROVIDER_READY` event is emitted whenever the data source becomes valid. - `SetProviderAsync(provider)` awaited: waits until the data source becomes valid or permanently fails. With a positive `StartWaitTime` the client constructor has already blocked for that long, so the remaining wait is unbounded — use `StartWaitTime` to bound constructor blocking and the OpenFeature `PROVIDER_ERROR`/`PROVIDER_READY` events to observe later state. `dotnet test` passes on `net8.0` (68 tests); `net471` and `net6.0` runtimes are unavailable in this environment and are covered by CI. </details> Link to Devin session: https://app.devin.ai/sessions/34fc74bc093b4c6680d2fddef4a4679b Open in Devin Desktop: https://app.devin.ai/desktop/session/34fc74bc093b4c6680d2fddef4a4679b?variant=devin Requested by: @kinyoklion <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > Reverts the 2.2.x behavior where **`StartWaitTime` also capped OpenFeature `InitializeAsync`**. **`InitializeAsync` again waits until the LaunchDarkly data source is ready or permanently fails**, with no provider-level timeout; **`StartWaitTime` only affects blocking in the `LdClient` constructor**. > > The provider drops the internal start-wait plumbing (`FailInitializationIfNotReady`, `StartWait(config)`, and the extra lock on the `Valid` status path). README **Initialization** and **Asynchronous initialization** text is updated to match. Tests that asserted init timeout / late-ready after timeout are removed. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit bd5d310. 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: Devin AI <devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BEGIN_COMMIT_OVERRIDE
chore: Resolve initialization immediately when a start wait time was used
END_COMMIT_OVERRIDE
Change to chore as it is being reverted.
A positive
StartWaitTimeno longer causes a second wait during provider initialization.LdClientconstructor for the start wait time, soInitializeAsyncnow completes with the outcome instead of scheduling its own timer; a 5 second start wait no longer means up to 10 seconds beforeSetProviderAsyncresolves.StartWaitTimeis unchanged: no timeout, initialization completes when the data source becomes valid or fails permanently.the client did not become ready within the {n}ms start wait time.Implementation details
Follow-up to #60, which introduced the timeout.
ScheduleInitTimeoutis replaced byFailInitializationIfNotReady, called at the end ofInitializeAsyncwhen a start wait was configured:The provider still keeps listening for data source status after failing, so a later successful connection emits a ready event and evaluations are never short-circuited.
Testing:
dotnet test test/LaunchDarkly.OpenFeature.ServerProvider.Tests -f net8.0. The timeout test now asserts the immediate failure, and the "does not time out when the client becomes ready" test covers a client which is ready when initialization is requested.Related spec change: https://github.com/launchdarkly/sdk-specs/pull/257
Link to Devin session: https://app.devin.ai/sessions/0c452d209ec54b068ba120b4c92b8f6c
Open in Devin Desktop: https://app.devin.ai/desktop/session/0c452d209ec54b068ba120b4c92b8f6c?variant=devin
Requested by: @kinyoklion
Note
Overview
Fixes double-wait on provider startup when
StartWaitTimeis greater than zero. The LaunchDarkly client already blocks in the provider constructor for that duration;InitializeAsyncno longer schedules a second timer, so a 5s start wait no longer stretches toward ~10s beforeSetProviderAsynccompletes.When a start wait is configured and the client is still not ready after construction,
InitializeAsyncfails synchronously with an updated message (the client did not become ready within the {n}ms start wait time). Background reconnection is unchanged—a later successful connection can still emit a ready event.StartWaitTimeof zero still means non-blocking construction and async initialization until the data source is valid.README initialization notes are aligned with this behavior; unit tests assert immediate failure and the ready-client success path.
Reviewed by Cursor Bugbot for commit 75a45cd. Bugbot is set up for automated code reviews on this repo. Configure here.