Skip to content

Commit bd63856

Browse files
adams85z4kn4fein
andauthored
Improve snapshot API docs (#553)
* Improve snapshot API docs --------- Co-authored-by: Peter Csajtai <peter.csajtai@outlook.com>
1 parent ae5e706 commit bd63856

File tree

12 files changed

+759
-455
lines changed

12 files changed

+759
-455
lines changed

website/docs/sdk-reference/dotnet.mdx

Lines changed: 80 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ The SDK provides several hooks (events), by means of which you can get notified
416416
Via the following events you can subscribe to particular events raised by the client:
417417

418418
- `event EventHandler<ClientReadyEventArgs> ClientReady`: This event is raised when the SDK reaches the ready state. If the SDK is set up to use lazy loading or manual polling, it's considered ready right after syncing up with the config cache.
419-
If auto polling is used, the ready state is reached when the SDK has a valid config JSON loaded into memory either from cache or from HTTP. If the config couldn't be loaded neither from cache nor from HTTP, the `ClientReady` event fires when the auto polling's `MaxInitWaitTime` has passed.
419+
If auto polling is used, the ready state is reached when the SDK has a valid config JSON loaded into memory either from cache or from HTTP. If the config couldn't be loaded neither from cache nor from HTTP, the `ClientReady` event fires when the auto polling's `maxInitWaitTime` has passed.
420420
- `event EventHandler<ConfigFetchedEventArgs> ConfigFetched`: This event is raised each time when the SDK attempts to refresh the locally cached config by fetching the latest version from the remote server. It is raised not only when `ForceRefreshAsync` is called but also
421421
when the refresh is initiated by the SDK automatically. Thus, this event allows you to observe potential network issues that occur under the hood.
422422
- `event EventHandler<ConfigChangedEventArgs> ConfigChanged`: This event is raised first when the SDK loads a valid config JSON into memory from cache, then each time afterwards when a config JSON with changed content is downloaded via HTTP.
@@ -439,6 +439,85 @@ IConfigCatClient client = ConfigCatClient.Get("#YOUR-SDK-KEY#", options =>
439439
client.FlagEvaluated += (s, e) => { /* handle the event */ };
440440
```
441441

442+
## Snapshots and non-blocking synchronous feature flag evaluation
443+
444+
Currently, the _ConfigCat_ client provides both asynchronous and synchronous methods for evaluating feature flags and settings.
445+
However, depending on the setup, the synchronous methods may block the executing thread for longer periods of time
446+
(e.g. when downloading config data from the ConfigCat CDN servers), which can lead to an unresponsive application.
447+
To prevent such issues, the problematic methods have been deprecated and are going to be removed in a future major version.
448+
449+
As an alternative, since v9.2.0, the .NET SDK provides a way to synchronously evaluate feature flags and settings
450+
as a non-blocking operation, via _snapshots_.
451+
452+
Using the `Snapshot()` method, you can capture the current state of the _ConfigCat_ client (including the latest downloaded config data)
453+
and use the resulting snapshot object to synchronously evaluate feature flags and settings based on the captured state:
454+
455+
```csharp
456+
using var client = ConfigCatClient.Get("#YOUR-SDK-KEY#",
457+
options => options.PollingMode = PollingModes.AutoPoll());
458+
459+
// Wait for the client to initialize.
460+
await client.WaitForReadyAsync();
461+
462+
var snapshot = client.Snapshot();
463+
464+
var user = new User("#UNIQUE-USER-IDENTIFIER#");
465+
foreach (var key in snapshot.GetAllKeys())
466+
{
467+
var value = snapshot.GetValue(key, default(object), user);
468+
Console.WriteLine($"{key}: {value}");
469+
}
470+
```
471+
472+
Creating a snapshot is a cheap operation. This is possible because snapshots capture the client's internal (in-memory) cache.
473+
No attempt is made to refresh the internal cache, even if it's empty or expired.
474+
475+
:::caution
476+
Please note that creating and using a snapshot
477+
* won't trigger a sync with the external cache when working with [shared caching](../advanced/caching.mdx#shared-cache),
478+
* won't fetch the latest config data from the ConfigCat CDN when the internally cached config data is empty or expired.
479+
:::
480+
481+
For the above reasons, it's recommended to use snapshots in conjunction with the Auto Polling mode, where the SDK automatically
482+
updates the internal cache in the background. (For other polling modes, you'll need to manually initiate a cache refresh
483+
by calling `ForceRefreshAsync`.)
484+
485+
Because of this behavior, it's important to make sure that the client has completed initialization and populated its internal cache
486+
before creating snapshots. Otherwise the snapshot's evaluation methods won't have the data to do actual evaluation,
487+
but will just return the default value you pass to them. Which behavior is usually not what you want in your application.
488+
489+
In Auto Polling mode, you can use the `WaitForReadyAsync` method to wait for the latest config data to become available locally.
490+
This is an asynchronous operation, which completes as soon as the client reaches the ready state, i.e. completes initialization
491+
(or the time specified via the `maxInitWaitTime` option passes).
492+
493+
(Please note that this doesn't apply to other polling modes. In those cases, the client doesn't contact the ConfigCat CDN
494+
during initialization, so the ready state is reached as soon as the first sync with the external cache completes.)
495+
496+
Typically, you call `WaitForReadyAsync` and wait for its completion only once, in the initialization phase of your application.
497+
498+
:::caution
499+
Reaching the ready state usually means the client is ready to evaluate feature flags and settings.
500+
However, please note that this is not guaranteed. In case of initialization failure or timeout, the internal cache
501+
may be empty or expired even after the ready state is reported. You can verify this by checking the return value.
502+
:::
503+
504+
```csharp
505+
var clientCacheState = await client.WaitForReadyAsync();
506+
if (clientCacheState == ClientCacheState.NoFlagData)
507+
{
508+
// Handle initialization failure (see below).
509+
Console.WriteLine("ConfigCat client failed to obtain the config data during initialization.");
510+
}
511+
```
512+
513+
You have the following options to handle unsuccessful initialization:
514+
* If it's acceptable for your application to start up and use the default values passed to the evaluation methods,
515+
you may log some warning (or skip the check altogether as the client will log warnings anyway), and let the application continue.
516+
* Otherwise, you need to either terminate the application or continue waiting. The latter is an option because the client
517+
might be able to obtain the config data later, in the case of a transient problem like some temporary network issue.
518+
However, the _ConfigCat SDK_ doesn't provide out-of-the-box support for this case currently. You can implement this logic by
519+
subscribing to the `ConfigChanged` hook and waiting for the first event.
520+
442521
## Online / Offline mode
443522

444523
In cases where you want to prevent the SDK from making HTTP calls, you can switch it to offline mode:
@@ -769,55 +848,6 @@ User userObject = new User("435170f4-8a8b-4b67-a723-505ac7cdea92");
769848
IReadOnlyList<EvaluationDetails> settingValuesTargeting = await client.GetAllValueDetailsAsync(userObject);
770849
```
771850
772-
## Snapshots and non-blocking synchronous feature flag evaluation
773-
774-
Currently, the _ConfigCat_ client provides both asynchronous and synchronous methods for evaluating feature flags and settings.
775-
However, depending on the setup, the synchronous methods may block the executing thread for longer periods of time
776-
(e.g. when downloading config data from the ConfigCat CDN servers), which can lead to an unresponsive application.
777-
To prevent such issues, the problematic methods have been deprecated and are going to be removed in a future major version.
778-
779-
As an alternative, since v9.2.0, the .NET SDK provides a way to synchronously evaluate feature flags and settings via _snapshots_.
780-
781-
Using the `Snapshot()` method, you can capture the current state of the _ConfigCat_ client (including the latest downloaded config data)
782-
and you can use the resulting snapshot object to synchronously evaluate feature flags and settings based on the captured state:
783-
784-
```csharp
785-
using var client = ConfigCatClient.Get("#YOUR-SDK-KEY#",
786-
options => options.PollingMode = PollingModes.ManualPoll);
787-
788-
// Make sure that the latest config data is available locally.
789-
await client.ForceRefreshAsync();
790-
791-
var snapshot = client.Snapshot();
792-
793-
var user = new User("#UNIQUE-USER-IDENTIFIER#");
794-
foreach (var key in snapshot.GetAllKeys())
795-
{
796-
var value = snapshot.GetValue(key, default(object), user);
797-
Console.WriteLine($"{key}: {value}");
798-
}
799-
```
800-
801-
:::caution
802-
Please note that when you create and utilize a snapshot, it won't refresh your local cache once the cached config data expires.
803-
Additionally, when working with [shared caching](../advanced/caching.mdx#shared-cache), creating a snapshot also doesn't
804-
trigger a sync with the external cache, since the snapshot only captures the config instance stored in the client's memory.
805-
Therefore, it's recommended to use snapshots in conjunction with the Auto Polling mode, where the SDK automatically updates the local cache
806-
in the background. For other polling modes, you'll need to manually initiate a cache refresh by invoking `ForceRefreshAsync`.
807-
:::
808-
809-
In Auto Poll mode, you can use the `WaitForReadyAsync` method to wait for the latest config data to become available locally:
810-
811-
```csharp
812-
using var client = ConfigCatClient.Get("#YOUR-SDK-KEY#",
813-
options => options.PollingMode = PollingModes.AutoPoll());
814-
815-
// Make sure that the latest config data is available locally.
816-
await client.WaitForReadyAsync();
817-
818-
var snapshot = client.Snapshot();
819-
```
820-
821851
## Using custom cache implementation
822852
823853
The _ConfigCat SDK_ stores the downloaded config data in a local cache to minimize network traffic and enhance client performance.

0 commit comments

Comments
 (0)