Add optional parameter to configuration providers for non-blocking startup#1745
Add optional parameter to configuration providers for non-blocking startup#1745GeorgeTsiokos wants to merge 5 commits into
Conversation
|
Do note that I just merged a PR to support xUnit v3 so your unit/integration tests may need a refresh. |
…artup Configuration and secret store providers now accept an `optional` parameter that allows applications to start without blocking on sidecar availability. When optional, configuration loads in the background with resilient retry logic that handles transient Dapr errors gracefully. - Add `optional` parameter to AddDaprConfigurationStore and AddDaprSecretStore - Harden LoadInBackgroundAsync to catch OperationCanceledException and DaprException separately, avoiding silent swallowing of programming errors - Dispose CancellationTokenSource in both providers to prevent resource leaks - Fix StringComparer inconsistency (InvariantCultureIgnoreCase → OrdinalIgnoreCase) - Mark fields readonly in DaprConfigurationStoreProvider for consistency - Restore UTF-8 BOM per .editorconfig and add missing trailing newlines - Add deterministic tests using reload tokens instead of fragile Task.Delay Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: George Tsiokos <george@tsiokos.com>
7acf13b to
50765d7
Compare
Tests verify three scenarios using secretstores.local.file (no external deps): - optional:true with delayed sidecar: config populates once sidecar starts - optional:false (default): Build() blocks until sidecar ready, secrets populated - Disposal during background load: exits cleanly with no hang Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: George Tsiokos <george@tsiokos.com>
50765d7 to
d33da80
Compare
|
A few items I'm intentionally leaving as-is — noting them here for visibility: Pre-existing
Exponential backoff — The flat Splitting the Non-optional blocking-failure test for config store — Pre-existing gap (the non-optional path throws on WaitForSidecar timeout, but there's no unit test for it). Out of scope for this PR.
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds an optional parameter to Dapr configuration/secret store configuration providers so apps can start without blocking on sidecar availability, and expands test coverage (unit + integration) for the new behavior.
Changes:
- Add
optional/IsOptionalplumbing across configuration sources, providers, and extension methods for configuration store, streaming configuration store, and secret store. - Introduce background loading logic and tighten exception handling/cancellation disposal behavior in providers.
- Add new unit/integration tests (and a new integration test project + testcontainers harness) validating late sidecar startup and clean disposal.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/Dapr.Extensions.Configuration/DaprConfigurationStoreExtension.cs |
Adds optional parameter to configuration store extension methods and passes it into the source. |
src/Dapr.Extensions.Configuration/DaprConfigurationStoreSource.cs |
Adds IsOptional to the source and forwards it to the provider. |
src/Dapr.Extensions.Configuration/DaprConfigurationStoreProvider.cs |
Implements optional non-blocking startup via background loading; updates cancellation/disposal behavior. |
src/Dapr.Extensions.Configuration/DaprSecretStoreConfigurationExtensions.cs |
Adds optional parameter across secret-store extension overloads and sets IsOptional. |
src/Dapr.Extensions.Configuration/DaprSecretStoreConfigurationSource.cs |
Adds IsOptional and forwards it to the provider. |
src/Dapr.Extensions.Configuration/DaprSecretStoreConfigurationProvider.cs |
Implements optional non-blocking startup via background loading; adds IDisposable and refactors fetch logic. |
test/Dapr.Extensions.Configuration.Test/DaprConfigurationStoreProviderTest.cs |
Adds unit tests covering optional behavior for config store providers. |
test/Dapr.Extensions.Configuration.Test/DaprSecretStoreConfigurationProviderTest.cs |
Adds unit tests covering optional behavior for secret store provider. |
test/Dapr.IntegrationTest.Configuration/Dapr.IntegrationTest.Configuration.csproj |
New integration test project for configuration/secret optional behavior. |
test/Dapr.IntegrationTest.Configuration/SecretStoreOptionalTests.cs |
New integration tests validating optional startup, late sidecar, and disposal behavior. |
src/Dapr.Testcontainers/Common/DaprHarnessBuilder.cs |
Adds a builder method for the new secret store harness. |
src/Dapr.Testcontainers/Harnesses/SecretStoreHarness.cs |
New harness for local file-based secret store used by integration tests. |
all.sln |
Adds the new integration test project; also introduces x64/x86 solution configurations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Superseded by #1844 |
Summary
Resolves #1748
optionalparameter toAddDaprConfigurationStore,AddStreamingDaprConfigurationStore, andAddDaprSecretStoreextension methods so applications can start without blocking on Dapr sidecar availabilityLoadInBackgroundAsyncin both providers with narrowed exception handling (OperationCanceledException+DaprException) instead of a broadcatch (Exception)that silently swallowed programming errorsCancellationTokenSourcein both providersStringComparerinconsistency (InvariantCultureIgnoreCase→OrdinalIgnoreCase) inFetchSecretsAsyncreadonlyinDaprConfigurationStoreProviderfor consistency withDaprSecretStoreConfigurationProvider.editorconfigand adds missing trailing newlinesTest plan
GetReloadToken()callbacks for deterministic assertions (no fragileTask.Delaypolling)optional: truewith delayed sidecar — config populates once sidecar starts (ShouldPopulateSecretsWhenSidecarStartsLate)optional: false(default) behavior unchanged —Build()blocks until sidecar ready (ShouldBlockAndPopulateSecretsWhenNotOptional)ShouldExitCleanlyWhenDisposedDuringBackgroundLoad)TestContext.Current.CancellationTokenpattern)🤖 Generated with Claude Code