Skip to content

feat(workflow_engine): Add in hook for producing occurrences from the stateful detector#10

Open
everettbu wants to merge 1 commit into
workflow-engine-stateful-detector-beforefrom
workflow-engine-stateful-detector-after
Open

feat(workflow_engine): Add in hook for producing occurrences from the stateful detector#10
everettbu wants to merge 1 commit into
workflow-engine-stateful-detector-beforefrom
workflow-engine-stateful-detector-after

Conversation

@everettbu

@everettbu everettbu commented Jul 26, 2025

Copy link
Copy Markdown

Test 10

Summary by CodeRabbit

  • Refactor

    • Improved internal logic for detector evaluation, shifting from list-based to dictionary-based results for better clarity and maintainability.
    • Centralized group type retrieval for detectors to streamline processing.
  • Tests

    • Refactored and enhanced test coverage for detector processing, including new helper classes and more comprehensive validation of detector evaluation results.
    • Updated tests to reflect changes in how detector results are structured and verified.

… stateful detector (#80168)

This adds a hook that can be implemented to produce an occurrence
specific to the detector that is subclassing the StatefulDetector.

Also change the signature of evaluate to return a dict keyed by groupkey
instead of a list. This helps avoid the chance of duplicate results for
the same group key.

<!-- Describe your PR here. -->
@coderabbitai

coderabbitai Bot commented Jul 26, 2025

Copy link
Copy Markdown

Walkthrough

The changes refactor detector evaluation in the workflow engine from returning lists to returning dictionaries keyed by group keys. Abstract methods and class inheritance are updated to reflect this, and a new method for building issue occurrences and event data is introduced. Associated tests are overhauled to match the new API and improve coverage and maintainability.

Changes

Cohort / File(s) Change Summary
Detector Handler Refactor
src/sentry/incidents/grouptype.py
The MetricAlertDetectorHandler class now inherits from StatefulDetectorHandler instead of DetectorHandler, removes its evaluate method, and becomes an empty class. Imports are updated accordingly.
Detector Model Enhancement
src/sentry/workflow_engine/models/detector.py
Adds a group_type property to the Detector class to centralize group type lookup and updates the detector_handler property to use this new property.
Detector Processing Logic Overhaul
src/sentry/workflow_engine/processors/detector.py
Changes detector evaluation and processing to return dictionaries keyed by group keys instead of lists, adds an abstract method for building occurrences and event data, and updates method signatures and logic throughout DetectorHandler and StatefulDetectorHandler. Removes duplicate key checks.
Test Suite Refactor and Expansion
tests/sentry/workflow_engine/processors/test_detector.py
Extensively refactors and expands tests to use new handler logic, introduces a base test class and a mock handler, updates all assertions and mocks to expect dictionary outputs, and adds coverage for new abstract methods and side effects. Removes duplicate group key test.

Sequence Diagram(s)

sequenceDiagram
    participant DataPacket
    participant Detector
    participant DetectorHandler
    participant StatefulDetectorHandler
    participant TestSuite

    DataPacket->>Detector: process_detectors(data_packet, detectors)
    Detector->>DetectorHandler: evaluate(data_packet)
    alt Stateful Handler
        DetectorHandler->>StatefulDetectorHandler: evaluate(data_packet)
        StatefulDetectorHandler->>StatefulDetectorHandler: build_occurrence_and_event_data(group_key, value, new_status)
        StatefulDetectorHandler-->>Detector: dict[group_key, DetectorEvaluationResult]
    else Stateless Handler
        DetectorHandler-->>Detector: dict[group_key, DetectorEvaluationResult]
    end
    Detector-->>DataPacket: list of (Detector, dict[group_key, DetectorEvaluationResult])
    TestSuite->>DetectorHandler: evaluate(data_packet)
    TestSuite->>StatefulDetectorHandler: build_occurrence_and_event_data(...)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

In fields of code where group keys grow,
The handlers learned new ways to show—
No more lists, but dicts instead,
With mock detectors well-bred.
Tests now prance with greater might,
Occurrences built just right.
🐇 Hopping forward, all is bright!

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch workflow-engine-stateful-detector-after

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@everettbu

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 28, 2025

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/sentry/workflow_engine/models/detector.py (1)

3-3: Remove unnecessary builtins import and simplify type annotation.

The builtins import is unnecessary for type annotations. Python's built-in type can be used directly.

-import builtins
 import logging
 @property
-def group_type(self) -> builtins.type[GroupType] | None:
+def group_type(self) -> type[GroupType] | None:
     return grouptype.registry.get_by_slug(self.type)

Also applies to: 59-60

tests/sentry/workflow_engine/processors/test_detector.py (1)

123-124: Consider using @freeze_time at the method level for better granularity.

While using @freeze_time() at the class level works, applying it at the method level for only the tests that need stable timestamps would be more precise and make the test requirements clearer.

Also applies to: 422-423, 531-532

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7249010 and de60b7f.

📒 Files selected for processing (4)
  • src/sentry/incidents/grouptype.py (1 hunks)
  • src/sentry/workflow_engine/models/detector.py (3 hunks)
  • src/sentry/workflow_engine/processors/detector.py (9 hunks)
  • tests/sentry/workflow_engine/processors/test_detector.py (11 hunks)
🔇 Additional comments (13)
src/sentry/workflow_engine/models/detector.py (2)

58-61: Good refactoring to centralize group type retrieval.

The introduction of the group_type property effectively centralizes the logic for retrieving the group type from the registry, avoiding code duplication and improving maintainability.


62-86: LGTM! Proper use of the centralized group_type property.

The refactoring correctly uses the new group_type property instead of duplicating the registry lookup logic.

src/sentry/incidents/grouptype.py (2)

7-7: Clean import statement refactoring.

Good cleanup removing unused imports and retaining only the necessary StatefulDetectorHandler.


11-12: Appropriate inheritance from StatefulDetectorHandler.

The refactoring to inherit from StatefulDetectorHandler[QuerySubscriptionUpdate] aligns with the new stateful detector pattern. The removal of the empty evaluate method is correct since the parent class provides the implementation.

src/sentry/workflow_engine/processors/detector.py (5)

47-71: Good refactoring to use dictionaries for detector results.

The change from lists to dictionaries keyed by DetectorGroupKey improves the API by:

  • Providing O(1) lookup by group key
  • Naturally preventing duplicate keys
  • Making the data structure more intuitive

The removal of duplicate key error handling is appropriate since dictionaries inherently prevent duplicates.


125-129: Consistent update to abstract method signature.

The evaluate method's return type change to dict[DetectorGroupKey, DetectorEvaluationResult] properly reflects the new evaluation result structure across the codebase.


166-170: Well-designed abstract method for building occurrences.

The build_occurrence_and_event_data abstract method properly delegates occurrence creation to concrete implementations while providing all necessary context through its parameters.


226-244: Correct implementation of dictionary-based evaluation results.

The evaluate method properly implements the new contract by returning a dictionary keyed by group keys, maintaining consistency with the updated API.


288-308: Proper integration of the new occurrence building abstraction.

The method correctly delegates occurrence creation to the build_occurrence_and_event_data abstract method for non-OK statuses while maintaining the existing StatusChangeMessage logic for resolutions.

tests/sentry/workflow_engine/processors/test_detector.py (4)

27-40: Well-implemented mock handler for testing.

The MockDetectorStateHandler properly implements all abstract methods and provides a good foundation for testing the stateful detector behavior.


42-121: Excellent test base class design.

The BaseDetectorHandlerTest effectively consolidates common test setup and provides reusable utilities, significantly improving test maintainability and reducing duplication.


244-276: Good helper function for consistent test data generation.

The build_mock_occurrence_and_event function effectively centralizes the creation of test occurrences and event data, ensuring consistency across tests.


134-173: Comprehensive test coverage for the new dictionary-based API.

The tests properly verify:

  • Dictionary-based evaluation results
  • Occurrence and event data generation
  • Multi-group key handling
  • Kafka production calls

Excellent adaptation to the new API contract.

Also applies to: 174-223

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants