Skip to content

Commit

Permalink
chore(flags): stop checking clickhouse for feature flag status endpoi…
Browse files Browse the repository at this point in the history
…nt (#26951)

Co-authored-by: Dylan Martin <[email protected]>
  • Loading branch information
havenbarnes and dmarticus authored Dec 16, 2024
1 parent eaf9de7 commit d149515
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 62 deletions.
70 changes: 12 additions & 58 deletions posthog/api/test/test_feature_flag.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import json
from typing import Optional
from unittest.mock import call, patch
from dateutil.relativedelta import relativedelta

from django.core.cache import cache
from django.db import connection
Expand Down Expand Up @@ -41,7 +40,6 @@
ClickhouseTestMixin,
FuzzyInt,
QueryMatchingTest,
_create_event,
_create_person,
flush_persons_and_events,
snapshot_clickhouse_queries,
Expand Down Expand Up @@ -6130,18 +6128,6 @@ def assert_expected_response(
if expected_reason is not None:
self.assertEqual(response_data.get("reason"), expected_reason)

def create_feature_flag_called_event(
self, feature_flag_key: str, response: Optional[bool] = True, datetime: Optional[datetime.datetime] = None
):
timestamp = datetime or now() - relativedelta(hours=12)
_create_event(
event="$feature_flag_called",
distinct_id="person1",
properties={"$feature_flag": feature_flag_key, "$feature_flag_response": response},
team=self.team,
timestamp=timestamp,
)

def test_flag_status_reasons(self):
FeatureFlag.objects.all().delete()

Expand All @@ -6165,7 +6151,7 @@ def test_flag_status_reasons(self):
team=self.team,
active=False,
)
self.create_feature_flag_called_event(disabled_flag.key)

self.assert_expected_response(disabled_flag.id, FeatureFlagStatus.ACTIVE)

# Request status for flag that has super group rolled out to <100%
Expand All @@ -6176,7 +6162,7 @@ def test_flag_status_reasons(self):
active=True,
filters={"super_groups": [{"rollout_percentage": 50, "properties": []}]},
)
self.create_feature_flag_called_event(fifty_percent_super_group_flag.key)

self.assert_expected_response(fifty_percent_super_group_flag.id, FeatureFlagStatus.ACTIVE)

# Request status for flag that has super group rolled out to 100% and specific properties
Expand All @@ -6201,7 +6187,7 @@ def test_flag_status_reasons(self):
]
},
)
self.create_feature_flag_called_event(fully_rolled_out_super_group_flag_with_properties.key)

self.assert_expected_response(fully_rolled_out_super_group_flag_with_properties.id, FeatureFlagStatus.ACTIVE)

# Request status for flag that has super group rolled out to 100% and has no specific properties
Expand Down Expand Up @@ -6231,7 +6217,7 @@ def test_flag_status_reasons(self):
active=True,
filters={"holdout_groups": [{"rollout_percentage": 50, "properties": []}]},
)
self.create_feature_flag_called_event(fifty_percent_holdout_group_flag.key)

self.assert_expected_response(fifty_percent_holdout_group_flag.id, FeatureFlagStatus.ACTIVE)

# Request status for flag that has holdout group rolled out to 100% and specific properties
Expand All @@ -6256,7 +6242,7 @@ def test_flag_status_reasons(self):
]
},
)
self.create_feature_flag_called_event(fully_rolled_out_holdout_group_flag_with_properties.key)

self.assert_expected_response(fully_rolled_out_holdout_group_flag_with_properties.id, FeatureFlagStatus.ACTIVE)

# Request status for flag that has holdout group rolled out to 100% and has no specific properties
Expand Down Expand Up @@ -6293,7 +6279,7 @@ def test_flag_status_reasons(self):
}
},
)
self.create_feature_flag_called_event(multivariate_flag_no_rolled_out_variants.key)

self.assert_expected_response(multivariate_flag_no_rolled_out_variants.id, FeatureFlagStatus.ACTIVE)

# Request status for multivariate flag with no variants set to 100%
Expand Down Expand Up @@ -6337,7 +6323,7 @@ def test_flag_status_reasons(self):
],
},
)
self.create_feature_flag_called_event(multivariate_flag_rolled_out_variant_no_rolled_out_release.key)

self.assert_expected_response(
multivariate_flag_rolled_out_variant_no_rolled_out_release.id,
FeatureFlagStatus.ACTIVE,
Expand All @@ -6361,7 +6347,7 @@ def test_flag_status_reasons(self):
],
},
)
self.create_feature_flag_called_event(multivariate_flag_rolled_out_release_condition_half_variant.key)

self.assert_expected_response(
multivariate_flag_rolled_out_release_condition_half_variant.id,
FeatureFlagStatus.ACTIVE,
Expand Down Expand Up @@ -6396,7 +6382,7 @@ def test_flag_status_reasons(self):
],
},
)
self.create_feature_flag_called_event(multivariate_flag_rolled_out_variant_rolled_out_filtered_release.key)

self.assert_expected_response(
multivariate_flag_rolled_out_variant_rolled_out_filtered_release.id,
FeatureFlagStatus.ACTIVE,
Expand Down Expand Up @@ -6431,7 +6417,7 @@ def test_flag_status_reasons(self):
],
},
)
self.create_feature_flag_called_event(multivariate_flag_filtered_rolled_out_release_with_override.key)

self.assert_expected_response(
multivariate_flag_filtered_rolled_out_release_with_override.id,
FeatureFlagStatus.ACTIVE,
Expand Down Expand Up @@ -6509,7 +6495,7 @@ def test_flag_status_reasons(self):
],
},
)
self.create_feature_flag_called_event(boolean_flag_no_rolled_out_release_conditions.key)

self.assert_expected_response(
boolean_flag_no_rolled_out_release_conditions.id,
FeatureFlagStatus.ACTIVE,
Expand Down Expand Up @@ -6570,39 +6556,7 @@ def test_flag_status_reasons(self):
],
},
)
self.create_feature_flag_called_event(boolean_flag_no_rolled_out_release_condition_recently_evaluated.key)
self.assert_expected_response(
boolean_flag_no_rolled_out_release_condition_recently_evaluated.id, FeatureFlagStatus.ACTIVE
)

# Request status for a boolean flag with no rolled out release conditions, and has
# been called, but not recently
boolean_flag_rolled_out_release_condition_not_recently_evaluated = FeatureFlag.objects.create(
name="Boolean flag with a release condition set to 100%",
key="boolean-not-recently-evaluated-flag",
team=self.team,
active=True,
filters={
"groups": [
{
"properties": [
{
"key": "name",
"type": "person",
"value": ["Smith"],
"operator": "contains",
}
],
"rollout_percentage": 50,
},
],
},
)
self.create_feature_flag_called_event(
boolean_flag_rolled_out_release_condition_not_recently_evaluated.key, True, now() - relativedelta(days=31)
)
self.assert_expected_response(
boolean_flag_rolled_out_release_condition_not_recently_evaluated.id,
FeatureFlagStatus.INACTIVE,
"Flag has not been evaluated recently",
boolean_flag_no_rolled_out_release_condition_recently_evaluated.id, FeatureFlagStatus.ACTIVE
)
5 changes: 1 addition & 4 deletions posthog/models/feature_flag/flag_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class FeatureFlagStatus(StrEnum):
# - ACTIVE: The feature flag is actively evaluated and the evaluations continue to vary.
# - STALE: The feature flag has been fully rolled out to users. Its evaluations can not vary.
# - INACTIVE: The feature flag is not being actively evaluated. STALE takes precedence over INACTIVE.
# NOTE: The "inactive" status is not currently used, but may be used in the future to automatically archive flags.
# - DELETED: The feature flag has been soft deleted.
# - UNKNOWN: The feature flag is not found in the database.
class FeatureFlagStatusChecker:
Expand All @@ -49,10 +50,6 @@ def get_status(self) -> tuple[FeatureFlagStatus, FeatureFlagStatusReason]:
if is_flag_fully_rolled_out:
return FeatureFlagStatus.STALE, fully_rolled_out_explanation

# Final, and most expensive check: see if the flag has been evaluated recently.
if self.is_flag_unevaluated_recently(flag):
return FeatureFlagStatus.INACTIVE, "Flag has not been evaluated recently"

return FeatureFlagStatus.ACTIVE, "Flag is not fully rolled out and may still be active"

def is_flag_fully_rolled_out(self, flag: FeatureFlag) -> tuple[bool, FeatureFlagStatusReason]:
Expand Down

0 comments on commit d149515

Please sign in to comment.