diff --git a/docs/feature-management-experimentation/10-getting-started/key-concepts.md b/docs/feature-management-experimentation/10-getting-started/key-concepts.md index f8065fef249..998ed10ee32 100644 --- a/docs/feature-management-experimentation/10-getting-started/key-concepts.md +++ b/docs/feature-management-experimentation/10-getting-started/key-concepts.md @@ -30,7 +30,7 @@ Once your code is deployed, you can instantly turn on or off features for any in FME provides visibility into your controlled releases by comparing data about feature flag evaluations with data about what happened after those evaluations. The data points that feed those comparisons are impressions and events. The results of those comparisons are called metrics. ### Impressions -An impression is a record of a targeting decision made. It is created automatically each time a feature flag is evaluated and contains details about the user or unique key for which the evaluation was performed, the targeting decision, the targeting rule that drove that decision, and a time stamp. Refer to the [Impressions](/docs/feature-management-experimentation/feature-management/impressions) guide for more information. +An impression is a record of a targeting decision made. It is created automatically each time a feature flag is evaluated and contains details about the user or unique key for which the evaluation was performed, the targeting decision, the targeting rule that drove that decision, and a time stamp. Refer to the [Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) guide for more information. ### Events An event is a record of user or system behavior. Events can be as simple as a page visited, a button clicked, or response time observed, and as complex as a transaction record with a detailed list of properties. An event doesn’t refer to a feature flag. The association between flag evaluations and events is computed for you. An event, associated with a user (or other unique keys), arriving after a flag decision for that same unique key, is attributed to that evaluation by FME’s attribution engine. @@ -91,13 +91,13 @@ Projects provide separation or partitioning of work to reduce clutter or to enfo Within each project, you may have multiple environments, such as development, staging, and production. Refer to the [Environments](/docs/feature-management-experimentation/management-and-administration/fme-settings/environments) guide for more information. ### Feature flags -Feature flags are created at the project level where you specify the feature flag name, traffic type, owners, and description. Targeting rules are then created and managed at the environment level as part of the feature flag definition. Refer to the [Feature flag management](/docs/feature-management-experimentation/feature-management/create-a-feature-flag) guide for more information. +Feature flags are created at the project level where you specify the feature flag name, traffic type, owners, and description. Targeting rules are then created and managed at the environment level as part of the feature flag definition. Refer to the [Feature flag management](/docs/feature-management-experimentation/feature-management/setup/create-a-feature-flag) guide for more information. ### Targeting rule Targeting rules for each feature flag are created at the environment level. For example, this supports one set of rules in your staging environment and another in production. Rules may be based on user or device attributes, membership in a segment, a percentage of a randomly distributed population, a list of individually specified user or unique key targets, or any combination of the above. ### Segment -A segment is a list of users or unique keys for targeting purposes. Segments are created at the environment level. Refer to the [Segments](/docs/feature-management-experimentation/feature-management/segments) guide for more information. +A segment is a list of users or unique keys for targeting purposes. Segments are created at the environment level. Refer to the [Segments](/docs/feature-management-experimentation/feature-management/targeting/segments) guide for more information. ### Traffic type Targeting decisions are made on a per-user or per unique key basis, but what are the available types of unique keys you intend to target? These are your traffic types, and you can define up to ten unique key types at the project level. diff --git a/docs/feature-management-experimentation/10-getting-started/overview/boxes-demo.md b/docs/feature-management-experimentation/10-getting-started/overview/boxes-demo.md new file mode 100644 index 00000000000..d97122c8df6 --- /dev/null +++ b/docs/feature-management-experimentation/10-getting-started/overview/boxes-demo.md @@ -0,0 +1,69 @@ +--- +title: Explore How Feature Flags Affect User Targeting +sidebar_label: Explore How Feature Flags Affect User Targeting +description: Learn how to use this visualization tool to help you explore the effects of individual targeting, custom attributes, traffic allocation limits, and dynamic configurations on feature flags. +sidebar_position: 3 +redirect_from: + - /docs/feature-management-experimentation/feature-management/best-practices/split-boxes-demo/ +--- + +## Overview + +The Split Boxes demo is a tool to help users understand the interaction between rules and the impact of various features. It’s a simple visualization that allows you to see the impact of individually targeting, custom attribution, limit exposure, and dynamic configuration. + +## Using the Boxes Demo + +Each box represents a user ID. + +![](.././static/split-boxes-demo.png) + +* You can individually target using the cell location, such as b8 or j5. +* You can also create a segment that includes any of the available values. +* You can create targeting rules using the attributes **row**, **col**, or **account**; + + * _row_ and _col_ use letters and numbers respectively, usually with "is in list" as the matcher. + * Valid account names include: Nike, Apple, LinkedIn, Best Buy, Google, Microsoft, Pinterest, Dell, Slack, Zoom, Samsung, and Disney. + +* You can modify the configuration of the treatments by updating any of the values. The `font_size` expects standard HTML sizes such as medium, large, x-large, etc. + +## Setting up the Boxes Demo + +There are three files attached: + +* The HTML contains the SDK and can be run locally or on a server. +* You need to provide the browser API key for the Split environment where you will update the rollout plan. +* You also need to provide the feature flag name. These are entered as variables in the HTML: + + ```html + + ``` + + * The Boxes_split.txt file contains an example baseline definition of the feature flag. + * The feature flag can be created automatically using the `CreateBoxSplit.sh` script, which uses the Split Admin REST API and the `jq` tool. Run the script with this command line to create the feature flag and add definitions: + + ```css + CreateBoxSplit [Project Name] [Environment Name] [Traffic Type] [Split Name] [Admin API_KEY] + ``` + + Example: + + ```sql + CreateBoxSplit Default Production user front_end_choose_boxes 9enxxxxxxxxxxxxxxxxxxxxxx + ``` + +In Chrome, to see feature flag changes immediately, disable cache in the Network tab of the Developer Tools. + +![](.././static/split-boxes-chrome.png) + +## Downloads + +| File | Size | Notes | +| --------------------------------------------------------- | --------- | --------------------------------- | +| [CreateBoxSplit.sh.zip](.././static/create-box-split.sh.zip) | 1 KB | | +| [Boxes\_split.txt](.././static/boxes-split.txt) | 658 Bytes | *Right-click > Save Link As...* | +| [Boxes.htm](.././static/boxes.htm) | 8 KB | *Right-click > Save Link As...* | + + diff --git a/docs/feature-management-experimentation/10-getting-started/overview/build-a-resilient-integration.md b/docs/feature-management-experimentation/10-getting-started/overview/build-a-resilient-integration.md index b45467ca0e9..d73275d3ed7 100644 --- a/docs/feature-management-experimentation/10-getting-started/overview/build-a-resilient-integration.md +++ b/docs/feature-management-experimentation/10-getting-started/overview/build-a-resilient-integration.md @@ -2,7 +2,7 @@ title: Build a Resilient Integration sidebar_label: Build a Resilient Integration description: Learn how to build a resilient integration with Harness FME. -sidebar_position: 7 +sidebar_position: 8 --- ## Overview @@ -70,7 +70,7 @@ For client-side SDKs, you can set up a listener for the `SDK_READY_TIMED_OUT` ev ### Account for the control treatment -In case Split is unreachable and the SDK is unable to fetch feature flag definitions‚ and there is no cache available in the case of client side SDKs‚ any evaluations will return the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +In case Split is unreachable and the SDK is unable to fetch feature flag definitions‚ and there is no cache available in the case of client side SDKs‚ any evaluations will return the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). Make sure you code your application so that it is able to safely handle this situation. This may mean falling back to a safe behavior, such as turning an experimental feature off. @@ -83,7 +83,7 @@ In the status page, you will see the status for Split's various components: * **SDK API**: This API serves rollout plans for our SDKs. A service disruption could prevent new SDK instances from initializing if your rollout plans aren't yet cached in Split's CDN as a result of previous requests by other SDK instances, and running SDK instances would not be able to fetch rollout plan changes. * **API**: Split's public API. * **Web console**: A web console outage means users can't log into Split's web application to modify rollout plans. Existing rollouts plans will continue to be served to Split SDKs in your applications and you end users' experience will be unaffected. -* **Data processing**: Issues in this component will impact Split's ability to ingest [impression](/docs/feature-management-experimentation/feature-management/impressions) and [event data](/docs/feature-management-experimentation/release-monitoring/events/). This will also affect Live tail, alerts, experimentation, and impression webhooks. SDKs mitigate issues in our data processing pipeline by following a retry mechanism when they fail to post data back to Split. Data processing issues are usually temporal, delaying ingestion and rarely resulting in data loss. +* **Data processing**: Issues in this component will impact Split's ability to ingest [impression](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) and [event data](/docs/feature-management-experimentation/release-monitoring/events/). This will also affect Live tail, alerts, experimentation, and impression webhooks. SDKs mitigate issues in our data processing pipeline by following a retry mechanism when they fail to post data back to Split. Data processing issues are usually temporal, delaying ingestion and rarely resulting in data loss. * **Integrations**: This component will reflect issues with any of Split's various [integrations](/docs/feature-management-experimentation/integrations). The integrations affected will be noted in the status page update and if the issue lies with an integration partner it will be noted and tracked. * **CDN**: Issues with our CDN may prevent new SDK instances from fetching rollout plans during initialization. For server-side SDKs, this will result in treatment evaluations returning control treatments. For client-side SDKs, evaluations will return treatments according to the rollout plans already cached in the device, if a cache is available. * **Streaming Authentication Service**: Issues in this component will prevent SDKs from receiving rollout plan updates via push notifications. In this scenario, all SDKs will fall back to polling to fetch updates with no impact to your end users. \ No newline at end of file diff --git a/docs/feature-management-experimentation/10-getting-started/overview/create-a-feature-flag.md b/docs/feature-management-experimentation/10-getting-started/overview/create-a-feature-flag.md index ccc7cdead29..a83b7858b0e 100644 --- a/docs/feature-management-experimentation/10-getting-started/overview/create-a-feature-flag.md +++ b/docs/feature-management-experimentation/10-getting-started/overview/create-a-feature-flag.md @@ -21,7 +21,7 @@ Select the traffic type user to get started. Traffic types give you the ability Owners, tags, and the description make it easy to sort, filter, and locate the features your team is rolling out. By default, administrators and the creator of the feature flag are considered its owners. Utilize groups with this owner field to organize your flags across your team. Learn more about owners and tags. -For more information about creating a feature flag, see [Create a feature flag](/docs/feature-management-experimentation/feature-management/create-a-feature-flag/). +For more information about creating a feature flag, see [Create a feature flag](/docs/feature-management-experimentation/feature-management/setup/create-a-feature-flag/). ## Add your feature flag to an environment @@ -31,7 +31,7 @@ To configure your feature flag for a particular environment, select the environm Treatments are the different variants or versions of your feature flag that you serve to your users. When you click the **Initiate environment** button, the Definition tab for a particular flag appears. Use this tab to assign your treatments. -We default the treatment names to on and off for each new feature flag but you can edit these names and add additional treatments. The default treatment selected in the treatments section will be served to everyone if the feature flag is killed and to all traffic not exposed to a flag. For more information about the default treatment, see [Set the default treatment](/docs/feature-management-experimentation/feature-management/set-the-default-treatment). +We default the treatment names to on and off for each new feature flag but you can edit these names and add additional treatments. The default treatment selected in the treatments section will be served to everyone if the feature flag is killed and to all traffic not exposed to a flag. For more information about the default treatment, see [Set the default treatment](/docs/feature-management-experimentation/feature-management/setup/default-treatment). After your treatments are set up and the default treatment is chosen, you can set individual targets, limit exposure, and set targeting rules to explicitly assign treatments or set targets based on dependencies or demographic data as attributes. @@ -39,7 +39,7 @@ After your treatments are set up and the default treatment is chosen, you can se * Limit exposure (advanced): Allows you to randomly assign a percentage of your users to be evaluated by all the targeting rules that are not individual targets. This feature is recommended for advanced experimentation use cases. * Set targeting rules: Allows you to build out if/else statements to use demographic data as attributes to assign treatments to users and  build dependencies with other features you manage in Split. -Click **Save changes** to configure the rules for this feature flag in the environment you selected. Learn more about [targeting](/docs/feature-management-experimentation/feature-management/define-feature-flag-treatments-and-targeting). +Click **Save changes** to configure the rules for this feature flag in the environment you selected. Learn more about [targeting](/docs/feature-management-experimentation/feature-management/setup/define-feature-flag-treatments-and-targeting). Now that you've set up this feature flag's targeting rules, let's take a look at how this flag would work in your code. To implement this feature flag, copy and wrap the provided code snippet around your feature's treatments. @@ -58,6 +58,12 @@ if (treatment === 'on') { } ``` -To help verify that treatments are being served to your users, click the [Live tail tab](/docs/feature-management-experimentation/feature-management/live-tail/) to view a stream of impressions or SDK evaluations. Impressions occur whenever a visitor is assigned a treatment (i.e., variations) for a feature flag. +To help verify that treatments are being served to your users, click the [Live tail tab](/docs/feature-management-experimentation/feature-management/monitoring-analysis/live-tail/) to view a stream of impressions or SDK evaluations. Impressions occur whenever a visitor is assigned a treatment (i.e., variations) for a feature flag. -These impressions are generated by the SDKs each time `getTreatment` is called. They are periodically sent back to Split's servers where they are stored and can be accessed for later use. For more information about impressions, see [Impressions](/docs/feature-management-experimentation/feature-management/impressions). \ No newline at end of file +These impressions are generated by the SDKs each time `getTreatment` is called. They are periodically sent back to Split's servers where they are stored and can be accessed for later use. For more information about impressions, see [Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions). + +## Further Reading + +Additional documentation, blog links, and articles: + +- [Feature Flags For Dummies](https://www.harness.io/resources/feature-flags-for-dummies) \ No newline at end of file diff --git a/docs/feature-management-experimentation/10-getting-started/overview/create-a-metric-alert-policy.md b/docs/feature-management-experimentation/10-getting-started/overview/create-a-metric-alert-policy.md index 47493ec22bd..05c471148fb 100644 --- a/docs/feature-management-experimentation/10-getting-started/overview/create-a-metric-alert-policy.md +++ b/docs/feature-management-experimentation/10-getting-started/overview/create-a-metric-alert-policy.md @@ -1,6 +1,6 @@ --- title: Create a Metric Alert Policy -sidebar_position: 5 +sidebar_position: 6 --- import AlertPolicies from '/docs/feature-management-experimentation/shared/alert-policies/index.mdx' diff --git a/docs/feature-management-experimentation/10-getting-started/overview/create-a-metric.md b/docs/feature-management-experimentation/10-getting-started/overview/create-a-metric.md index 31d2d554078..ae69d57a466 100644 --- a/docs/feature-management-experimentation/10-getting-started/overview/create-a-metric.md +++ b/docs/feature-management-experimentation/10-getting-started/overview/create-a-metric.md @@ -1,6 +1,6 @@ --- title: Create a Metric -sidebar_position: 4 +sidebar_position: 5 --- import MetricsSetup from '/docs/feature-management-experimentation/shared/metrics/setup/index.mdx' diff --git a/docs/feature-management-experimentation/10-getting-started/overview/create-an-experiment.md b/docs/feature-management-experimentation/10-getting-started/overview/create-an-experiment.md index 456e85c34c2..84ab0511036 100644 --- a/docs/feature-management-experimentation/10-getting-started/overview/create-an-experiment.md +++ b/docs/feature-management-experimentation/10-getting-started/overview/create-an-experiment.md @@ -2,7 +2,9 @@ title: Create an Experiment sidebar_label: Create an Experiment description: Learn how to create an experiment in Harness FME. -sidebar_position: 6 +sidebar_position: 7 +redirect_from: + - /docs/feature-management-experimentation/feature-management/faqs/is-there-a-way-to-limit-the-number-of-users-in-an-experiment --- ## Overview @@ -33,6 +35,19 @@ To create an A/B test in Harness FME: 1. Apply tags to help categorize your experiment (for example, by team, status, or feature area). 1. Click **Save**. +### Limiting the number of users in an experiment + +You can't directly cap the total number of users who will participate in an experiment. However, you can use the **Limit exposure** option to control the percentage of eligible users who are exposed to the experiment at any given time. + +This approach lets you: + +- Reduce risk when rolling out changes. +- Gather results from a smaller sample before expanding to all users. + +:::tip +Start with a lower exposure percentage (for example, 10%) to validate results, then increase it gradually. +::: + ## View experiment results Once your experiment is running, Harness FME automatically tracks key metrics and monitors the statistical significance of the results. diff --git a/docs/feature-management-experimentation/10-getting-started/overview/index.md b/docs/feature-management-experimentation/10-getting-started/overview/index.md index f6f2c18db41..0039d47049c 100644 --- a/docs/feature-management-experimentation/10-getting-started/overview/index.md +++ b/docs/feature-management-experimentation/10-getting-started/overview/index.md @@ -2,6 +2,8 @@ title: Overview sidebar_label: Overview description: How to make Feature Management & Experimentation work for you +redirect_from: + - /docs/feature-management-experimentation/feature-management/best-practices/o-reilly-book --- Harness Feature Management & Experimentation (FME) combines capabilities for feature delivery and control with built-in tools for measurement and learning. FME connects insightful data to every feature release and supports modern practices like continuous delivery and progressive delivery. @@ -142,6 +144,8 @@ Split has robust data pipelines and attribution logic. If you do find a mismatch Manage feature flag scheduling, flag sets, and flag lifecycles. Feature flags turn on features to specific users or segments. You can tailor access to beta testers and early adopters based on individual IDs, attributes, dependencies, or percentages. Gradually increase the rollout percentage to limit the blast radius of your releases. +In [this book](https://www.harness.io/resources/feature-flags-best-practices), Split CTO Pato Echague and Pete Hodgson explain how to implement feature-flagged software successfully, and offer some tips to developers on how to configure and manage a growing set of feature flags within your product, maintain them over time, manage infrastructure migrations, and more. + ### Release monitoring Release monitoring detects the impact of each feature on system performance and user behavior, starting with the earliest stage of a gradual rollout. With detection and triage done at the flag level, you can ship more often and with greater confidence. @@ -180,7 +184,13 @@ Use traffic types to easily identify the customer traffic you are splitting. A t ### Testing with feature flags -Feature flags can be integrated into a variety of testing strategies across the software development lifecycle. In quality assurance and engineering workflows, they support unit tests, end-to-end tests, smoke tests, lifecycle testing, A/B testing, and both shift-left and shift-right practices. Teams can also use localhost mode to validate flag behavior in isolation or as part of CI pipelines. +Feature flags can be integrated into a variety of testing strategies across the software development lifecycle. In quality assurance and engineering workflows, they support unit, smoke, regression, sanity, and end-to-end testing, along with lifecycle testing, usability testing (moderated, unmoderated, think-aloud, remote), A/B testing, benchmark testing, and accessibility checks. + +* **[Smoke testing](https://www.harness.io/blog/differences-between-smoke-testing-and-sanity-testing)**: A quick validation that critical functionality works before deeper testing begins. +* **[Regression testing](https://www.harness.io/blog/comparing-smoke-tests-to-regression-tests)**: Ensures recent changes haven’t broken existing functionality. +* **[Sanity testing](https://www.harness.io/blog/differences-between-smoke-testing-and-sanity-testing)**: A fast check that recent fixes or updates didn’t disrupt core features. + +Teams can also use localhost mode to validate flag behavior in isolation or as part of CI pipelines, and apply flags in both shift-left and shift-right practices. For guidance on incorporating feature flags into these workflows, see [Creating Unit Tests for Code Using FME SDKs](/docs/feature-management-experimentation/api/unit-tests) and [Using Test Automation in QA](/docs/feature-management-experimentation/api/test-automation). @@ -232,12 +242,10 @@ This list may change in the event of a failover, so we recommend subscribing to Split uses a third-party provider, SendGrid, to send user invitations. If your spam blocker prevents these from being delivered, allow the following IP address: `168.245.9.60`. -### Additional topics - -* Integrate & automate: Understand Split’s API and connect Split with the solutions you use today. - -* Working as a team: Functionality for teams that need more controls and additional organization. +## Further Reading -* Securing your data: Carry your security best practices through into Split. +Additional documentation, blog blog links, and articles: -* Support: Understand support definitions and incident response times. \ No newline at end of file +- [Testing Redesigned Data Pipelines with Split](https://www.harness.io/blog/testing-pipelines-split) +- [Understanding Different Types of Usability Testing](https://www.harness.io/blog/types-of-usability-testing) +- [Differences Between Smoke Testing and Sanity Testing](https://www.harness.io/blog/differences-between-smoke-testing-and-sanity-testing#feature-flags-and-their-role-in-testing) \ No newline at end of file diff --git a/docs/feature-management-experimentation/10-getting-started/overview/manage-the-feature-flag-lifecycle.md b/docs/feature-management-experimentation/10-getting-started/overview/manage-the-feature-flag-lifecycle.md index 67e9f1737ed..58fd036440a 100644 --- a/docs/feature-management-experimentation/10-getting-started/overview/manage-the-feature-flag-lifecycle.md +++ b/docs/feature-management-experimentation/10-getting-started/overview/manage-the-feature-flag-lifecycle.md @@ -2,7 +2,7 @@ title: Manage the Feature Flag Lifecycle sidebar_label: Manage the Feature Flag Lifecycle description: Learn how to manage the feature flag lifecycle with Harness FME. -sidebar_position: 8 +sidebar_position: 9 --- ## Overview diff --git a/docs/feature-management-experimentation/10-getting-started/overview/send-event-data.md b/docs/feature-management-experimentation/10-getting-started/overview/send-event-data.md index 4ccd5cfb0dc..aee934624af 100644 --- a/docs/feature-management-experimentation/10-getting-started/overview/send-event-data.md +++ b/docs/feature-management-experimentation/10-getting-started/overview/send-event-data.md @@ -2,7 +2,7 @@ title: Send Event Data sidebar_label: Send Event Data description: Learn how to send event data to Harness FME. -sidebar_position: 3 +sidebar_position: 4 --- ## Overview diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/shared/boxes-split.txt b/docs/feature-management-experimentation/10-getting-started/static/boxes-split.txt similarity index 100% rename from docs/feature-management-experimentation/40-feature-management/best-practices/shared/boxes-split.txt rename to docs/feature-management-experimentation/10-getting-started/static/boxes-split.txt diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/shared/boxes.htm b/docs/feature-management-experimentation/10-getting-started/static/boxes.htm similarity index 100% rename from docs/feature-management-experimentation/40-feature-management/best-practices/shared/boxes.htm rename to docs/feature-management-experimentation/10-getting-started/static/boxes.htm diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/shared/create-box-split.sh.zip b/docs/feature-management-experimentation/10-getting-started/static/create-box-split.sh.zip similarity index 100% rename from docs/feature-management-experimentation/40-feature-management/best-practices/shared/create-box-split.sh.zip rename to docs/feature-management-experimentation/10-getting-started/static/create-box-split.sh.zip diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/static/split-boxes-chrome.png b/docs/feature-management-experimentation/10-getting-started/static/split-boxes-chrome.png similarity index 100% rename from docs/feature-management-experimentation/40-feature-management/best-practices/static/split-boxes-chrome.png rename to docs/feature-management-experimentation/10-getting-started/static/split-boxes-chrome.png diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/static/split-boxes-demo.png b/docs/feature-management-experimentation/10-getting-started/static/split-boxes-demo.png similarity index 100% rename from docs/feature-management-experimentation/40-feature-management/best-practices/static/split-boxes-demo.png rename to docs/feature-management-experimentation/10-getting-started/static/split-boxes-demo.png diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/android-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/android-sdk.md index a83197ab713..e6184c2c2f0 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/android-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/android-sdk.md @@ -55,7 +55,7 @@ implementation 'io.split.client:android-client:5.3.1' The first time the SDK is instantiated, it starts background tasks to update an in-memory cache and in-storage cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of the data. -If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it is in this intermediate state, it may not have the data necessary to run the evaluation. In this circumstance, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it is in this intermediate state, it may not have the data necessary to run the evaluation. In this circumstance, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). After the first initialization, the fetched data is stored. Further initializations fetch data from that cache and the configuration is immediately available. @@ -274,7 +274,7 @@ client.on(SplitEvent.SDK_READY_FROM_CACHE, object : SplitEventTask() { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `getTreatment` methods need to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `getTreatment` methods need to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the Rollout plan as defined in Harness FME to decide which treatment is assigned to this key. @@ -564,7 +564,7 @@ val treatmentsByFlagSets = client.getTreatmentsByFlagSets(flagSets) ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), use the `getTreatmentWithConfig` method. This method returns an object containing the treatment and associated configuration. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), use the `getTreatmentWithConfig` method. This method returns an object containing the treatment and associated configuration. The config element is a stringified version of the configuration JSON defined in Harness FME. If there is no configuration defined for a treatment, the SDK returns `null` for the config parameter. @@ -638,7 +638,7 @@ val treatmentsByFlagSets = client.getTreatmentsWithConfigByFlagSets(flagSetNames ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `getTreatment` method. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/angular-utilities.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/angular-utilities.md index 7108fc9e534..6adc232543d 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/angular-utilities.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/angular-utilities.md @@ -68,7 +68,7 @@ Configure the service with the SDK key for the FME environment that you would li ### Basic use -When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, block until the SDK is ready, as shown below. You can subscribe to `splitService.sdkReady$` observable provided by splitService before asking for an evaluation. @@ -92,7 +92,7 @@ this.splitService.sdkReady$.subscribe(() => { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the splitService's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the splitService's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -185,7 +185,7 @@ const treatments: SplitIO.Treatments = this.splitService.getTreatmentsByFlagSets ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), use the `getTreatmentWithConfig` method. This method returns an object with the structure below: +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), use the `getTreatmentWithConfig` method. This method returns an object with the structure below: ```javascript title="TypeScript" type TreatmentResult = { diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/browser-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/browser-sdk.md index 7a2483ba8e8..8c880da2beb 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/browser-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/browser-sdk.md @@ -158,7 +158,7 @@ Configure the SDK with the SDK key for the FME environment that you would like t ### Basic use -When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, block until the SDK is ready, as shown below. We set the client to listen for the `SDK_READY` event triggered by the SDK before asking for an evaluation. @@ -205,7 +205,7 @@ client.on(client.Event.SDK_READY, function() { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -374,7 +374,7 @@ treatments = client.getTreatmentsByFlagSets(flagSets); ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `getTreatmentWithConfig` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `getTreatmentWithConfig` method. This method will return an object with the structure below: @@ -479,7 +479,7 @@ treatmentResults = client.getTreatmentsWithConfigByFlagSets(flagSets); ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `getTreatment` method. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data. @@ -764,7 +764,7 @@ const client = factory.client(); For testing, a developer can put code behind feature flags on their development machine without the SDK requiring network connectivity. To achieve this, the SDK can be started in **localhost** mode (aka off-the-grid or offline mode). In this mode, the SDK neither polls nor updates Harness servers. Instead, it uses an in-memory data structure to determine what treatments to show to the logged in customer for each of the features. Define the feature flags you want to use in the `features` object map. All `getTreatment` calls for a feature flag now only return the one treatment (and config, if defined) that you have defined in the map. -Any feature that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK was asked to evaluate them. +Any feature that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK was asked to evaluate them. You can use the additional configuration parameters below when instantiating the SDK in `localhost` mode. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/flutter-plugin.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/flutter-plugin.md index 945edf6f021..2b6c46e20d9 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/flutter-plugin.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/flutter-plugin.md @@ -49,7 +49,7 @@ Configure the plugin with the SDK key for the FME environment that you would lik ### Basic use -When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it's in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it's in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, wait until the SDK is ready, as shown below. You can use the `onReady` parameter when creating the client to get notified when this happens. @@ -72,7 +72,7 @@ _split.client(onReady: (client) async { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), pass the client's `getTreatment` method as an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), pass the client's `getTreatment` method as an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. The `getTreatment` method supports five types of attributes: strings, numbers, dates, booleans, and sets. The proper data type and syntax for each are: @@ -195,7 +195,7 @@ _split.client(onReady: (client) async { ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), use the `getTreatmentWithConfig` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), use the `getTreatmentWithConfig` method. This method returns an object containing the treatment and associated configuration: diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/ios-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/ios-sdk.md index d7c915bf047..eb8ccfe1225 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/ios-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/ios-sdk.md @@ -53,7 +53,7 @@ Once added, follow the steps provided in the [Carthage Readme](https://github.co The first time that the SDK is instantiated, it starts background tasks to update an in-memory cache and in-storage cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of the data. -If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it is in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it is in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). After the first initialization, the fetched data is stored. Further initializations fetch data from that cache and the configuration is available immediately. @@ -157,7 +157,7 @@ client?.on(event: SplitEvent.sdkReadyFromCache, queue: customQueue) { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the Rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -304,7 +304,7 @@ let treatmentsByFlagSets = client.getTreatmentsByFlagSets(flagSets, attributes: ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), use the `getTreatmentWithConfig` methods. These methods returns an object containing the treatment and associated configuration. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), use the `getTreatmentWithConfig` methods. These methods returns an object containing the treatment and associated configuration. The config element is a stringified version of the configuration JSON defined in Harness FME. If there is no configuration defined for a treatment, the SDK returns `null` for the config parameter. @@ -336,7 +336,7 @@ let treatmentsByFlagSets = client.getTreatmentsWithConfigByFlagSets(flagSets, at ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `getTreatment` method. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/javascript-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/javascript-sdk.md index 069929ed211..5ce2c6b29b3 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/javascript-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/javascript-sdk.md @@ -2,6 +2,7 @@ title: JavaScript SDK sidebar_label: JavaScript SDK redirect_from: + - /docs/feature-management-experimentation/feature-management/faqs/why-are-some-users-double-bucketed/ - /docs/feature-management-experimentation/sdks-and-infrastructure/faqs-client-side-sdks/javascript-sdk-localhost-mode-does-not-support-allowlist-keys - /docs/feature-management-experimentation/sdks-and-infrastructure/faqs-client-side-sdks/javascript-sdk-cors-error-in-streaming-call-when-running-sdk-in-service-worker - /docs/feature-management-experimentation/sdks-and-infrastructure/faqs-client-side-sdks/javascript-sdk-does-sdk-ready-event-fire-only-once @@ -148,7 +149,7 @@ Configure the SDK with the SDK key for the FME environment that you would like t ### Basic use -When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it's in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it's in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK properly loads before asking it for a treatment, block until the SDK is ready, as shown below. We set the client to listen for the `SDK_READY` event triggered by the SDK before asking for an evaluation. @@ -193,7 +194,7 @@ client.on(client.Event.SDK_READY, function() { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -363,7 +364,7 @@ treatments = client.getTreatmentsByFlagSets(flagSets); ### Get Treatments with Configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), use the `getTreatmentWithConfig` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), use the `getTreatmentWithConfig` method. This method returns an object with the structure below: @@ -488,7 +489,7 @@ treatmentResults = client.getTreatmentsWithConfigByFlagSets(flagSets); ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `getTreatment` method. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data. @@ -727,7 +728,7 @@ For testing, a developer can put code behind feature flags on their development When instantiating the SDK in localhost mode, your `authorizationKey` is `localhost`. Define the feature flags you want to use in the `features` object map. All `getTreatment` calls for a feature flag now only return the one treatment (and config, if defined) that you have defined in the map. -Any feature that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK was asked to evaluate them. +Any feature that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK was asked to evaluate them. You can use the additional configuration parameters below when instantiating the SDK in `localhost` mode. @@ -1419,6 +1420,66 @@ The following example applications detail how to configure and instantiate the J ## Troubleshooting +### User IDs Being Double Bucketed (SDK_READY_TIMED_OUT Event Issue) + +Using the JavaScript SDK, some percentage of User IDs are double bucketed: the same User ID is processed in the Control block, and at a later call in an actual treatment block. + +One possible root cause is that the JavaScript SDK engine completes fetching treatments after the `requestTimeoutBeforeReady` or `readyTimeout` parameter expires, firing the browser event `SDK_READY_TIMED_OUT`. + +This tends to happen for mobile users with slow internet connections. + +If the JavaScript code does not properly handle this event—for example, if it only raises an error and exits: + +```javascript +var client = SdkFactory.client(); +this.clientReady = new Promise(function(resolve, reject) { + client.once(client.Event.SDK_READY, function() { + resolve(); + }); + client.once(client.Event.SDK_READY_TIMED_OUT, function() { + reject(new Error("Client SDK Ready Timed Out")); + }); +}); +``` + +There are two possible events: + +* If the `SDK_READY` event comes first, the promise resolves, and everything works as expected. +* If the `SDK_READY_TIMED_OUT` event comes first, the promise rejects and remains rejected, meaning that any `.catch()` attached will always be called—even if the SDK eventually becomes ready later. + +If you add a `.catch()` that does not return or throw an error, the wrapper code might continue executing as if the SDK is ready, even when it is not. For example: + +```javascript +this.clientReady.catch(() => {}).then(() => { +}); +``` + +Here, the `.catch()` swallows the error without returning or throwing, causing the promise chain to appear "recovered." This can cause code to run prematurely against an SDK that isn’t ready. + +Even if the `SDK_READY_TIMED_OUT` event fires, the SDK might become ready a few milliseconds later and emit the `SDK_READY` event. You should handle these events only when you actually want to respond to them. + +1. Allow the SDK to retry fetching treatments a couple of times before giving up, increasing the chance the SDK becomes ready within the timeout: + + ```javascript + startup: { + requestTimeoutBeforeReady: 5, // 5 seconds + readyTimeout: 5, // 5 seconds + retriesOnFailureBeforeReady: 2, // 2 retries + } + ``` + +1. Configure the SDK to store `Splits` and `mySegments` data in the browser’s `LOCALSTORAGE`. This caches data between page loads and reduces fetch time on subsequent page visits, making the SDK ready faster: + + ```javascript + storage: { + type: 'LOCALSTORAGE', + prefix: 'MYPREFIX' + }, + ``` + + Use a custom prefix to prevent data collision across projects. + +For more information, see the [API reference documentation](https://docs.split.io/docs/javascript-sdk-overview#section-configuration). ### CORS Error in streaming call when running the SDK in a Service Worker When running the JavaScript SDK inside a Service Worker, the SDK’s streaming HTTP call to `streaming.split.io` can be blocked by the browser’s CORS policy. @@ -1664,4 +1725,4 @@ var factory = splitio({ var user_client = factory.client('CUSTOMER_ID', 'TRAFFIC_TYPE'); ``` -This correctly appends the key ID to the URL and prevents the 404 error. \ No newline at end of file +This correctly appends the key ID to the URL and prevents the 404 error. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/react-native-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/react-native-sdk.md index 519cfa64338..aca64c1a6eb 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/react-native-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/react-native-sdk.md @@ -141,7 +141,7 @@ Configure the SDK with the SDK key for the FME environment that you would like t ### Basic use -When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, block until the SDK is ready, as shown below. We set the client to listen for the `SDK_READY` event triggered by the SDK before asking for an evaluation. @@ -202,7 +202,7 @@ LogBox.ignoreLogs(['Setting a timer']); ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -378,7 +378,7 @@ treatments = client.getTreatmentsByFlagSets(flagSets); ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `getTreatmentWithConfig` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `getTreatmentWithConfig` method. This method returns an object with the structure below: @@ -693,7 +693,7 @@ For testing, a developer can put code behind feature flags on their development Define the feature flags you want to use in the `features` object map. All `getTreatment` calls for a feature flag now only return the one treatment (and config, if defined) that you have defined in the map. You can then change the treatment as necessary for your testing. To update a treatment or a config, or to add or remove feature flags from the mock cache, update the properties of the `features` object you've provided. The SDK simulates polling for changes and updates from it. Do not assign a new object to the `features` property because the SDK has a reference to the original object and will not detect the change. -Any feature that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK was asked to evaluate them. +Any feature that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK was asked to evaluate them. You can use the additional configuration parameters below when instantiating the SDK in `localhost` mode. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/react-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/react-sdk.md index 07756c1acb2..84164ba648d 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/react-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/react-sdk.md @@ -208,11 +208,11 @@ Configure the SDK with the SDK key for the FME environment that you would like t ### Get treatments with configurations -When the SDK is instantiated, it kicks off background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it kicks off background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, block until the SDK is ready, as shown below. We provide the `isReady` boolean prop based on the client that will be used by the component. Internally we listen for the `SDK_READY` event triggered by given SDK factory client to set the value of `isReady`. -After the `isReady` prop is set to true, you can use the SDK. The `useSplitTreatments` hook returns the proper treatments based on the `names` prop value passed to it and the `core.key` value you passed in the config when instantiating the SDK. Then use the `treatments` property to access the treatment values as well as the corresponding [dynamic configurations](/docs/feature-management-experimentation/feature-management/dynamic-configurations) that you defined in Harness FME. Remember to handle the client returning control as a safeguard. +After the `isReady` prop is set to true, you can use the SDK. The `useSplitTreatments` hook returns the proper treatments based on the `names` prop value passed to it and the `core.key` value you passed in the config when instantiating the SDK. Then use the `treatments` property to access the treatment values as well as the corresponding [dynamic configurations](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations) that you defined in Harness FME. Remember to handle the client returning control as a safeguard. Similarly to the vanilla JS SDK, React SDK supports the ability to evaluate flags based on cached content when using [LOCALSTORAGE](/docs/feature-management-experimentation/sdks-and-infrastructure/client-side-sdks/javascript-sdk#configuration) as storage type. In this case, the `isReadyFromCache` prop will change to true almost instantly since access to the cache is synchronous, allowing you to consume flags earlier on components that are critical to your UI. Keep in mind that the data might be stale until `isReady` prop is true. Read more [below](#subscribe-to-events-and-changes). @@ -384,7 +384,7 @@ export default class MyComponentToggle extends React.Component { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the underlying `getTreatmentsWithConfig` or `getTreatmentsWithConfigByFlagSets` call, whether you are evaluating using the `names` or `flagSets` property respectively. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. The SDK supports five types of attributes: strings, numbers, dates, booleans, and sets. The proper data type and syntax for each are: +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the underlying `getTreatmentsWithConfig` or `getTreatmentsWithConfigByFlagSets` call, whether you are evaluating using the `names` or `flagSets` property respectively. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. The SDK supports five types of attributes: strings, numbers, dates, booleans, and sets. The proper data type and syntax for each are: * **Strings:** Use type String. * **Numbers:** Use type Number. @@ -612,7 +612,7 @@ class MyComponent extends React.Component { ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the SDK each time an evaluation is done using the `useSplitTreatments` hook. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the SDK each time an evaluation is done using the `useSplitTreatments` hook. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `useSplitTreatments` hook. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data. @@ -764,7 +764,7 @@ For testing, a developer can put code behind feature flags on their development When instantiating the SDK in localhost mode, your `authorizationKey` is `"localhost"`. Define the feature flags you want to use in the `features` object map. All `useSplitTreatments` calls for a feature flag return the treatment (and config, if defined) that you have defined in the map. You can then change the treatment as necessary for your testing. If you want to update a treatment or a config, or to add or remove feature flags from the mock cache, update the properties of the `features` object you've provided. The SDK simulates polling for changes and updates from the `features` object. Do not assign a new object to the `features` property because the SDK has a reference to the original object and will not detect the change. -Any feature that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK is asked to evaluate them. Use the following additional configuration parameters when instantiating the SDK in `localhost` mode: +Any feature that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK is asked to evaluate them. Use the following additional configuration parameters when instantiating the SDK in `localhost` mode: | **Configuration** | **Description** | **Default value** | | --- | --- | --- | diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/redux-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/redux-sdk.md index 6726489d539..3311621c603 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/redux-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-sdks/redux-sdk.md @@ -405,7 +405,7 @@ Note that these treatments won't be updated automatically when there is a change ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `getTreatments` action creator needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `getTreatments` action creator needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatments` action creator call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -552,7 +552,7 @@ function onUpdateCallback() { ### Get Treatments with Configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you don't need to call a specific action creator for your evaluations. Instead, our SDK stores both the treatment and the associated config (or null if there isn't one) in the Redux state. To access this values you can either use the `selectTreatmentWithConfigAndStatus` selector (recommended) or just access the config from the state. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you don't need to call a specific action creator for your evaluations. Instead, our SDK stores both the treatment and the associated config (or null if there isn't one) in the Redux state. To access this values you can either use the `selectTreatmentWithConfigAndStatus` selector (recommended) or just access the config from the state. Each evaluation entry loaded into the state under the `treatments` key will have the structure below: @@ -630,7 +630,7 @@ const treatmentResult = splitTreatments['key']['feature_flag_1']; ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the SDK each time an evaluation is done using the `getTreatments` action creator. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the SDK each time an evaluation is done using the `getTreatments` action creator. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `getTreatments` action creator. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data. @@ -796,7 +796,7 @@ For testing, a developer can put code behind feature flags on their development When instantiating the SDK in localhost mode, your `authorizationKey` is `"localhost"`. Define the feature flags you want to use in the `features` object map. All feature flag evaluations with `getTreatments` actions return the one treatment (and config, if defined) that you have defined in the map. You can then change the treatment as necessary for your testing. If you want to update a treatment or a config, or to add or remove feature flags from the mock cache, update the properties of the `features` object you've provided. The SDK simulates polling for changes and updates from it. Do not assign a new object to the `features` property because the SDK has a reference to the original object and will not detect the change. -Any feature flag that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK is asked to evaluate them. Use the following additional configuration parameters when instantiating the SDK in `localhost` mode: +Any feature flag that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK is asked to evaluate them. Use the following additional configuration parameters when instantiating the SDK in `localhost` mode: | **Configuration** | **Description** | **Default value** | | --- | --- | --- | diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/android-suite.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/android-suite.md index 464cd0587d0..01ccc623d66 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/android-suite.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/android-suite.md @@ -98,7 +98,7 @@ Configure the Suite with the SDK key for the FME environment that you would like ### Basic use -When the Suite is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of the data. If the Suite is asked to evaluate which treatment to show to a user for a specific feature flag while in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the Suite does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the Suite is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of the data. If the Suite is asked to evaluate which treatment to show to a user for a specific feature flag while in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the Suite does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the Suite is properly loaded before asking it for a treatment, block until the Suite is ready, as shown below. We set the client to listen for the `SDK_READY` event triggered by the Suite before asking for an evaluation. @@ -163,7 +163,7 @@ client.on(SplitEvent.SDK_READY, object : SplitEventTask() { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the Suite's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the Suite's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -350,7 +350,7 @@ val treatmentsByFlagSets = client.getTreatmentsByFlagSets(flagSets) ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `getTreatmentWithConfig` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `getTreatmentWithConfig` method. This method will return an object with the structure below: diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/browser-suite.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/browser-suite.md index 1cb107050e7..527d5a937cb 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/browser-suite.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/browser-suite.md @@ -139,7 +139,7 @@ Configure the Suite with the SDK key for the FME environment that you would like ### Basic use -When the Suite is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of the data. If the Suite is asked to evaluate which treatment to show to a user for a specific feature flag while in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the Suite does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the Suite is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of the data. If the Suite is asked to evaluate which treatment to show to a user for a specific feature flag while in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the Suite does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the Suite is properly loaded before asking it for a treatment, block until the Suite is ready, as shown below. We set the client to listen for the `SDK_READY` event triggered by the Suite before asking for an evaluation. @@ -186,7 +186,7 @@ client.on(client.Event.SDK_READY, function() { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the Suite's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the Suite's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -362,7 +362,7 @@ treatments = client.getTreatmentsByFlagSets(flagSets); ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `getTreatmentWithConfig` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `getTreatmentWithConfig` method. This method will return an object with the structure below: @@ -483,7 +483,7 @@ treatmentResults = client.getTreatmentsWithConfigByFlagSets(flagSets); ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the Suite each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the Suite each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `getTreatment` method. These properties are then included in the impression sent by the Suite and can provide useful context to the impression data. @@ -791,7 +791,7 @@ For testing, a developer can evaluate FME feature flags on their development mac Define the feature flags you want to use in the `features` object map. All `getTreatment` calls for a feature flag now only return the one treatment (and config, if defined) that you have defined in the map. You can then change the treatment as necessary for your testing. To update a treatment or a config, or to add or remove feature flags from the mock cache, update the properties of the `features` object you've provided. The SDK simulates polling for changes and updates from it. Do not assign a new object to the `features` property because the SDK has a reference to the original object and will not detect the change. -Any feature flag that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK is asked to evaluate it. +Any feature flag that is not provided in the `features` map returns the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK is asked to evaluate it. You can use the additional configuration parameters below when instantiating the SDK in `localhost` mode. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/ios-suite.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/ios-suite.md index eaaedd829f0..a23222b3be2 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/ios-suite.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/client-side-suites/ios-suite.md @@ -82,7 +82,7 @@ Configure the Suite with the SDK key for the FME environment that you would like ### Basic use -When the Suite is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of the data. If the Suite is asked to evaluate which treatment to show to a user for a specific feature flag while in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the Suite does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the Suite is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of the data. If the Suite is asked to evaluate which treatment to show to a user for a specific feature flag while in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the Suite does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the Suite is properly loaded before asking it for a treatment, block until the Suite is ready, as shown below. We set the client to listen for the `SDK_READY` event triggered by the Suite before asking for an evaluation. @@ -107,7 +107,7 @@ client?.on(event: SplitEvent.sdkReady) { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the Suite's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the Suite's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -217,7 +217,7 @@ let treatmentsByFlagSets = client.getTreatmentsByFlagSets(flagSets, attributes: ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), use the `getTreatmentWithConfig` method. This method returns an object containing the treatment and associated configuration. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), use the `getTreatmentWithConfig` method. This method returns an object containing the treatment and associated configuration. The config element is a stringified version of the configuration JSON defined in Harness FME. If there is no configuration defined for a treatment, the `result.config` property will be `nil`. @@ -248,7 +248,7 @@ let treatmentsByFlagSets = client.getTreatmentsWithConfigByFlagSets(flagSets, at ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `getTreatment` method. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/elixir-thin-client-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/elixir-thin-client-sdk.md index 8bbaa3258d3..eaf54b0d226 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/elixir-thin-client-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/elixir-thin-client-sdk.md @@ -103,7 +103,7 @@ end After you start the SDK, you can use the `Split.get_treatment/3` function to decide what version of your features your customers are served. The function requires the `FEATURE_FLAG_NAME` argument that you want to ask for a treatment and a unique `key` argument that corresponds to the end user that you want to serve the feature to. -From there, you simply need to use an if-else-if or case statement block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +From there, you simply need to use an if-else-if or case statement block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). ```elixir title="Elixir" ## The key here represents the string ID of the user/account/etc you're trying to evaluate a treatment for @@ -120,7 +120,7 @@ end ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `get_treatment` function needs to pass an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `get_treatment` function needs to pass an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `get_treatment` call in a map. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -185,7 +185,7 @@ You can also use the [Split Manager](#manager) to get all of your treatments at ### Get Treatments with Configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `Split.get_treatment_with_config/3` function. This function returns an `Split.TreatmentWithConfig` struct containing the treatment and associated configuration. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `Split.get_treatment_with_config/3` function. This function returns an `Split.TreatmentWithConfig` struct containing the treatment and associated configuration. The config element is a stringified version of the configuration JSON defined in Harness FME. If there is no configuration defined for a treatment, the SDK returns `nil` for the config parameter. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/go-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/go-sdk.md index 0d4ac3c7979..804bdfca613 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/go-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/go-sdk.md @@ -71,7 +71,7 @@ Starting version 4.0.0, cfg.BlockUntilReady is deprecated and migrated to the fo When the SDK is instantiated in `inmemory-standalone` operation mode, it kicks off background tasks to update an in-memory or Redis cache. -This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it is in this intermediate state, it may not have the data necessary to run the evaluation. In this circumstance, the SDK does not fail, but instead returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it is in this intermediate state, it may not have the data necessary to run the evaluation. In this circumstance, the SDK does not fail, but instead returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, you need to block until the SDK is ready. You can block by using the `BlockUntilReady(int)` method as part of the instantiation process of the SDK factory client as shown below. Do this as a part of the startup sequence of your application. @@ -108,7 +108,7 @@ Now you can start asking the SDK to evaluate treatments for your customers. After you instantiate the SDK factory client, you can start using the client's `Treatment` method to decide what version of your feature flags your customers are served. The method requires the `FEATURE_FLAG_NAME` attribute that you want to ask for a treatment and a unique `key` attribute that corresponds to the end user that you are serving the feature flag to. -Then use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +Then use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). ```go title="Go" // The key here represents the ID of the user/account/etc you're trying to evaluate a treatment for @@ -130,7 +130,7 @@ The arguments for the `Treatment()` call are: ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `Treatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `Treatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `Treatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or off` treatment to this account. @@ -196,7 +196,7 @@ treatments := splitClient.TreatmentsByFlagSets("KEY", []string{"backend", "serve ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `TreatmentWithConfig` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `TreatmentWithConfig` method. This method will return an object containing the treatment and associated configuration. @@ -718,7 +718,7 @@ factory, err := client.NewSplitFactory("localhost", sdkConf) In this mode, the SDK loads a mapping of feature flag name to treatment from a file at `$HOME/.split`. For a given flag, the treatment specified in the file is returned for every customer. -`getTreatment` calls for a feature flag and only returns the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature flag that is not provided in the `featureFlag` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK is asked to evaluate them. +`getTreatment` calls for a feature flag and only returns the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature flag that is not provided in the `featureFlag` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK is asked to evaluate them. The format of this file is two columns separated by a whitespace. The left column is the feature flag name and the right column is the treatment name. The following is a sample `.split` file: diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/java-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/java-sdk.md index 2561e25b22f..8ffd63658b4 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/java-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/java-sdk.md @@ -82,7 +82,7 @@ Starting version 3.0.1, SplitClientConfig#ready(int) is deprecated and migrated * Call `SplitClient#blockUntilReady()` or `SplitManager#blockUntilReady()`. ::: -When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it's in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it's in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, block until the SDK is ready. Do this by setting the desired wait using `.setBlockUntilReadyTimeout()` in the configuration and calling `blockUntilReady()` on the client. Do this all as a part of the startup sequence of your application. @@ -144,7 +144,7 @@ Now you can start asking the SDK to evaluate treatments for your customers. After you instantiate the SDK factory client, you can start using the `getTreatment` method of the SDK factory client to decide what version of your features your customers are served. The method requires the `FEATURE_FLAG_NAME` attribute that you want to ask for a treatment and a unique `key` attribute that corresponds to the end user that you are serving the feature to. -Then use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +Then use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). @@ -187,7 +187,7 @@ when (treatment) { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the Rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -313,7 +313,7 @@ val treatmentsBySets = client.getTreatmentsByFlagSets("KEY", flagSetNames) ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `getTreatmentWithConfig` method. This method returns an object containing the treatment and associated configuration. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `getTreatmentWithConfig` method. This method returns an object containing the treatment and associated configuration. The config element is a stringified version of the configuration JSON defined in Harness FME. If there is no configuration defined for a treatment, the SDK returns `null` for the config parameter. @@ -381,7 +381,7 @@ val treatmentsBySets: Map = client.getTreatmentsWithConfigB ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `getTreatment` method. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data. @@ -1041,7 +1041,7 @@ val client: SplitClient = splitFactory.client() In this mode, the SDK loads a mapping of feature flag name to treatment from a file at `$HOME/.split`. For a given flag, the treatment specified in the file is returned for every customer. -`getTreatment` calls for a feature flag and only returns the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature that is not provided in the `features` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK is asked to evaluate them. +`getTreatment` calls for a feature flag and only returns the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature that is not provided in the `features` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK is asked to evaluate them. The format of this file is two columns separated by a whitespace. The left column is the feature flag name and the right column is the treatment name. The following is a sample `.split` file: diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/net-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/net-sdk.md index ecddae3df25..02d05ecc09e 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/net-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/net-sdk.md @@ -45,7 +45,7 @@ Starting version 5.0.0, .Ready is deprecated and migrated to the following imple Call `SplitClient.BlockUntilReady(int milliseconds)` or `SplitManager.BlockUntilReady(int milliseconds)`. ::: -When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, block until the SDK is ready. This is done by using `.BlockUntilReady(int milliseconds)` method as part of the instantiation process of the SDK factory client as shown below. Do this all as a part of the startup sequence of your application. If SDK is not ready after the specified time, the SDK fails to initialize and throws a `TimeoutException` error. @@ -79,7 +79,7 @@ Now you can start asking the SDK to evaluate treatments for your customers. After you instantiate the SDK factory client, you can use the `GetTreatment` method of the SDK factory client to decide what version of your features your customers are served. The method requires the `FEATURE_FLAG_NAME` attribute that you want to ask for a treatment and a unique `key` attribute that corresponds to the end user that you are serving the feature to. -Then use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +Then use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). @@ -128,7 +128,7 @@ else ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `GetTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `GetTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `GetTreatment` call. These attributes are compared and evaluated against the attributes used in the Rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -293,7 +293,7 @@ You can also use the [Split Manager](#manager) to get all of your treatments at ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `GetTreatmentWithConfig` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `GetTreatmentWithConfig` method. This method returns an object containing the treatment and associated configuration. @@ -795,7 +795,7 @@ catch (Exception ex) In this mode, the SDK loads a mapping of feature flag name to treatment from a file at `$HOME/.split`. For a given feature flag, the treatment specified in the file is returned for every customer. -`GetTreatment` calls for a feature flag only return the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature flag that is not provided in the `features` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK is asked to evaluate them. +`GetTreatment` calls for a feature flag only return the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature flag that is not provided in the `features` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK is asked to evaluate them. The format of this file is two columns separated by a whitespace. The left column is the feature flag name, and the right column is the treatment name. Here is a sample `.split` file. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/nodejs-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/nodejs-sdk.md index 2706e1d7d4f..6577e7f4447 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/nodejs-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/nodejs-sdk.md @@ -105,13 +105,13 @@ Use the SDK factory client to evaluate treatments. ### Basic use -When the SDK is instantiated, it kicks off background jobs to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds. While the SDK is in this intermediate state, if it is asked to evaluate which treatment to show to the logged in customer for a specific feature flag, it may not have data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it kicks off background jobs to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds. While the SDK is in this intermediate state, if it is asked to evaluate which treatment to show to the logged in customer for a specific feature flag, it may not have data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, block until the SDK is ready (as shown below). We set the client to listen for the `SDK_READY` event triggered by the SDK before asking for an evaluation. When the `SDK_READY` event fires, you can use the `getTreatment` method to return the proper treatment based on the `key` and `FEATURE_FLAG_NAME` attributes you provided. -Then use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning the [control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +Then use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning the [control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). @@ -155,7 +155,7 @@ client.on(client.Event.SDK_READY, () => { ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `getTreatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `getTreatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -289,7 +289,7 @@ If your code runs with both types of storage, read [Working with both sync and a ### Get treatments with configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `getTreatmentWithConfig` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `getTreatmentWithConfig` method. This method will return an object containing the treatment and associated configuration. @@ -373,7 +373,7 @@ treatmentResults = client.getTreatmentsWithConfigByFlagSets('user_id', flagSets) ### Append properties to impressions -[Impressions](/docs/feature-management-experimentation/feature-management/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. +[Impressions](/docs/feature-management-experimentation/feature-management/monitoring-analysis/impressions) are generated by the SDK each time a `getTreatment` method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation. You can append properties to an impression by passing an object of key-value pairs to the `getTreatment` method. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data. @@ -841,7 +841,7 @@ client.on(client.Event.SDK_READY, function() { In this mode, the SDK loads a mapping of feature flag name to treatment from a file at `$HOME/.split`. For a given feature flag, the treatment specified in the file is returned for every customer. Should you want to use another file, you just need to set the `features` key in the configuration object passed at instantiation time, to the full path of the desired file. -`getTreatment` calls for a feature flag only return the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature flag that is not provided in the `features` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK is asked to evaluate them. +`getTreatment` calls for a feature flag only return the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature flag that is not provided in the `features` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK is asked to evaluate them. Here is a sample `.split` file. The format of this file is two columns separated by a whitespace. The left column is the feature flag name, and the right column is the treatment name. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/php-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/php-sdk.md index 47bddc53de7..d23105920d5 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/php-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/php-sdk.md @@ -88,7 +88,7 @@ $splitClient = $splitFactory->client(); After you instantiate the SDK factory client, use the `getTreatment` method of the SDK factory client to decide what version of your feature flags your customers are served. The method requires the `FEATURE_FLAG_NAME` attribute that you want to ask for a treatment and a unique `key` attribute that corresponds to the end user that you want to serve the feature flag to. -From there, you need to use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +From there, you need to use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). ```php title="PHP" client(); In this mode, the SDK loads a mapping of feature flag name to treatment from a file at `$HOME/.split`. For a given feature flag, the treatment specified in the file is returned for every customer. -`getTreatment` calls for a feature flag only return the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature flag that is not provided in the `featureFlags` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK is asked to evaluate them. +`getTreatment` calls for a feature flag only return the one treatment that you defined in the file. You can then change the treatment as necessary for your testing in the file. Any feature flag that is not provided in the `featureFlags` map returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK is asked to evaluate them. The format of this file is two columns separated by a whitespace. The left column is the feature flag name, and the right column is the treatment name. Here is a sample `.split` file. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/php-thin-client-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/php-thin-client-sdk.md index 92c9a9e0d12..80584ef6955 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/php-thin-client-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/php-thin-client-sdk.md @@ -55,7 +55,7 @@ $client = $factory->client(); After you instantiate the SDK factory client, you can start using the `getTreatment` method of the SDK factory client to decide what version of your features your customers are served. The method requires the `FEATURE_FLAG_NAME` attribute that you want to ask for a treatment and a unique `key` attribute that corresponds to the end user that you want to serve the feature to. -From there, you simply need to use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +From there, you simply need to use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). ```php title="PHP" @@ -519,7 +519,7 @@ If the `key` attribute is something other than `string`, Python SDK returns `CON ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `get_treatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `get_treatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `get_treatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -663,7 +663,7 @@ print(treatments) ### Get Treatments with Configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `get_treatment_with_config` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `get_treatment_with_config` method. This method will return an object containing the treatment and associated configuration. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/ruby-sdk.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/ruby-sdk.md index 66cd00668ab..c7b57fdfade 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/ruby-sdk.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/server-side-sdks/ruby-sdk.md @@ -46,7 +46,7 @@ Since version 2.0.0 of the split-synchronizer, we use a more efficient scheme to ### 2. Instantiate the SDK and create a new SDK factory client -When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while its in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). To make sure the SDK is properly loaded before asking it for a treatment, block it until the SDK is ready. You can do this by using the `block_until_ready` method of the SDK factory client (or Manager) as part of the instantiation process of the SDK as shown below. Do this as a part of the startup sequence of your application. @@ -149,7 +149,7 @@ If you are running NGINX with `thread_spawn_method = 'smart'`, use our Redis int After you instantiate the SDK factory client, you can start using the `get_Treatment` method of the SDK factory client to decide what version of your features your customers are served. The method requires the `FEATURE_FLAG_NAME` attribute that you want to ask for a treatment and a unique `KEY` attribute that corresponds to the end user that you want to serve the feature to. -From there, you simply need to use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment). +From there, you simply need to use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment). ```ruby title="Ruby" ## The key here represents the ID of the user, account, etc. you're trying to evaluate a treatment for @@ -166,7 +166,7 @@ end ### Attribute syntax -To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/target-with-custom-attributes), the SDK's `get_treatment` method needs to be passed an attribute map at runtime. +To [target based on custom attributes](/docs/feature-management-experimentation/feature-management/targeting/target-with-custom-attributes), the SDK's `get_treatment` method needs to be passed an attribute map at runtime. In the example below, we are rolling out a feature flag to users. The provided attributes `plan_type`, `registered_date`, `permissions`, `paying_customer`, and `deal_size` are passed to the `get_treatment` call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the `on` or `off` treatment to this account. @@ -237,7 +237,7 @@ You can also use the [Split Manager](#manager) if you want to get all of your tr ### Get Treatments with Configurations -To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/dynamic-configurations), you should use the `get_treatment_with_config` method. +To [leverage dynamic configurations with your treatments](/docs/feature-management-experimentation/feature-management/setup/dynamic-configurations), you should use the `get_treatment_with_config` method. This method will return an object containing the treatment and associated configuration. @@ -503,7 +503,7 @@ In the example given, a call to `get_treatment` passing `john_doe` as the key re config: {'desc': 'this applies only to ON and only for john_doe and jane_doe. The rest will receive OFF'} ``` -Any feature that is not provided in the `split_file` markup map returns [the control treatment](/docs/feature-management-experimentation/feature-management/control-treatment) if the SDK is asked to evaluate them. +Any feature that is not provided in the `split_file` markup map returns [the control treatment](/docs/feature-management-experimentation/feature-management/setup/control-treatment) if the SDK is asked to evaluate them. By default, changes in the file are not automatically picked up without restarting the client. To have the client automatically pick up changes to the file, specify `reload_rate` as the interval in seconds at which changes are picked up. Here is an example of specifying both `split_file` and `reload_rate`. diff --git a/docs/feature-management-experimentation/20-sdks-and-infrastructure/validate-sdk-setup.md b/docs/feature-management-experimentation/20-sdks-and-infrastructure/validate-sdk-setup.md index 0961e301605..48948f10f4b 100644 --- a/docs/feature-management-experimentation/20-sdks-and-infrastructure/validate-sdk-setup.md +++ b/docs/feature-management-experimentation/20-sdks-and-infrastructure/validate-sdk-setup.md @@ -41,7 +41,7 @@ The following validation considerations are relevant for all FME SDKs. * **Validate 24 hours of impressions (and events) from the Data hub.** Take a feature flag that has a known high activity and download all impressions for it from the previous 24 hour period. Ensure that the number of treatments and IDs all match with expectations. For events, take the previous full 24 hours of events, if applicable. With impressions, take note if you are seeing any ‘CONTROL’ treatments as those warrant further investigation to understand why those are happening. -* **Evaluate if you can take advantage of Flag Sets** You can use Flag Sets for limiting the flags downloaded by an SDK. [Flag Sets](/docs/feature-management-experimentation/feature-management/using-flag-sets-to-boost-sdk-performance) allow you to control from Harness FME which flags are downloaded by an SDK. This means you can ensure that only the flags needed for a frontend SDK or a backend SDK are downloaded. This reduces the time for the SDK to get ready while also saving memory and bandwidth. +* **Evaluate if you can take advantage of Flag Sets** You can use Flag Sets for limiting the flags downloaded by an SDK. [Flag Sets](/docs/feature-management-experimentation/feature-management/manage-flags/using-flag-sets-to-boost-sdk-performance) allow you to control from Harness FME which flags are downloaded by an SDK. This means you can ensure that only the flags needed for a frontend SDK or a backend SDK are downloaded. This reduces the time for the SDK to get ready while also saving memory and bandwidth. ## Browser SDKs (including Angular, React, etc.) diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/_category_.json b/docs/feature-management-experimentation/40-feature-management/best-practices/_category_.json deleted file mode 100644 index 5dc379bfa40..00000000000 --- a/docs/feature-management-experimentation/40-feature-management/best-practices/_category_.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "label": "Best practices", - "collapsible": "true", - "collapsed": "true", - "className": "red" -} \ No newline at end of file diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/best-practices-when-targeting-an-account-or-organization.md b/docs/feature-management-experimentation/40-feature-management/best-practices/best-practices-when-targeting-an-account-or-organization.md deleted file mode 100644 index e7dcf5c92f6..00000000000 --- a/docs/feature-management-experimentation/40-feature-management/best-practices/best-practices-when-targeting-an-account-or-organization.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Best practices when targeting an account or organization -sidebar_label: Best practices when targeting an account or organization -sidebar_position: 4 ---- - -import Link from "@docusaurus/Link"; - -Traffic types that target using a key for accounts or organizations (or schools or hospitals or...) as opposed to individual users are most often based on managing entitlements or for B2B applications. Of course, you can also target based on a department, plant, location or any level of granularity for which you have an associated key. We'll use 'account' as a proxy for all of the above. - -## Consistency of Experience - -When you want consistency of experience for all users within a single account, then use the account traffic type. This ensures that by providing a single ID - the account ID - you get the benefit of consistency without having to provide any complex data objects around users. - -If you want to measure the impact of a feature being rolled out by accounts through experimentation, avoid using SUM or COUNT metrics. As an example, say account A has 1,000 users but account B has two users. A metric that COUNTs or SUMs activity across these two accounts will be skewed in favor of the bigger account. Conversely, if you create metrics that measure AVERAGEs or PERCENTAGEs, data is normalized across accounts. - -As a B2B company, if you are OK with rolling out some of the features without the guarantee of consistency of experience for all users within a single account, then use a user traffic type. This also opens up a world of experimentation for you as you can measure SUM, COUNTs, AVERAGEs, PERCENTAGEs. - -Another option is to roll out a feature flag by user, but use company as a custom attribute to ensure everyone in specific (or all) companies get the same experience. This allows you to create a consistent experience within each organization, but still evaluate the results on a user by user basis. Of course, as noted above, you will not be able to control the distribution if some companies have far more users than others. More on that in [this article](/docs/feature-management-experimentation/feature-management/faqs/ensure-a-consistent-user-experience). - -These are tradeoffs that individual teams can make. You can roll out some features by accounts and others by users and Split allows you manage the experiences for each. \ No newline at end of file diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/csv-file-comma.md b/docs/feature-management-experimentation/40-feature-management/best-practices/csv-file-comma.md deleted file mode 100644 index ad72fede326..00000000000 --- a/docs/feature-management-experimentation/40-feature-management/best-practices/csv-file-comma.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: How to upload CSV file that contains IDs with comma character to new segment? -sidebar_label: How to upload CSV file that contains IDs with comma character to new segment? -sidebar_position: 1 ---- - -### Question - -Using the CSV upload feature in segment page in Split user interface, is it possible to upload user IDs in the CSV file that contain comma? The standard escape for CSV comma values is encapsulating the column value with double quotes like the example below: -``` -"user1, key1" -"user2, key2" -"user3, key3" -``` - -### Answer - -The CSV upload functionality in Split user interface automatically considers each line as a unique user id, so there is no need to add the double quotes, as they are added to the final user IDs that are imported to a Split segment. To use the example above, remove the double quotes, as below: -``` -user1, key1 -user2, key2 -user3, key3 -``` \ No newline at end of file diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/o-reilly-book.md b/docs/feature-management-experimentation/40-feature-management/best-practices/o-reilly-book.md deleted file mode 100644 index 4f996eef7b5..00000000000 --- a/docs/feature-management-experimentation/40-feature-management/best-practices/o-reilly-book.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: "O'Reilly book: Feature Flag Best Practices" -sidebar_label: "O'Reilly book: Feature Flag Best Practices" -sidebar_position: 2 ---- - -import Link from "@docusaurus/Link"; - -In [this book](https://try.split.io/hubfs/pdfs/oreilly-feature-flag-best-practices/OReilly_and_Split_Feature_Flag_Best_Practices.pdf), Split CTO Pato Echague and Pete Hodgson explain how to implement feature-flagged software successfully, and offer some tips to developers on how to configure and manage a growing set of feature flags within your product, maintain them over time, manage infrastructure migrations, and more. \ No newline at end of file diff --git a/docs/feature-management-experimentation/40-feature-management/best-practices/split-boxes-demo.md b/docs/feature-management-experimentation/40-feature-management/best-practices/split-boxes-demo.md deleted file mode 100644 index fa90e41153c..00000000000 --- a/docs/feature-management-experimentation/40-feature-management/best-practices/split-boxes-demo.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Split Boxes Demo -sidebar_label: Split Boxes Demo -helpdocs_is_private: false -helpdocs_is_published: true -sidebar_position: 5 ---- - -import Link from "@docusaurus/Link"; - -The Split Boxes demo is a tool to help users understand the interaction between rules and the impact of various features. It's a simple visualization that allows you to see the impact of individually targeting, custom attribution, limit exposure, and dynamic configuration. - -## Using the Boxes Demo - -Each box represents a user ID. - -![](./static/split-boxes-demo.png) - -You can individually target using the cell location, such as b8 or j5. You can also create a segment that includes any of the available values. - -You can create targeting rules using the attributes row, col, or account; row and col will use letters and numbers respectively, usually with 'is in list' as the matcher. Valid account names include Nike, Apple, LinkedIn, Best Buy, Google, Microsoft, Pinterest, Dell, Slack, Zoom, Samsung and Disney. - -You can modify the configuration of the treatments by updating any of the values. The font_size expects standard HTML sizes, such as medium, large, x-large, etc. - -## Setting up the Boxes Demo - -There are three files attached. The HTML contains the SDK and can be run locally or on a server. You need to provide the browser API key for whichever Split environment in which you will be updating the rollout plan. You also need to provide the name of the feature flag. These are entered as vars in the HTML. - -```html -