Skip to content

Commit

Permalink
Filter Segment Exposures (#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
sroyal-statsig authored Jun 6, 2024
1 parent 74b0d36 commit aa73690
Showing 1 changed file with 25 additions and 19 deletions.
44 changes: 25 additions & 19 deletions dotnet-statsig/src/Statsig/Server/Evaluation/Evaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ internal List<string> GetSpecNames(string type)
["name"] = hashedName,
["value"] = gate.Value,
["rule_id"] = gate.RuleID,
["secondary_exposures"] = CleanExposures(gate.SecondaryExposures),
["secondary_exposures"] = CleanExposures(gate.SecondaryExposures).ToArray(),
};
gates.Add(hashedName, entry);
}
Expand Down Expand Up @@ -291,7 +291,7 @@ internal List<string> GetSpecNames(string type)
}

entry["undelegated_secondary_exposures"] =
CleanExposures(evaluation.UndelegatedSecondaryExposures);
CleanExposures(evaluation.UndelegatedSecondaryExposures).ToArray();
layerConfigs.Add(hashedName, entry);
}

Expand Down Expand Up @@ -343,8 +343,8 @@ private ConfigEvaluation EvaluateSpec(StatsigUser user, string specName, SpecTyp
return Evaluate(user, lookup[name], 0);
}

private IEnumerable<IReadOnlyDictionary<string, string>> CleanExposures(
IEnumerable<IReadOnlyDictionary<string, string>> exposures
private List<IReadOnlyDictionary<string, string>> CleanExposures(
List<IReadOnlyDictionary<string, string>> exposures
)
{
if (exposures == null)
Expand All @@ -356,6 +356,10 @@ IEnumerable<IReadOnlyDictionary<string, string>> exposures
return exposures.Select((exp) =>
{
var gate = exp["gate"];
if (gate.StartsWith("segment:"))
{
return null;
}
var gateValue = exp["gateValue"];
var ruleID = exp["ruleID"];
var key = $"{gate}|{gateValue}|{ruleID}";
Expand All @@ -366,7 +370,7 @@ IEnumerable<IReadOnlyDictionary<string, string>> exposures

seen.Add(key);
return exp;
}).Where(exp => exp != null).Select(exp => exp!).ToArray();
}).Where(exp => exp != null).Select(exp => exp!).ToList();
}

private bool IsUserAllocatedToExperiment(
Expand Down Expand Up @@ -398,7 +402,7 @@ DynamicConfig config
["group"] = config.RuleID,
["is_device_based"] = (spec.IDType != null &&
spec.IDType.ToLowerInvariant() == "stableid"),
["secondary_exposures"] = CleanExposures(config.SecondaryExposures),
["secondary_exposures"] = CleanExposures(config.SecondaryExposures).ToArray(),
};

return entry;
Expand Down Expand Up @@ -438,7 +442,7 @@ private string HashName(string? name = "", string? hashAlgo = "sha256")
UndelegatedSecondaryExposures = exposures
};
result.ConfigValue.SecondaryExposures =
exposures.Concat(delegatedResult.ConfigValue.SecondaryExposures).ToList();
CleanExposures(exposures.Concat(delegatedResult.ConfigValue.SecondaryExposures).ToList());
result.ConfigDelegate = rule.ConfigDelegate;
return result;
}
Expand Down Expand Up @@ -485,7 +489,7 @@ private ConfigEvaluation Evaluate(StatsigUser user, ConfigSpec spec, int depth)
spec.Name,
passPercentage ? rule.FeatureGateValue.Value : spec.FeatureGateDefault.Value,
rule.ID,
secondaryExposures,
CleanExposures(secondaryExposures),
_store.EvalReason
);
var configV = new DynamicConfig
Expand All @@ -494,7 +498,7 @@ private ConfigEvaluation Evaluate(StatsigUser user, ConfigSpec spec, int depth)
passPercentage ? rule.DynamicConfigValue.Value : spec.DynamicConfigDefault.Value,
rule.ID,
rule.GroupName,
secondaryExposures,
CleanExposures(secondaryExposures),
spec.ExplicitParameters,
spec.HasSharedParams,
IsUserAllocatedToExperiment(user, spec, rule.ID)
Expand All @@ -511,8 +515,8 @@ private ConfigEvaluation Evaluate(StatsigUser user, ConfigSpec spec, int depth)
(
EvaluationResult.Fail,
_store.EvalReason,
new FeatureGate(spec.Name, spec.FeatureGateDefault.Value, "default", secondaryExposures),
new DynamicConfig(spec.Name, spec.DynamicConfigDefault.Value, "default", null, secondaryExposures,
new FeatureGate(spec.Name, spec.FeatureGateDefault.Value, "default", CleanExposures(secondaryExposures)),
new DynamicConfig(spec.Name, spec.DynamicConfigDefault.Value, "default", null, CleanExposures(secondaryExposures),
spec.ExplicitParameters)
);
}
Expand Down Expand Up @@ -619,15 +623,17 @@ private EvaluationResult EvaluateCondition(StatsigUser user, ConfigCondition con
}

var pass = otherGateResult.Result == EvaluationResult.Pass;
var newExposure = new Dictionary<string, string>
secondaryExposures = new List<IReadOnlyDictionary<string, string>>(otherGateResult.GateValue.SecondaryExposures);
if (!targetStr.StartsWith("segment:"))
{
["gate"] = targetStr,
["gateValue"] = pass ? "true" : "false",
["ruleID"] = otherGateResult.GateValue.RuleID
};
secondaryExposures =
new List<IReadOnlyDictionary<string, string>>(otherGateResult.GateValue.SecondaryExposures);
secondaryExposures.Add(newExposure);
var newExposure = new Dictionary<string, string>
{
["gate"] = targetStr,
["gateValue"] = pass ? "true" : "false",
["ruleID"] = otherGateResult.GateValue.RuleID
};
secondaryExposures.Add(newExposure);
}
if ((type == "pass_gate" && pass) || (type == "fail_gate" && !pass))
{
return EvaluationResult.Pass;
Expand Down

0 comments on commit aa73690

Please sign in to comment.