Repository navigation
fix: Honor the cancellation token when waiting for initialization - #72
Merged
Merged
Conversation
Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
Contributor
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
Contributor
|
@cursor review |
Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
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 fb037c7. Configure here.
Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
1 of 3 tasks
tanderson-ld
approved these changes
Oct 8, 2026
kinyoklion
added a commit
that referenced
this pull request
Oct 23, 2026
LaunchDarkly .NET SDK 8.17.0 made a rejected SDK key (401/403 and other 4xx) retryable, so the data source no longer reaches `Off` for it. The README matrix still said `InitializeAsync` waits until the client becomes ready "or fails permanently", which is no longer true for a rejected key. - Initialization row: now⚠️ . It notes the SDK 8.17.0 behavior: without a cancellation token, `InitializeAsync` can wait indefinitely. It links the provider-side tracking PR [#71](#71) (start wait). - Asynchronous Initialization: the SDK's default `StartWaitTime` is 10 seconds (`ConfigurationBuilder.DefaultStartWaitTime`). The README said 5. <details> <summary>Details</summary> **Requirements** - [ ] I have added test coverage for new or changed functionality - [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 **Related issues** #71 **Describe the solution you've provided** The provider references `LaunchDarkly.ServerSdk` `[8.1.0,9.0)`, so new installs resolve to 8.17.x and get the retry behavior. 8.17.0 release notes: "`DataSourceState.Off` no longer indicates a rejected SDK key. `Off` is now reached only by explicit shutdown." `main` was merged in after #72 (cancellation token) landed. The row now keeps #72's cancellation wording and no longer links #72 as a gap. **Additional context** #71 also edits the Initialization row. Whichever merges second will need a small README conflict fix. Found in the weekly OpenFeature provider audit. Docs-only change. </details> Link to Devin session: https://app.devin.ai/sessions/2a67f9d291bc4417bb40f632c191b44f Open in Devin Desktop: https://app.devin.ai/desktop/session/2a67f9d291bc4417bb40f632c191b44f?variant=devin Requested by: @kinyoklion [SDK-3255](https://launchdarkly.atlassian.net/browse/SDK-3255) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > Updates the README **Initialization** feature matrix row to **partial (⚠️ )** and revises how `InitializeAsync` behaves with LaunchDarkly .NET SDK **8.17.0+**: a rejected SDK key is retried instead of failing permanently, so without a `SetProviderAsync` cancellation token initialization can wait indefinitely. The row now says init waits until ready or shutdown (not permanent failure) and links provider follow-up **#71**. > > In **Asynchronous Initialization**, the documented default constructor blocking wait is corrected from **5** to **10** seconds to match `ConfigurationBuilder.DefaultStartWaitTime`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 7920750. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [SDK-3255]: https://launchdarkly.atlassian.net/browse/SDK-3255?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
kinyoklion
pushed a commit
that referenced
this pull request
Oct 23, 2026
🤖 I have created a release *beep* *boop* --- ## [2.3.2](2.3.1...2.3.2) (2026-10-23) ### Bug Fixes * Honor the cancellation token when waiting for initialization ([#72](#72)) ([0e6432d](0e6432d)) * Include an error type in provider error events ([#73](#73)) ([4f64d9c](4f64d9c)) * Include the last data source error in provider error and stale events ([#74](#74)) ([8c23f97](8c23f97)) --- 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** > **Release 2.3.2** bumps the package version in the manifest, `LaunchDarkly.OpenFeature.ServerProvider.csproj`, and adds a **2.3.2** section to `CHANGELOG.md`. No application code changes appear in this PR; it ships three already-merged bug fixes. > > The release notes call out: honoring **`CancellationToken`** during provider initialization waits, setting **`ErrorType`** on provider error events, and including the **last data source error** in provider error and stale event messages. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 47ba220. 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>
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.

InitializeAsyncignored itsCancellationToken, so a caller that passed a token toSetProviderAsynccould not stop waiting for the LaunchDarkly client.InitializeAsyncwith anOperationCanceledExceptioninstead of waiting for the data sourceRequirements
Related issues
None.
Implementation details
The OpenFeature .NET SDK passes the token given to
Api.SetProviderAsync(provider, cancellationToken)throughProviderRepositoryintoFeatureProvider.InitializeAsync. The provider returned_initCompletion.Taskdirectly, so the token had no effect.Waiting now goes through a helper which, when the token can be canceled, races
_initCompletion.Taskagainst aTaskCompletionSourcecanceled by a token registration._initCompletionitself is untouched, so the provider still becomesREADY(or errors) when the data source reports its state, regardless of a canceled wait.Shutdown is unchanged: it only removes listeners and disposes the client, so there is no wait to cancel.
Tests: two cases covering cancellation of a first wait and of a wait on an already in-progress initialization.
dotnet test -f net8.0passes (70 tests).Note: #71 also changes initialization waiting; whichever merges second needs a trivial rebase of this region.
Link to Devin session: https://app.devin.ai/sessions/a47abf28ecd44130917b9b5131287221
Open in Devin Desktop: https://app.devin.ai/desktop/session/a47abf28ecd44130917b9b5131287221?variant=devin
Requested by: @kinyoklion
SDK-3255
Note
Overview
InitializeAsyncnow honors theCancellationTokenpassed through OpenFeature (e.g. fromSetProviderAsync), so callers can stop waiting for the LaunchDarkly data source without blocking until ready or permanent failure.Waiting goes through
WaitForInitializationAsync, which races_initCompletionagainst token cancellation. Cancellation is per call:_initCompletionis unchanged, so the client can still finish initializing and other waiters are unaffected. A canceled wait completes withOperationCanceledException.StatusProvidergainsStartupWaitCanceled: it clears the “first event” suppression and, if status is already known, emits the matching provider event so subscribers still see READY (or stale/error) after a canceled startup wait. Status messages are retained for that replay; event emission is centralized inEmitStatusEvent.The README Initialization row and three unit tests document and cover token cancel on first wait, cancel on a concurrent second wait, and ProviderReady after cancel when the data source later becomes valid.
Reviewed by Cursor Bugbot for commit afef99f. Bugbot is set up for automated code reviews on this repo. Configure here.