Skip to content

Commit a487d40

Browse files
ref(workflow_engine): Remove DetectorLifeCycleHooks (#102990)
These hooks can be implemented by overriding the validator and hooking into create / update / delete Fixes [NEW-610: Provide way for detectors `after_update` hooks to have knowledge of what changed](https://linear.app/getsentry/issue/NEW-610/provide-way-for-detectors-after-update-hooks-to-have-knowledge-of-what)
1 parent 8dd1ef6 commit a487d40

File tree

5 files changed

+2
-162
lines changed

5 files changed

+2
-162
lines changed

src/sentry/workflow_engine/endpoints/organization_detector_details.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
)
3636
from sentry.workflow_engine.endpoints.validators.utils import get_unknown_detector_type_error
3737
from sentry.workflow_engine.models import Detector
38-
from sentry.workflow_engine.types import DetectorLifeCycleHooks
3938

4039

4140
def get_detector_validator(
@@ -205,8 +204,6 @@ def delete(self, request: Request, organization: Organization, detector: Detecto
205204
)
206205
validator.delete()
207206

208-
DetectorLifeCycleHooks.on_pending_delete(detector)
209-
210207
if detector.type == MetricIssue.slug:
211208
schedule_update_project_config(detector)
212209

src/sentry/workflow_engine/endpoints/validators/base/detector.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
)
3131
from sentry.workflow_engine.models.data_condition import DataCondition
3232
from sentry.workflow_engine.models.detector import enforce_config_schema
33-
from sentry.workflow_engine.types import DataConditionType, DetectorLifeCycleHooks
33+
from sentry.workflow_engine.types import DataConditionType
3434

3535

3636
@dataclass(frozen=True)
@@ -143,7 +143,6 @@ def update(self, instance: Detector, validated_data: dict[str, Any]):
143143
data=instance.get_audit_log_data(),
144144
)
145145

146-
DetectorLifeCycleHooks.on_after_update(instance)
147146
return instance
148147

149148
def delete(self) -> None:
@@ -230,6 +229,4 @@ def create(self, validated_data):
230229
data=detector.get_audit_log_data(),
231230
)
232231

233-
DetectorLifeCycleHooks.on_after_create(detector)
234-
235232
return detector

src/sentry/workflow_engine/types.py

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from __future__ import annotations
22

33
from abc import ABC, abstractmethod
4-
from collections.abc import Callable
54
from dataclasses import dataclass, field
65
from enum import IntEnum, StrEnum
76
from typing import TYPE_CHECKING, Any, ClassVar, Generic, TypedDict, TypeVar
@@ -184,54 +183,8 @@ class SnubaQueryDataSourceType(TypedDict):
184183
event_types: list[SnubaQueryEventType]
185184

186185

187-
type DetectorLifeCycleHook = Callable[[Detector], None]
188-
189-
190-
@dataclass(frozen=True)
191-
class DetectorLifeCycleHooks:
192-
"""
193-
The DetectorLifeCycleHooks allow for hooks to be added into different areas of the API.
194-
These hooks are only invoked through the API, for changes that might be happening outside of the API,
195-
it's recommended to use a signal to capture the model updates.
196-
197-
Args:
198-
after_create:
199-
This method is used as a callback after a detector is created. The first argument is the detector that was created.
200-
201-
before_delete:
202-
This method is used in the deletion API for a detector, the callback will be invoked with the id for the detector
203-
that is deleted.
204-
205-
after_update:
206-
This method is used to access when a detector is updated in the API.
207-
"""
208-
209-
after_create: DetectorLifeCycleHook | None = None
210-
pending_delete: DetectorLifeCycleHook | None = None
211-
after_update: DetectorLifeCycleHook | None = None
212-
213-
@staticmethod
214-
def on_after_create(detector: Detector):
215-
hooks = detector.settings.hooks
216-
if hooks and hooks.after_create:
217-
hooks.after_create(detector)
218-
219-
@staticmethod
220-
def on_after_update(detector: Detector):
221-
hooks = detector.settings.hooks
222-
if hooks and hooks.after_update:
223-
hooks.after_update(detector)
224-
225-
@staticmethod
226-
def on_pending_delete(detector: Detector):
227-
hooks = detector.settings.hooks
228-
if hooks and hooks.pending_delete:
229-
hooks.pending_delete(detector)
230-
231-
232186
@dataclass(frozen=True)
233187
class DetectorSettings:
234-
hooks: DetectorLifeCycleHooks | None = None
235188
handler: type[DetectorHandler] | None = None
236189
validator: type[BaseDetectorTypeValidator] | None = None
237190
config_schema: dict[str, Any] = field(default_factory=dict)

tests/sentry/workflow_engine/detectors/test_life_cycle_hooks.py

Lines changed: 0 additions & 77 deletions
This file was deleted.

tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@
3131
)
3232
from sentry.workflow_engine.models.data_condition import Condition
3333
from sentry.workflow_engine.models.detector_workflow import DetectorWorkflow
34-
from sentry.workflow_engine.types import (
35-
DetectorLifeCycleHooks,
36-
DetectorPriorityLevel,
37-
DetectorSettings,
38-
)
34+
from sentry.workflow_engine.types import DetectorPriorityLevel
3935

4036
pytestmark = [pytest.mark.sentry_metrics, requires_snuba, requires_kafka]
4137

@@ -761,29 +757,3 @@ def test_error_group_type(self) -> None:
761757
event=audit_log.get_event_id("DETECTOR_REMOVE"),
762758
actor=self.user,
763759
).exists()
764-
765-
def test_detector_life_cycle_delete_hook(self) -> None:
766-
detector_settings = DetectorSettings(
767-
hooks=DetectorLifeCycleHooks(pending_delete=mock.Mock())
768-
)
769-
770-
with mock.patch.object(
771-
Detector, "settings", new_callable=mock.PropertyMock
772-
) as mock_settings:
773-
mock_settings.return_value = detector_settings
774-
775-
with outbox_runner():
776-
self.get_success_response(self.organization.slug, self.detector.id)
777-
778-
detector_settings.hooks.pending_delete.assert_called_with(self.detector) # type: ignore[union-attr]
779-
780-
def test_detector_life_cycle__no_delete_hook(self) -> None:
781-
detector_settings = DetectorSettings(hooks=DetectorLifeCycleHooks())
782-
783-
with mock.patch.object(
784-
Detector, "settings", new_callable=mock.PropertyMock
785-
) as mock_settings:
786-
mock_settings.return_value = detector_settings
787-
788-
with outbox_runner():
789-
self.get_success_response(self.organization.slug, self.detector.id)

0 commit comments

Comments
 (0)