-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
ref(detectors): Add abstract-ish base class for DetectorHandler #108000
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,11 +86,37 @@ class GroupedDetectorEvaluationResult: | |
| tainted: bool | ||
|
|
||
|
|
||
| # TODO - @saponifi3d - Change this class to be a pure ABC and remove the `__init__` method. | ||
| # TODO - @saponifi3d - Once the change is made, we should introduce a `BaseDetector` class to evaluate simple cases | ||
| class DetectorHandler(abc.ABC, Generic[DataPacketType, DataPacketEvaluationType]): | ||
| class DetectorHandler(abc.ABC, Generic[DataPacketType]): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if this is kept as a pure ABC, should it live in |
||
| """ | ||
| Abstract base class defining the public interface for detector handlers. | ||
| """ | ||
|
|
||
| def __init__(self, detector: Detector): | ||
| self.detector = detector | ||
|
Comment on lines
94
to
95
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we keep this as a pure abc and only have type definitions?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted to, but an abstract constructor felt strange when an actual constructor gave us what we needed. DetectorSettings could use a Callable which constructs the correct type, could've gone with an abstract static constructor, but in nearly all worlds it seemed like we'd just be requiring someone to implement this init, so I went with it. Open to alternatives, but wasn't sold by the ones I considered as being better. |
||
|
|
||
| @abc.abstractmethod | ||
| def evaluate( | ||
| self, data_packet: DataPacket[DataPacketType] | ||
| ) -> dict[DetectorGroupKey, DetectorEvaluationResult]: | ||
| pass | ||
|
|
||
|
|
||
| class BaseDetectorHandler( | ||
| DetectorHandler[DataPacketType], | ||
| Generic[DataPacketType, DataPacketEvaluationType], | ||
| ): | ||
| """ | ||
| Base implementation class providing shared infrastructure for detector handlers. | ||
| Includes metrics tracking, condition group loading, and defines abstract methods | ||
| that concrete handlers must implement. | ||
|
|
||
| DataPacketType is what we've embedded within the data packet. | ||
| DataPacketEvaluationType is the type of the value to be extracted from the data packet and | ||
| used to evaluate the conditions on the detector. | ||
| """ | ||
|
|
||
| def __init__(self, detector: Detector): | ||
| super().__init__(detector) | ||
| if detector.workflow_condition_group_id is not None: | ||
| try: | ||
| # Check if workflow_condition_group is already prefetched | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ | |
| from sentry.testutils.silo import region_silo_test | ||
| from sentry.uptime.grouptype import UptimeDomainCheckFailure | ||
| from sentry.workflow_engine.handlers.detector import ( | ||
| DetectorHandler, | ||
| BaseDetectorHandler, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for future - this could be a super cool abstraction; we could create a TestDetectorHandler and all the registration info. right now most of the tests are loosely based on an existing detector type cause... time. |
||
| DetectorOccurrence, | ||
| GroupedDetectorEvaluationResult, | ||
| ) | ||
|
|
@@ -42,7 +42,7 @@ def setUp(self) -> None: | |
| ) | ||
| self.registry_patcher.start() | ||
|
|
||
| class MockDetectorHandler(DetectorHandler[dict[Never, Never], bool]): | ||
| class MockDetectorHandler(BaseDetectorHandler[dict[Never, Never], bool]): | ||
| def evaluate_impl( | ||
| self, data_packet: DataPacket[dict[Never, Never]] | ||
| ) -> GroupedDetectorEvaluationResult: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing i've struggled with in these abstractions is the
DetectorGroupKey- and grouping in general for the results.. 🤔 should we have a grouping detector that handles all of this?I haven't bottomed out on any of that stuff, just a thought i've been struggling with when looking at the base class. (the functional programmer in me wants to make GroupingDetector and decorate these classes with it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been spinning on this a bit myself, and I'm not sure yet. This change is partially a spinoff of me trying to reason through these issues.