Skip to content

Commit 1552390

Browse files
authored
fix(aci): ANY_SHORT_CIRCUIT early exit (#87114)
1 parent dc30bff commit 1552390

File tree

2 files changed

+59
-3
lines changed

2 files changed

+59
-3
lines changed

src/sentry/workflow_engine/processors/data_condition_group.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,13 @@ def process_data_condition_group(
126126
conditions_to_evaluate = [(condition, value) for condition in conditions]
127127
logic_result, condition_results = evaluate_data_conditions(conditions_to_evaluate, logic_type)
128128

129-
if (not logic_result and logic_type == DataConditionGroup.Type.ALL) or (
130-
logic_result and logic_type == DataConditionGroup.Type.ANY
131-
):
129+
is_short_circuit_all = not logic_result and logic_type == DataConditionGroup.Type.ALL
130+
is_short_circuit_any = logic_result and logic_type in (
131+
DataConditionGroup.Type.ANY,
132+
DataConditionGroup.Type.ANY_SHORT_CIRCUIT,
133+
)
134+
135+
if is_short_circuit_all or is_short_circuit_any:
132136
# if we have a logic type of all and a False result,
133137
# or if we have a logic type of any and a True result, then
134138
# we can short-circuit any remaining conditions since we have a completed logic result

tests/sentry/workflow_engine/processors/test_workflow.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,58 @@ def test_enqueues_workflow_any_logic_type(self):
343343
)
344344
assert project_ids[0][0] == self.project.id
345345

346+
def test_skips_enqueuing_any(self):
347+
# skips slow conditions if the condition group evaluates to True without evaluating them
348+
assert self.workflow.when_condition_group
349+
self.workflow.when_condition_group.update(
350+
logic_type=DataConditionGroup.Type.ANY_SHORT_CIRCUIT
351+
)
352+
353+
self.create_data_condition(
354+
condition_group=self.workflow.when_condition_group,
355+
type=Condition.EVENT_FREQUENCY_COUNT,
356+
comparison={
357+
"interval": "1h",
358+
"value": 100,
359+
},
360+
condition_result=True,
361+
)
362+
363+
triggered_workflows = evaluate_workflow_triggers({self.workflow}, self.job)
364+
assert triggered_workflows == {self.workflow}
365+
project_ids = buffer.backend.get_sorted_set(
366+
WORKFLOW_ENGINE_BUFFER_LIST_KEY, 0, self.buffer_timestamp
367+
)
368+
assert len(project_ids) == 0
369+
370+
def test_skips_enqueuing_all(self):
371+
assert self.workflow.when_condition_group
372+
self.workflow.when_condition_group.conditions.all().delete()
373+
self.workflow.when_condition_group.update(logic_type=DataConditionGroup.Type.ALL)
374+
375+
self.create_data_condition(
376+
condition_group=self.workflow.when_condition_group,
377+
type=Condition.EVENT_FREQUENCY_COUNT,
378+
comparison={
379+
"interval": "1h",
380+
"value": 100,
381+
},
382+
condition_result=True,
383+
)
384+
self.create_data_condition(
385+
condition_group=self.workflow.when_condition_group,
386+
type=Condition.REGRESSION_EVENT, # fast condition, does not pass
387+
comparison=True,
388+
condition_result=True,
389+
)
390+
391+
triggered_workflows = evaluate_workflow_triggers({self.workflow}, self.job)
392+
assert not triggered_workflows
393+
project_ids = buffer.backend.get_sorted_set(
394+
WORKFLOW_ENGINE_BUFFER_LIST_KEY, 0, self.buffer_timestamp
395+
)
396+
assert len(project_ids) == 0
397+
346398

347399
class TestEvaluateWorkflowActionFilters(BaseWorkflowTest):
348400
def setUp(self):

0 commit comments

Comments
 (0)