Skip to content

Commit 6bd4514

Browse files
committed
feat(crons): Add CronMonitorDataSourceHandler
Adding a new `DataSourceHandler` so that we can treat cron `Monitor` rows as a `DataSource`
1 parent f17ceaf commit 6bd4514

File tree

3 files changed

+111
-240
lines changed

3 files changed

+111
-240
lines changed

src/sentry/monitors/models.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import zoneinfo
66
from collections.abc import Sequence
77
from datetime import datetime
8-
from typing import TYPE_CHECKING, Any, ClassVar, Self
8+
from typing import TYPE_CHECKING, Any, ClassVar, Self, override
99
from uuid import uuid4
1010

1111
import jsonschema
@@ -34,12 +34,17 @@
3434
from sentry.db.models.fields.slug import DEFAULT_SLUG_MAX_LENGTH, SentrySlugField
3535
from sentry.db.models.manager.base import BaseManager
3636
from sentry.db.models.utils import slugify_instance
37+
from sentry.deletions.base import ModelRelation
3738
from sentry.locks import locks
3839
from sentry.models.environment import Environment
40+
from sentry.models.organization import Organization
3941
from sentry.models.rule import Rule, RuleSource
40-
from sentry.monitors.types import CrontabSchedule, IntervalSchedule
42+
from sentry.monitors.types import DATA_SOURCE_CRON_MONITOR, CrontabSchedule, IntervalSchedule
4143
from sentry.types.actor import Actor
4244
from sentry.utils.retries import TimedRetryPolicy
45+
from sentry.workflow_engine.models import DataSource
46+
from sentry.workflow_engine.registry import data_source_type_registry
47+
from sentry.workflow_engine.types import DataSourceTypeHandler
4348

4449
logger = logging.getLogger(__name__)
4550

@@ -790,3 +795,41 @@ class MonitorEnvBrokenDetection(Model):
790795
class Meta:
791796
app_label = "monitors"
792797
db_table = "sentry_monitorenvbrokendetection"
798+
799+
800+
@data_source_type_registry.register(DATA_SOURCE_CRON_MONITOR)
801+
class CronMonitorDataSourceHandler(DataSourceTypeHandler[Monitor]):
802+
@staticmethod
803+
def bulk_get_query_object(
804+
data_sources: list[DataSource],
805+
) -> dict[int, Monitor | None]:
806+
monitor_ids: list[int] = []
807+
808+
for ds in data_sources:
809+
try:
810+
monitor_ids.append(int(ds.source_id))
811+
except ValueError:
812+
logger.exception(
813+
"Invalid DataSource.source_id fetching Monitor",
814+
extra={"id": ds.id, "source_id": ds.source_id},
815+
)
816+
817+
qs_lookup = {
818+
str(monitor.id): monitor for monitor in Monitor.objects.filter(id__in=monitor_ids)
819+
}
820+
return {ds.id: qs_lookup.get(ds.source_id) for ds in data_sources}
821+
822+
@staticmethod
823+
def related_model(instance) -> list[ModelRelation]:
824+
return [ModelRelation(Monitor, {"id": instance.source_id})]
825+
826+
@override
827+
@staticmethod
828+
def get_instance_limit(org: Organization) -> int | None:
829+
return None
830+
831+
@override
832+
@staticmethod
833+
def get_current_instance_count(org: Organization) -> int:
834+
# We don't have a limit at the moment, so no need to count.
835+
raise NotImplementedError

src/sentry/monitors/types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
from sentry.db.models.fields.slug import DEFAULT_SLUG_MAX_LENGTH
1212

13+
DATA_SOURCE_CRON_MONITOR = "cron_monitor"
14+
1315

1416
class CheckinTrace(TypedDict):
1517
trace_id: str

0 commit comments

Comments
 (0)