Skip to content

Commit ca65865

Browse files
committed
perf(aci): Load slow conditions for all DataConditionGroups at once
1 parent dcaf2e9 commit ca65865

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

src/sentry/workflow_engine/models/data_condition_group.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections.abc import Mapping
12
from enum import StrEnum
23
from typing import ClassVar, Self
34

@@ -40,6 +41,21 @@ class Type(StrEnum):
4041
organization = models.ForeignKey("sentry.Organization", on_delete=models.CASCADE)
4142

4243

44+
def batch_get_slow_conditions(dcgs: list[DataConditionGroup]) -> Mapping[int, list[DataCondition]]:
45+
"""
46+
Get all slow conditions for a list of data condition groups.
47+
"""
48+
dcg_ids = [dcg.id for dcg in dcgs]
49+
conditions = DataCondition.objects.filter(
50+
condition_group__in=dcg_ids,
51+
)
52+
slow_conditions_by_dcg = {dcg.id: [] for dcg in dcgs}
53+
for condition in conditions:
54+
if is_slow_condition(condition):
55+
slow_conditions_by_dcg[condition.condition_group_id].append(condition)
56+
return slow_conditions_by_dcg
57+
58+
4359
def get_slow_conditions(dcg: DataConditionGroup) -> list[DataCondition]:
4460
"""
4561
Get all conditions that are considered slow for a given data condition group

src/sentry/workflow_engine/processors/delayed_workflow.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
SLOW_CONDITIONS,
4545
Condition,
4646
)
47-
from sentry.workflow_engine.models.data_condition_group import get_slow_conditions
47+
from sentry.workflow_engine.models.data_condition_group import batch_get_slow_conditions
4848
from sentry.workflow_engine.processors.action import filter_recently_fired_workflow_actions
4949
from sentry.workflow_engine.processors.data_condition_group import evaluate_data_conditions
5050
from sentry.workflow_engine.processors.detector import get_detector_by_event
@@ -224,9 +224,9 @@ def get_condition_query_groups(
224224
Map unique condition queries to the group IDs that need to checked for that query.
225225
"""
226226
condition_groups: dict[UniqueConditionQuery, set[int]] = defaultdict(set)
227+
slow_conditions_by_dcg = batch_get_slow_conditions(data_condition_groups)
227228
for dcg in data_condition_groups:
228-
slow_conditions = get_slow_conditions(dcg)
229-
for condition in slow_conditions:
229+
for condition in slow_conditions_by_dcg[dcg.id]:
230230
workflow_id = dcg_to_workflow.get(dcg.id)
231231
workflow_env = workflows_to_envs[workflow_id] if workflow_id else None
232232
for condition_query in generate_unique_queries(condition, workflow_env):
@@ -273,8 +273,9 @@ def get_groups_to_fire(
273273
condition_group_results: dict[UniqueConditionQuery, QueryResult],
274274
) -> dict[int, set[DataConditionGroup]]:
275275
groups_to_fire: dict[int, set[DataConditionGroup]] = defaultdict(set)
276+
slow_conditions_by_dcg = batch_get_slow_conditions(data_condition_groups)
276277
for dcg in data_condition_groups:
277-
slow_conditions = get_slow_conditions(dcg)
278+
slow_conditions = slow_conditions_by_dcg[dcg.id]
278279
action_match = DataConditionGroup.Type(dcg.logic_type)
279280
workflow_id = dcg_to_workflow.get(dcg.id)
280281
workflow_env = workflows_to_envs[workflow_id] if workflow_id else None
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from sentry.testutils.cases import TestCase
2+
from sentry.workflow_engine.models.data_condition import Condition, DataCondition
3+
from sentry.workflow_engine.models.data_condition_group import (
4+
DataConditionGroup,
5+
batch_get_slow_conditions,
6+
)
7+
8+
9+
class TestBatchGetSlowConditions(TestCase):
10+
def setUp(self):
11+
super().setUp()
12+
self.dcg = self.create_data_condition_group()
13+
14+
def create_slow_condition(self, condition_group: DataConditionGroup) -> DataCondition:
15+
return self.create_data_condition(
16+
condition_group=condition_group,
17+
type=Condition.EVENT_FREQUENCY_COUNT,
18+
comparison={
19+
"interval": "1d",
20+
"value": 7,
21+
},
22+
)
23+
24+
def test_batch_get_slow_conditions(self):
25+
condition = self.create_slow_condition(self.dcg)
26+
assert batch_get_slow_conditions([self.dcg]) == {self.dcg.id: [condition]}
27+
28+
def test_batch_get_slow_conditions__no_slow_conditions(self):
29+
self.create_data_condition(condition_group=self.dcg, type=Condition.EQUAL)
30+
assert batch_get_slow_conditions([self.dcg]) == {self.dcg.id: []}
31+
32+
def test_multiple_dcgs(self):
33+
dcg2 = self.create_data_condition_group()
34+
condition1 = self.create_slow_condition(self.dcg)
35+
condition2 = self.create_slow_condition(dcg2)
36+
self.create_data_condition(condition_group=self.dcg, type=Condition.EQUAL)
37+
condition4 = self.create_slow_condition(dcg2)
38+
assert batch_get_slow_conditions([self.dcg, dcg2]) == {
39+
self.dcg.id: [condition1],
40+
dcg2.id: [condition2, condition4],
41+
}

0 commit comments

Comments
 (0)