Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 48 additions & 4 deletions hugo/content/en/feature_flags/client/android.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ val configuration = Configuration.Builder(
.build()
Datadog.initialize(this, configuration, TrackingConsent.GRANTED)

// 3. Enable Feature Flags
Flags.enable()
// 3. Enable Feature Flags with a bounded assignment request timeout
Flags.enable(
FlagsConfiguration.Builder()
.assignmentRequestTimeout(1_500L)
Comment thread
leoromanovsky marked this conversation as resolved.
.build()
)

// 4. Create and set up the OpenFeature provider
val provider = FlagsClient.Builder().build().asOpenFeatureProvider()
Expand Down Expand Up @@ -98,8 +102,13 @@ After initializing Datadog, enable `Flags` to attach it to the current Datadog A

{{< code-block lang="kotlin" >}}
import com.datadog.android.flags.Flags
import com.datadog.android.flags.FlagsConfiguration

val flagsConfiguration = FlagsConfiguration.Builder()
.assignmentRequestTimeout(1_500L)
Comment thread
leoromanovsky marked this conversation as resolved.
.build()

Flags.enable()
Flags.enable(flagsConfiguration)
{{< /code-block >}}

You can also pass a configuration object; see [Advanced configuration](#advanced-configuration).
Expand Down Expand Up @@ -300,12 +309,47 @@ The `Flags.enable()` API accepts optional configuration with the options listed

{{< code-block lang="kotlin" >}}
val config = FlagsConfiguration.Builder()
// configure options here
.assignmentRequestTimeout(1_500L)
.assignmentRequestRetryCount(2)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
.assignmentRequestRetryCount(2)
.assignmentRequestRetryCount(2)
// configure additional options here

as I suggested here, I think it's nice to have this placeholder for the other options, to not imply these are the only ones

.build()

Flags.enable(config)
{{< /code-block >}}

`assignmentRequestTimeout(timeoutMs)`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

suggesting to move this info above the settings it references

Suggested change
`assignmentRequestTimeout(timeoutMs)`
<div class="alert alert-info">The assignment request timeout and retry settings below apply only to requests that fetch flag assignments. They do not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>
`assignmentRequestTimeout(timeoutMs)`

: Timeout in milliseconds for each flag assignment request, including the complete response-body download. The SDK does not add a timeout by default. Set a positive value to enable the timeout; `0` leaves it disabled. Negative values are coerced to `0`. When the HTTP call already has a nonzero timeout, the shorter timeout applies.

`assignmentRequestRetryCount(retryCount)`
: Number of retries after the initial flag assignment request. The default is `0`, so the SDK makes only the initial request unless you opt in to retries. Values outside the range from `0` to `10` are coerced to the nearest bound. Retries cover selected transient network errors, timeouts, HTTP 408, and HTTP 5xx responses. Canceled calls, HTTP 429, generic I/O errors, permanent protocol errors, and TLS failures are not retried. Retries use randomized exponential backoff capped at 30 seconds. The SDK reads `Retry-After` only for HTTP 503. A valid value up to 30 seconds is a minimum delay before the backoff. A response that requests a longer delay is not retried.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

what does it mean for values outside 0 to 10 to be "coerced to the nearest bound"?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
: Number of retries after the initial flag assignment request. The default is `0`, so the SDK makes only the initial request unless you opt in to retries. Values outside the range from `0` to `10` are coerced to the nearest bound. Retries cover selected transient network errors, timeouts, HTTP 408, and HTTP 5xx responses. Canceled calls, HTTP 429, generic I/O errors, permanent protocol errors, and TLS failures are not retried. Retries use randomized exponential backoff capped at 30 seconds. The SDK reads `Retry-After` only for HTTP 503. A valid value up to 30 seconds is a minimum delay before the backoff. A response that requests a longer delay is not retried.
: Number of retries after the initial flag assignment request. The default is `0`, so the SDK makes only the initial request unless you opt in to retries. Values outside the range from `0` to `10` are coerced to the nearest bound. Retries cover selected transient network errors, timeouts, HTTP 408, and HTTP 5xx responses. Canceled calls, HTTP 429, generic I/O errors, permanent protocol errors, and TLS failures are not retried. Retries use randomized exponential backoff capped at 30 seconds. The SDK reads `Retry-After` only for HTTP 503. A valid value up to 30 seconds is a minimum delay before the backoff. A response that requests a longer delay is not retried. The SDK manages the configured retry count and creates a new HTTP call for each attempt. The timeout applies to each attempt. Total network duration can reach `(retryCount + 1) * timeoutMs`, plus retry delays. When the timeout is `0`, the HTTP transport supplies the time bound and may allow an unlimited duration.

think this info, previously below, makes sense to fold in here


The SDK manages the configured retry count and creates a new HTTP call for each attempt. The timeout applies to each attempt. Total network duration can reach `(retryCount + 1) * timeoutMs`, plus retry delays. When the timeout is `0`, the HTTP transport supplies the time bound and may allow an unlimited duration.

<div class="alert alert-info">Assignment request timeout and retry settings apply only to requests that fetch flag assignments. They do not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>

For lower-level transport control, supply an assignment-only OkHttp call factory. Add OkHttp as a direct application dependency when you use this option:

{{< code-block lang="groovy" filename="build.gradle" >}}
dependencies {
implementation "com.squareup.okhttp3:okhttp:4.12.0"
}
{{< /code-block >}}

{{< code-block lang="kotlin" >}}
import okhttp3.OkHttpClient

val assignmentClient = OkHttpClient.Builder()
// Add assignment-specific proxy, TLS, or interceptors here.
.build()

val config = FlagsConfiguration.Builder()
.assignmentRequestCallFactory(assignmentClient)
.assignmentRequestTimeout(1_500L)
.assignmentRequestRetryCount(2)
.build()
{{< /code-block >}}

The SDK still constructs the URL, method, body, and authentication headers. The scalar timeout and retry policies compose on top of calls created by the supplied factory. When the assignment timeout is positive, the factory must return calls that provide and honor a configurable `Call.timeout()`. A call that returns `Timeout.NONE` fails before execution. Exposure and evaluation uploads continue to use the SDK transport. The application retains ownership of the supplied factory and its resources.
Comment on lines +329 to +351

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this content breaks up the Global configuration list and makes it difficult to follow—see the preview link to validate. I suggest moving it to its own section, placed after the list ends, titled "#### Supply a custom assignment transport"


`trackExposures()`
: When `true` (default), the SDK automatically records an _exposure event_ when a flag is evaluated. These events contain metadata about which flag was accessed, which variant was served, and under what context. They are sent to Datadog so you can later analyze feature adoption. If you only need local evaluation without telemetry, you can disable it with: `trackExposures(false)`.

Expand Down
44 changes: 43 additions & 1 deletion hugo/content/en/feature_flags/client/flutter.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,13 @@ final configuration = DatadogConfiguration(
rumConfiguration: DatadogRumConfiguration(
applicationId: '<RUM_APPLICATION_ID>',
),
)..addPlugin(const DatadogFlagsPluginConfiguration());
)..addPlugin(
const DatadogFlagsPluginConfiguration(
flagsConfiguration: DatadogFlagsConfiguration(
assignmentRequestTimeout: Duration(milliseconds: 1500),
Comment thread
leoromanovsky marked this conversation as resolved.
),
),
);

await DatadogSdk.instance.initialize(configuration, TrackingConsent.granted);
{{< /code-block >}}
Expand Down Expand Up @@ -126,6 +132,7 @@ final datadogFlags = DatadogFlags.instance;

await datadogFlags.enable(
configuration: DatadogFlagsConfiguration(
assignmentRequestTimeout: const Duration(milliseconds: 1500),
datadogConfig: const DatadogFlagsConfig(
clientToken: '<CLIENT_TOKEN>',
env: '<ENV_NAME>',
Expand Down Expand Up @@ -289,13 +296,45 @@ print(details.error?.code);
{{< code-block lang="dart" >}}
DatadogFlagsConfiguration(
datadogConfig: datadogConfig,
assignmentRequestTimeout: const Duration(milliseconds: 1500),
assignmentRequestRetryCount: 2,
trackExposures: true,
trackEvaluations: true,
evaluationFlushInterval: const Duration(seconds: 10),
store: myStore,
);
{{< /code-block >}}

`assignmentRequestTimeout`
: Timeout for each flag assignment request, including the complete response-body download. The SDK does not add a timeout by default. Set a positive duration to enable the timeout; `Duration.zero` leaves it disabled.

`assignmentRequestRetryCount`
: Number of retries after the initial flag assignment request. The default is `0`, so the SDK makes only the initial request unless you opt in to retries. Accepted values are from `0` to `10`. Retries cover selected transient network errors, timeouts, HTTP 408, and HTTP 5xx responses. Cancellation, HTTP 429, generic I/O errors, permanent protocol errors, and TLS failures are not retried. Retries use randomized exponential backoff capped at 30 seconds. For HTTP 503, a valid `Retry-After` value up to 30 seconds is a minimum delay before the backoff. A response that requests a longer delay is not retried.

<div class="alert alert-info">Assignment request timeout and retry settings apply only to requests that fetch flag assignments. They do not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>

For lower-level transport control, compose an assignment-only HTTP client:

{{< code-block lang="dart" >}}
import 'package:datadog_flags/datadog_flags.dart';
import 'package:http/http.dart' as http;
Comment thread
leoromanovsky marked this conversation as resolved.

final assignmentClient = withAssignmentRequestRetry(
withAssignmentRequestTimeout(
http.Client(),
const Duration(milliseconds: 1500),
),
2,
);

final config = DatadogFlagsConfiguration(
datadogConfig: datadogConfig,
assignmentRequestHttpClient: assignmentClient,
);
{{< /code-block >}}

A supplied `assignmentRequestHttpClient` is used verbatim and replaces the scalar timeout and retry settings. The helpers buffer the complete response, create a fresh request for each retry, and apply only to assignment requests. The application owns and closes the supplied client after disabling Feature Flags.

Comment on lines +314 to +337

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

same feedback as the android.md page (except the new header on this page should be an H3 instead of H4)—move the alert callout above the settings and the new content into a new "### Supply a custom assignment transport" section

`trackExposures`
: When `true` (default), the SDK records exposure events for successful evaluations whose assignments are marked for logging. Set to `false` to disable exposure tracking.

Expand Down Expand Up @@ -326,6 +365,8 @@ final configuration = DatadogConfiguration(
)..addPlugin(
const DatadogFlagsPluginConfiguration(
flagsConfiguration: DatadogFlagsConfiguration(
assignmentRequestTimeout: Duration(milliseconds: 1500),
assignmentRequestRetryCount: 2,
trackExposures: true,
trackEvaluations: true,
),
Expand Down Expand Up @@ -391,6 +432,7 @@ Future<void> initializeFlags() async {

await datadogFlags.enable(
configuration: DatadogFlagsConfiguration(
assignmentRequestTimeout: const Duration(milliseconds: 1500),
datadogConfig: const DatadogFlagsConfig(
clientToken: '<CLIENT_TOKEN>',
env: '<ENV_NAME>',
Expand Down
52 changes: 50 additions & 2 deletions hugo/content/en/feature_flags/client/ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ After initializing Datadog, enable `Flags` to attach it to the current Datadog i
{{< code-block lang="swift" >}}
import DatadogFlags

Flags.enable()
var flagsConfiguration = Flags.Configuration()
flagsConfiguration.assignmentRequestTimeout = 1.5
Comment thread
leoromanovsky marked this conversation as resolved.
Flags.enable(with: flagsConfiguration)
{{< /code-block >}}

You can also pass a configuration object; see [Advanced configuration](#advanced-configuration).
Expand Down Expand Up @@ -328,7 +330,9 @@ Datadog.initialize(
trackingConsent: .granted
)

Flags.enable()
var flagsConfiguration = Flags.Configuration()
flagsConfiguration.assignmentRequestTimeout = 1.5
Flags.enable(with: flagsConfiguration)

let context = MutableContext(targetingKey: "user-123")
let provider = DatadogProvider()
Expand Down Expand Up @@ -444,9 +448,53 @@ The `Flags.enable()` API accepts optional configuration with options listed belo

{{< code-block lang="swift" >}}
var config = Flags.Configuration()
config.assignmentRequestTimeout = 1.5
config.assignmentRequestRetryCount = 2
Flags.enable(with: config)
{{< /code-block >}}

`assignmentRequestTimeout`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
`assignmentRequestTimeout`
<div class="alert alert-info">Assignment request timeout and retry settings apply only to requests that fetch flag assignments. They do not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>
`assignmentRequestTimeout`

moving callout from below

: Timeout in seconds for each flag assignment request, including the complete response-body download. The SDK does not add a timeout by default. Set a positive, finite value to enable the timeout. A value of `0`, a negative value, or a non-finite value disables it. Values greater than `2_147_483.647` seconds are reduced to this maximum.

`assignmentRequestRetryCount`
: Number of retries after the initial flag assignment request. The default is `0`, so the SDK makes only the initial request unless you opt in to retries. Values outside the range from `0` to `10` are reduced to the nearest bound. Retries cover selected transient network errors, timeouts, HTTP 408, and HTTP 5xx responses. Cancellation, HTTP 429, unknown URL errors, permanent URL errors, and TLS failures are not retried. Retries use randomized exponential backoff capped at 30 seconds. The SDK reads `Retry-After` only for HTTP 503. A valid value up to 30 seconds is a minimum delay before the backoff. A response that requests a longer delay is not retried.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
: Number of retries after the initial flag assignment request. The default is `0`, so the SDK makes only the initial request unless you opt in to retries. Values outside the range from `0` to `10` are reduced to the nearest bound. Retries cover selected transient network errors, timeouts, HTTP 408, and HTTP 5xx responses. Cancellation, HTTP 429, unknown URL errors, permanent URL errors, and TLS failures are not retried. Retries use randomized exponential backoff capped at 30 seconds. The SDK reads `Retry-After` only for HTTP 503. A valid value up to 30 seconds is a minimum delay before the backoff. A response that requests a longer delay is not retried.
: Number of retries after the initial flag assignment request. The default is `0`, so the SDK makes only the initial request unless you opt in to retries. Values outside the range from `0` to `10` are reduced to the nearest bound. Retries cover selected transient network errors, timeouts, HTTP 408, and HTTP 5xx responses. Cancellation, HTTP 429, unknown URL errors, permanent URL errors, and TLS failures are not retried. Retries use randomized exponential backoff capped at 30 seconds. The SDK reads `Retry-After` only for HTTP 503. A valid value up to 30 seconds is a minimum delay before the backoff. A response that requests a longer delay is not retried. The scalar timeout applies to each attempt. Total duration includes all attempts and all retry delays.

moving the orphaned text below here


The scalar timeout applies to each attempt. Total duration includes all attempts and all retry delays.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
The scalar timeout applies to each attempt. Total duration includes all attempts and all retry delays.

suggesting to fold this in to the description above


<div class="alert alert-info">Assignment request timeout and retry settings apply only to requests that fetch flag assignments. They do not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
<div class="alert alert-info">Assignment request timeout and retry settings apply only to requests that fetch flag assignments. They do not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>

moving this above


For lower-level transport control, compose an assignment-only fetch implementation:

{{< code-block lang="swift" >}}
let assignmentFetch = Flags.AssignmentRequestFetch
.urlSession()
.withTimeout(1.5)
.withRetry(2)

var config = Flags.Configuration()
config.assignmentRequestFetch = assignmentFetch
Flags.enable(with: config)
{{< /code-block >}}

The SDK still constructs the URL, body, authentication, and custom headers. A supplied `assignmentRequestFetch` replaces the scalar timeout and retry settings. The SDK accepts at most one completion from the supplied fetch for each request and validates the HTTP response status. The custom transport applies only to assignment requests. The caller retains ownership of a supplied `URLSession` and other custom transport resources. The SDK does not invalidate or close them.

`withTimeout(timeout)`
: Adds a timeout that includes the complete response-body download. A positive, finite value enables the timeout. A nonpositive or non-finite value leaves the transport unchanged. Values greater than `2_147_483.647` seconds are reduced to this maximum.

`withRetry(retryCount)`
: Adds SDK-managed retries after the initial attempt. Values outside the range from `0` to `10` are reduced to the nearest bound. The retry policy matches `assignmentRequestRetryCount`. The SDK reads `Retry-After` only for HTTP 503.

In the example, `withTimeout` is inside `withRetry`. Therefore, each attempt has its own 1.5-second timeout. Reverse the wrappers to use one 1.5-second timeout for the initial request and all retries:

{{< code-block lang="swift" >}}
let assignmentFetch = Flags.AssignmentRequestFetch
.urlSession()
.withRetry(2)
.withTimeout(1.5)
{{< /code-block >}}

With this reversed order, one timeout covers all attempts and retry delays. With the original order, total duration includes each attempt timeout and all retry delays.

Comment on lines +466 to +497

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

suggesting to move this into a new H3 (titled ### Supply a custom assignment transport) after line 525 (customFlagsHeaders entry), before ## Testing (527)

`trackExposures`
: When `true` (default), the SDK automatically records an _exposure event_ when a flag is evaluated. These events contain metadata about which flag was accessed, which variant was served, and under what context. They are sent to Datadog so you can later analyze feature adoption. If you only need local evaluation without telemetry, you can disable this option.

Expand Down
30 changes: 28 additions & 2 deletions hugo/content/en/feature_flags/client/javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Create a `DatadogProvider` instance with your Datadog credentials. For live Brow
{{< site-region region="gov,gov2" >}}<div class="alert alert-danger">Browser Feature Flags are not supported for the selected <a href="/getting_started/site">Datadog site</a> ({{< region-param key="dd_site_name" >}}).</div>{{< /site-region >}}

```javascript
import { DatadogProvider } from '@datadog/openfeature-browser';
import { DatadogProvider, withTimeout } from '@datadog/openfeature-browser';
import { OpenFeature } from '@openfeature/web-sdk';

const provider = new DatadogProvider({
Expand All @@ -65,6 +65,7 @@ const provider = new DatadogProvider({
clientToken: '<CLIENT_TOKEN>',
site: '{{< region-param key="dd_site" code="true" >}}',
env: '<ENV_NAME>',
flagConfigurationFetch: withTimeout(globalThis.fetch, 1_500),
});
```

Expand Down Expand Up @@ -170,7 +171,7 @@ console.log(details.errorCode); // Error code, if evaluation failed
Here's a complete example showing how to set up and use Datadog Feature Flags in a JavaScript application:

```javascript
import { DatadogProvider } from '@datadog/openfeature-browser';
import { DatadogProvider, withTimeout } from '@datadog/openfeature-browser';
import { OpenFeature } from '@openfeature/web-sdk';

// Initialize the Datadog provider
Expand All @@ -179,6 +180,7 @@ const provider = new DatadogProvider({
clientToken: '<CLIENT_TOKEN>',
site: '{{< region-param key="dd_site" code="true" >}}',
env: '<ENV_NAME>',
flagConfigurationFetch: withTimeout(globalThis.fetch, 1_500),
});

// Set the evaluation context
Expand Down Expand Up @@ -226,6 +228,30 @@ The web provider also supports these optional settings:
| `flaggingProxy` | unset | Fetch flags through a proxy instead of `site`. |
| `customHeaders` | unset | Add headers to flag-fetch requests. |
| `overwriteRequestHeaders` | `false` | Replace default request headers with `customHeaders`. |
| `flagConfigurationFetch` | `globalThis.fetch` | Provide a Fetch-compatible implementation for flag configuration requests. |

### Bound flag configuration requests

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
### Bound flag configuration requests
### Set a timeout and retries for flag configuration requests


The browser provider does not add a timeout or retries by default. Use `withTimeout` and `withRetry` to bound each request attempt and retry transient failures:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
The browser provider does not add a timeout or retries by default. Use `withTimeout` and `withRetry` to bound each request attempt and retry transient failures:
The browser provider does not add a timeout or retries by default. Use `withTimeout` and `withRetry` to limit each request attempt and retry transient failures:
<div class="alert alert-info">The `flagConfigurationFetch` option applies only to flag configuration requests. It does not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>

suggesting moving alert from below up here. also updating "bound" to "limit"


{{< code-block lang="javascript" >}}
import { DatadogProvider, withRetry, withTimeout } from '@datadog/openfeature-browser';

const provider = new DatadogProvider({
// Other provider options...
flagConfigurationFetch: withRetry(withTimeout(globalThis.fetch, 1_500), 2),
});
{{< /code-block >}}

`withTimeout(fetch, timeoutMs)`
: Sets the timeout in milliseconds for each request attempt, including the complete response-body download. Set the timeout to `0` to disable the timer. Accepted values are non-negative integers up to `2_147_483_647`.

`withRetry(fetch, retryCount)`
: Sets the number of retries after the initial request. Set the retry count to `0` to disable retries. Accepted values are integers from `0` to `10`. Retries cover Fetch `TypeError` failures, timeout errors, HTTP 408, and HTTP 5xx responses. Caller cancellation and HTTP 429 responses are not retried. Retries use randomized exponential backoff capped at 30 seconds. For HTTP 503, a valid `Retry-After` value up to 30 seconds is a minimum delay before the backoff. A response that requests a longer delay is not retried. Browsers report network, CORS, and CSP failures as `TypeError`, so the wrapper cannot separate these causes.

In the example, `withTimeout` is inside `withRetry`. Therefore, each attempt has its own 1,500-millisecond timeout.

<div class="alert alert-info">The `flagConfigurationFetch` option applies only to flag configuration requests. It does not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
<div class="alert alert-info">The `flagConfigurationFetch` option applies only to flag configuration requests. It does not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>

suggesting moving this above


## Override flags in your browser

Expand Down
27 changes: 26 additions & 1 deletion hugo/content/en/feature_flags/client/unity.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ After initializing Datadog, enable `Flags` to attach it to the current Datadog U
{{< code-block lang="csharp" >}}
using Datadog.Unity.Flags;

DdFlags.Enable();
DdFlags.Enable(new FlagsConfiguration(
assignmentRequestTimeoutSeconds: 1,
Comment thread
leoromanovsky marked this conversation as resolved.
assignmentRequestRetryCount: 0));
{{< /code-block >}}

You can also pass a configuration object; see [Advanced configuration](#advanced-configuration).
Expand Down Expand Up @@ -203,12 +205,35 @@ The `DdFlags.Enable()` API accepts optional configuration with options listed be

{{< code-block lang="csharp" >}}
DdFlags.Enable(new FlagsConfiguration(
assignmentRequestTimeoutSeconds: 1,
assignmentRequestRetryCount: 2,
trackExposures: true,
trackEvaluations: true,
evaluationFlushIntervalSeconds: 10.0f
));
{{< /code-block >}}

`assignmentRequestTimeoutSeconds`
: Timeout in seconds for each flag assignment request, including the complete response-body download. The SDK does not add a timeout by default. Set a positive value to enable the timeout; `0` leaves it disabled.

`assignmentRequestRetryCount`
: Number of retries after the initial flag assignment request. The default is `0`, so the SDK makes only the initial request unless you opt in to retries. Accepted values are from `0` to `10`. Retries cover selected transient network errors, timeouts, HTTP 408, and HTTP 5xx responses. Cancellation, HTTP 429, generic I/O errors, permanent protocol errors, and TLS failures are not retried. Retries use randomized exponential backoff capped at 30 seconds. For HTTP 503, a valid `Retry-After` value up to 30 seconds is a minimum delay before the backoff. A response that requests a longer delay is not retried.

<div class="alert alert-info">Assignment request timeout and retry settings apply only to requests that fetch flag assignments. They do not affect exposure, aggregated flag evaluation, or RUM telemetry requests.</div>

For lower-level transport control, compose an assignment-only transport:

{{< code-block lang="csharp" >}}
var assignmentTransport = AssignmentRequestTransports.Default
.WithTimeout(1)
.WithRetry(2);

DdFlags.Enable(new FlagsConfiguration(
assignmentRequestTransport: assignmentTransport));
{{< /code-block >}}

A supplied `assignmentRequestTransport` is used verbatim and replaces the scalar timeout and retry settings. The helpers use fully buffered immutable responses, create a fresh native request for each retry, and apply only to assignment requests. The SDK owns its native requests; the application retains ownership of a custom transport and its resources.

Comment on lines +222 to +236

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

same feedback as the android.md page (except the new header on this page should be an H3 instead of H4)—move the alert callout above the settings and the new content into a new "### Supply a custom assignment transport" section

`trackExposures`
: When `true` (default), the SDK automatically records an _exposure event_ when a flag is evaluated. These events contain metadata about which flag was accessed, which variant was served, and under what context. They are sent to Datadog so you can later analyze feature adoption. Set to `false` to disable exposure tracking.

Expand Down
Loading
Loading