Skip to content

Commit 02ae306

Browse files
authored
feat(on-demand): Add feature flag check before cardinality check (#98726)
Some users are experiencing high latency due to this cardinality check. Since metrics extraction for widgets has paused and we're in the process of migrating users to spans/EAP, I figured we could avoid running this check for users that do not have the feature flag if we're not planning to continue rolling it out.
1 parent d18137b commit 02ae306

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

src/sentry/tasks/on_demand_metrics.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from celery.exceptions import SoftTimeLimitExceeded
99
from django.utils import timezone
1010

11-
from sentry import options
11+
from sentry import features, options
1212
from sentry.models.dashboard_widget import (
1313
DashboardWidgetQuery,
1414
DashboardWidgetQueryOnDemand,
@@ -423,6 +423,9 @@ def check_field_cardinality(
423423
is_task: bool = False,
424424
widget_query: DashboardWidgetQuery | None = None,
425425
) -> dict[str, str]:
426+
if not features.has("organizations:on-demand-metrics-extraction-widgets", organization):
427+
return {}
428+
426429
if not query_columns:
427430
return {}
428431
if is_task:

tests/sentry/dashboards/endpoints/test_organization_dashboard_details.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3121,7 +3121,7 @@ def test_ondemand_updates_new_widget(self, mock_query: mock.MagicMock) -> None:
31213121
assert current_version.extraction_state == "enabled:creation"
31223122

31233123
@mock.patch("sentry.tasks.on_demand_metrics._query_cardinality")
3124-
def test_cardinality_precedence_over_feature_checks(self, mock_query: mock.MagicMock) -> None:
3124+
def test_cardinality_check_with_feature_flag(self, mock_query: mock.MagicMock) -> None:
31253125
mock_query.return_value = {"data": [{"count_unique(sometag)": 1_000_000}]}, [
31263126
"sometag",
31273127
]
@@ -3145,7 +3145,9 @@ def test_cardinality_precedence_over_feature_checks(self, mock_query: mock.Magic
31453145
},
31463146
],
31473147
}
3148-
response = self.do_request("put", self.url(self.dashboard.id), data=data)
3148+
3149+
with self.feature(["organizations:on-demand-metrics-extraction-widgets"]):
3150+
response = self.do_request("put", self.url(self.dashboard.id), data=data)
31493151
assert response.status_code == 200, response.data
31503152
widgets = self.get_widgets(self.dashboard.id)
31513153
assert len(widgets) == 1
@@ -3160,6 +3162,48 @@ def test_cardinality_precedence_over_feature_checks(self, mock_query: mock.Magic
31603162
assert current_version is not None
31613163
assert current_version.extraction_state == "disabled:high-cardinality"
31623164

3165+
@mock.patch("sentry.tasks.on_demand_metrics._query_cardinality")
3166+
def test_feature_check_takes_precedence_over_cardinality(
3167+
self, mock_query: mock.MagicMock
3168+
) -> None:
3169+
mock_query.return_value = {"data": [{"count_unique(sometag)": 1_000_000}]}, [
3170+
"sometag",
3171+
]
3172+
data: dict[str, Any] = {
3173+
"title": "first dashboard",
3174+
"widgets": [
3175+
{
3176+
"title": "errors per project",
3177+
"displayType": "table",
3178+
"interval": "5m",
3179+
"widgetType": DashboardWidgetTypes.get_type_name(self.widget_type),
3180+
"queries": [
3181+
{
3182+
"name": "errors",
3183+
"fields": ["count()", "sometag"],
3184+
"columns": ["sometag"],
3185+
"aggregates": ["count()"],
3186+
"conditions": "event.type:transaction",
3187+
}
3188+
],
3189+
},
3190+
],
3191+
}
3192+
response = self.do_request("put", self.url(self.dashboard.id), data=data)
3193+
assert response.status_code == 200, response.data
3194+
widgets = self.get_widgets(self.dashboard.id)
3195+
assert len(widgets) == 1
3196+
last = list(widgets).pop()
3197+
queries = last.dashboardwidgetquery_set.all()
3198+
3199+
ondemand_objects = DashboardWidgetQueryOnDemand.objects.filter(
3200+
dashboard_widget_query=queries[0]
3201+
)
3202+
for version in OnDemandMetricSpecVersioning.get_spec_versions():
3203+
current_version = ondemand_objects.filter(spec_version=version.version).first()
3204+
assert current_version is not None
3205+
assert current_version.extraction_state == "disabled:pre-rollout"
3206+
31633207
@mock.patch("sentry.api.serializers.rest_framework.dashboard.get_current_widget_specs")
31643208
def test_cardinality_skips_non_discover_widget_types(
31653209
self, mock_get_specs: mock.MagicMock

0 commit comments

Comments
 (0)