Skip to content

Conversation

@Datron
Copy link
Collaborator

@Datron Datron commented Nov 21, 2025

Problem

Internal juspay systems require more information from the provider to provide adequate debugging information

Solution

  • refactor resolution
  • expose get_satisfied_experiments
  • Add variants chosen to the Resolution Details so users can validate and debug

Future TODO

Have all s11n providers expose the same interface. This will be done in a future PR

@Datron Datron requested a review from a team as a code owner November 21, 2025 07:18
@semanticdiff-com
Copy link

semanticdiff-com bot commented Nov 21, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/superposition_provider/src/utils.rs  77% smaller
  crates/superposition_provider/src/provider.rs  26% smaller
  crates/superposition_provider/src/client.rs  0% smaller
  crates/superposition_provider/src/lib.rs  0% smaller

) -> Result<serde_json::Map<String, Value>> {
self.eval_config(evaluation_context).await
prefix_filters: Option<Vec<String>>,
) -> Result<(serde_json::Map<String, Value>, Vec<String>)> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we make a type for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Aliasing it for now

@Datron Datron force-pushed the expose-satisfied-experiments branch 3 times, most recently from 5fdfbca to 00fb43c Compare November 25, 2025 10:34
Copy link
Collaborator

@mahatoankitkumar mahatoankitkumar left a comment

Choose a reason for hiding this comment

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

TODO for the next PR.

  • Making a separate type instead of aliasing.
  • And expose these functions in other providers too.

.await
}

pub async fn get_running_experiments_from_provider(&self) -> Result<Experiments> {
Copy link
Collaborator

@knutties knutties Nov 28, 2025

Choose a reason for hiding this comment

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

Why call this get_running_experiments_from_provider while using the get_cached_experiments inside? 1-1 naming will be helpful here ?

@Datron Datron force-pushed the expose-satisfied-experiments branch 2 times, most recently from 34c16c4 to bf955aa Compare December 15, 2025 10:50
@Datron Datron force-pushed the expose-satisfied-experiments branch from bf955aa to 128469a Compare December 15, 2025 12:38
&self,
query_data: &serde_json::Map<String, Value>,
prefix_filter: Option<&[String]>,
prefix_filter: Option<Vec<String>>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

why not reference, if we dont need reference here then in line 233 of this file, we dont need the to_vec conversion anymore

);

let cac_config = CacConfig::new(superposition_options, config_options);
let cac_config = CacClient::new(superposition_options, config_options);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
let cac_config = CacClient::new(superposition_options, config_options);
let cac_client = CacClient::new(superposition_options, config_options);

));

let exp_config = ExperimentationConfig::new(superposition_options, exp_options);
let exp_config = ExperimentationClient::new(superposition_options, exp_options);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
let exp_config = ExperimentationClient::new(superposition_options, exp_options);
let exp_client = ExperimentationClient::new(superposition_options, exp_options);

)
}

pub async fn get_last_modified_time(&self) -> Result<DateTime<Utc>> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this function name says last modified, but it is returning last updated
they seem totally different and confusing though

flag_key: &str,
evaluation_context: &EvaluationContext,
converter: fn(&Value) -> EvaluationResult<T>,
) -> EvaluationResult<ResolutionDetails<T>> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

astonishing! open-feature already had such types

Comment on lines +235 to +247
if targeting_key.is_some() {
if let Some(exp_config) = &self.exp_client {
let applicable_variant_ids = exp_config
.get_applicable_variants(&dimensions_info, &context, targeting_key)
.await?;

context.insert(
"variantIds".to_string(),
Value::Array(variant_ids.into_iter().map(Value::String).collect()),
);

match &self.cac_config {
Some(cac_config) => cac_config.evaluate_config(&context, None).await,
None => Err(SuperpositionError::ConfigError(
"CAC config not initialized".into(),
)),
context.insert("variantIds".to_string(), json!(applicable_variant_ids));
variant_ids = applicable_variant_ids;
} else {
log::warn!("Targeting key is set, but experiments have not been defined in the superposition provider builder options")
}
}
let Some(ref client) = self.cac_client else {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this section feels wrong, ideally shouldn't this have been separate and not part of eval_config, rather passed in to this
or maybe having this in here is still fine but not returned from every resolve operation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants