feat: add get_experiment_groups() to expose group names and return values#54
Open
cam-matsui wants to merge 2 commits into
Open
feat: add get_experiment_groups() to expose group names and return values#54cam-matsui wants to merge 2 commits into
get_experiment_groups() to expose group names and return values#54cam-matsui wants to merge 2 commits into
Conversation
…lues Adds a new public get_experiment_groups method that returns the group name and return value for each group in a given experiment, without requiring a user evaluation. Implemented in the Rust core and exposed across all language bindings (Node, Python, Java, PHP, Go, .NET, Elixir) plus the C/C++ FFI. Behavior mirrors statsig-io/python-sdk#36: - Returns [] if the experiment does not exist or the name refers to a dynamic config (entity != "experiment"). - Returns [] for inactive experiments (isActive != true). - Excludes rules that are not experiment groups (isExperimentGroup != true), e.g. holdout/sizing rules.
Addresses review feedback: - C++: expose getExperimentGroups in the hand-written wrapper (statsig.h/.cpp) with an ExperimentGroup type and from_json/to_json, plus a hermetic serialization test. Previously only the generated FFI header was updated. - Elixir: add a dedicated test that serves eval_proj_dcs.json over a local mock server and exercises the public Statsig.get_experiment_groups/1 wrapper, including the happy path (Control/Test/Test2). Removes the redundant no-specs NIF test. - Docs: clarify across Rust, Elixir, Go, PHP, .NET, and Java that the method returns an empty list for inactive experiments (and unknown names / dynamic configs) by design.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why?
When building generic experimentation into a "platform", one must be cautious in deciding if and when to log exposures to avoid dilution. For example:
We have a rules engine and we want to generically provide the ability to experiment between 2 rules that evaluate whether a user gets an email. We might set up an experiment like:
rule_id=Arule_id=BOne option is just to call
get_experiment(user)and evaluate the rule with the returned ID. However, if rule A and rule B both return the same result (e.g.,false) for some subset of users, we will dilute our experiment by exposing those users into the experiment even though none of those users would receive the email either way.In most cases, we should instead evaluate both rules for all users in the experiment, and only log exposure if the results (and therefore the user experience) differ for rule A and B. In these kinds of scenarios, we need access to configurations for all experiment groups.
Because we have all of this data available in memory anyway, we are extending the interface to avoid reaching into SDK internals or making redundant HTTP requests to the console API.
This ports statsig-io/python-sdk#36 to server-core so the same capability is available as customers migrate from the legacy Python SDK to the core SDK.
Summary
Adds a new public
get_experiment_groupsfunction that returns the group name and return value for each group in a given experiment, without requiring a user evaluation. Implemented once in the Rust core and exposed across every binding.New API
Each entry has
group_nameandreturn_value. Equivalent methods are exposed in every binding (camelCase / language-idiomatic naming):statsig.get_experiment_groups("my_experiment")statsig.getExperimentGroups("my_experiment")statsig.get_experiment_groups("my_experiment")statsig.getExperimentGroups("my_experiment")$statsig->getExperimentGroups("my_experiment")statsig.GetExperimentGroups("my_experiment")statsig.GetExperimentGroups("my_experiment")Statsig.get_experiment_groups("my_experiment")Behavior
isActive != true).isExperimentGroup != true), e.g. holdout / sizing rules.Changes
statsig-rust): newExperimentGrouptype andStatsig::get_experiment_groups, using the existing spec-store read-lock pattern. No user evaluation, no exposures.statsig_get_experiment_groupsC export drives the FFI-based bindings; generated headers/bindings (statsig_ffi.h,libstatsig_ffi.h,StatsigFFI.g.cs) and the pyo3 stub (.pyi) and Node type defs (.d.ts) are regenerated.statsig-rust/tests/data/eval_proj_dcs.jsonand asserting againsttest_experiment_no_targeting), covering the happy path plus the empty-list cases (unknown experiment, dynamic config, inactive experiment).