11import logging
22from collections .abc import Sequence
3+ from contextlib import contextmanager
34from copy import deepcopy
45from datetime import UTC , datetime
56
6- from django .db import connections , router , transaction
7+ from django .db import connections , router
78from django .db .models import (
89 Case ,
910 DateTimeField ,
113114
114115logger = logging .getLogger (__name__ )
115116
117+
118+ @contextmanager
119+ def _postgres_jit_disabled (using : str ):
120+ """
121+ Disable PostgreSQL JIT compilation on the given database connection for the duration of
122+ the block.
123+
124+ Uses session-level SET/RESET rather than SET LOCAL (which requires a transaction) so that
125+ callers don't need to open a transaction — important when the calling code may issue queries
126+ against multiple databases.
127+ """
128+ with connections [using ].cursor () as cursor :
129+ cursor .execute ("SET jit = off" )
130+ try :
131+ yield
132+ finally :
133+ with connections [using ].cursor () as cursor :
134+ cursor .execute ("RESET jit" )
135+
136+
116137# Sentinel values for incident_status annotation when sorting combined rules
117138# Used to ensure proper sort order for rules without active incidents
118139INCIDENT_STATUS_NONE = - 1 # Metric alerts with no active incident
@@ -519,7 +540,7 @@ def _get_workflow_engine(
519540 def has_type (rule_type : str ) -> bool :
520541 return not type_filter or rule_type in type_filter
521542
522- # Disable JIT for the combined paginator queries.
543+ # Disable JIT on the Detector/DetectorGroup database for the combined paginator queries.
523544 # The planner thinks our metric detector query is going to be very slow because DetectorGroup
524545 # in general has many Groups per Detector, even though for metrics detectors (our case here) it's effectively
525546 # one-to-one.
@@ -528,11 +549,11 @@ def has_type(rule_type: str) -> bool:
528549 # Disabling it makes this endpoint considerably faster.
529550 # The risk of other regression here should be low; our API endpoint isn't generally doing the sort of bulk
530551 # work that benefits from JIT.
531- db = router . db_for_write ( Detector )
532- with transaction . atomic ( using = db ):
533- with connections [ db ]. cursor () as cursor :
534- cursor . execute ( "SET LOCAL jit = off" )
535-
552+ #
553+ # Note: Monitor lives on a different database, so we can't use a transaction here
554+ # (SET LOCAL would require one). Session-level SET + RESET is fine for a request-scoped
555+ # connection.
556+ with _postgres_jit_disabled ( using = router . db_for_write ( Detector )):
536557 intermediaries : list [CombinedQuerysetIntermediary ] = []
537558 if has_type ("alert_rule" ):
538559 intermediaries .append (CombinedQuerysetIntermediary (metric_detectors , sort_key ))
0 commit comments