New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: correctly count metrics when a flag with dependencies has disabled parents #304
Changes from all commits
4a6f2ce
576216f
fb3db22
2f4a2ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -364,9 +364,15 @@ def is_enabled( | |
if self.unleash_bootstrapped or self.is_initialized: | ||
try: | ||
feature = self.features[feature_name] | ||
feature_check = feature.is_enabled( | ||
context | ||
) and self._dependencies_are_satisfied(feature_name, context) | ||
dependency_check = self._dependencies_are_satisfied( | ||
feature_name, context | ||
) | ||
|
||
if dependency_check: | ||
feature_check = feature.is_enabled(context) | ||
else: | ||
feature.increment_stats(False) | ||
feature_check = False | ||
|
||
if feature.only_for_metrics: | ||
return self._get_fallback_value( | ||
|
@@ -449,6 +455,8 @@ def get_variant(self, feature_name: str, context: Optional[dict] = None) -> dict | |
feature = self.features[feature_name] | ||
|
||
if not self._dependencies_are_satisfied(feature_name, context): | ||
feature.increment_stats(False) | ||
feature._count_variant("disabled") | ||
Comment on lines
+458
to
+459
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We never counted stats for variants at all if dependencies were not satisfied. |
||
return DISABLED_VARIATION | ||
|
||
variant_check = feature.get_variant(context) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -572,6 +572,7 @@ def test_uc_doesnt_count_metrics_for_dependency_parents(unleash_client): | |
time.sleep(1) | ||
|
||
child = "ChildWithVariant" | ||
parent = "Parent" | ||
thomasheartman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# Check a flag that depends on a parent | ||
unleash_client.is_enabled(child) | ||
unleash_client.get_variant(child) | ||
|
@@ -581,7 +582,37 @@ def test_uc_doesnt_count_metrics_for_dependency_parents(unleash_client): | |
request = json.loads(responses.calls[-1].request.body) | ||
assert request["bucket"]["toggles"][child]["yes"] == 2 | ||
assert request["bucket"]["toggles"][child]["variants"]["childVariant"] == 1 | ||
assert "Parent" not in request["bucket"]["toggles"] | ||
assert parent not in request["bucket"]["toggles"] | ||
|
||
|
||
@responses.activate | ||
def test_uc_counts_metrics_for_child_even_if_parent_is_disabled(unleash_client): | ||
# Set up API | ||
responses.add(responses.POST, URL + REGISTER_URL, json={}, status=202) | ||
responses.add( | ||
responses.GET, | ||
URL + FEATURES_URL, | ||
json=MOCK_FEATURE_WITH_DEPENDENCIES_RESPONSE, | ||
status=200, | ||
) | ||
responses.add(responses.POST, URL + METRICS_URL, json={}, status=202) | ||
|
||
# Create Unleash client and check initial load | ||
unleash_client.initialize_client() | ||
time.sleep(1) | ||
|
||
child = "WithDisabledDependency" | ||
parent = "Disabled" | ||
# Check a flag that depends on a disabled parent | ||
unleash_client.is_enabled(child) | ||
unleash_client.get_variant(child) | ||
|
||
# Verify that the parent doesn't have any metrics registered | ||
time.sleep(12) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is my only objection here. These tests are very painful to run since they all trigger long sleeps. This one adds a full 13 seconds The client is being newed up with a 10 second metrics send interval. Can we see what happens to the test suite if we reduce that to 1 and trim the sleep down to say 2 seconds? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, sure. I'll have a look. Think I might have had a look before, but can't remember why I didn't follow through in that case. Will check. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, there's a suggestion in 1abe74e. It worked when I last ran it locally, but I'm suspecting it might be a little flaky. Not sure that's a cost we wanna pay. Have a look. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And of course, we can move it out into a separate PR too. But just wanted some input on it first. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think I have too and failed to improve this a few times. Looks like the build server hates that change. I think these are accidentally doing more than just pausing execution. Okay, let's not do that then, this looks to be bigger than just this PR, I just to make sure it wasn't an easy fix we weren't doing. Let's remove the commit, I'm okay for this to go in without the timing change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Summary of in-person chat: I think I have a way to fix this. Will take those changes into a new PR (#305 tentatively) |
||
request = json.loads(responses.calls[-1].request.body) | ||
assert request["bucket"]["toggles"][child]["no"] == 2 | ||
assert request["bucket"]["toggles"][child]["variants"]["disabled"] == 1 | ||
assert parent not in request["bucket"]["toggles"] | ||
|
||
|
||
@responses.activate | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the flag is enabled itself, but its dependencies are not satisfied, we'd count it as a "yes" previously (by checking "is_enabled" first.