Skip to content

feat(occurrences on eap): Implement EAP query for eventstore get_events#112423

Open
shashjar wants to merge 4 commits intomasterfrom
shashjar/eventstore-get-events-eap-query
Open

feat(occurrences on eap): Implement EAP query for eventstore get_events#112423
shashjar wants to merge 4 commits intomasterfrom
shashjar/eventstore-get-events-eap-query

Conversation

@shashjar
Copy link
Copy Markdown
Member

@shashjar shashjar commented Apr 7, 2026

Implements an EAP query (double read) for the eventstore's __get_events function (used by both get_events & get_unfetched_events) in src/sentry/services/eventstore/snuba/backend.py.

Rather than write logic to convert an eventstore.Filter value to the equivalent format needed for an EAP query, I'm adding logic here to create eap_conditions at the individual callsites.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 7, 2026
stripped = col.lstrip("-")
prefix = "-" if col.startswith("-") else ""
# EAP uses "id" as the public alias for event_id
eap_name = "id" if stripped == "event_id" else stripped
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Special case needed here

@shashjar shashjar requested review from a team and thetruecpaul April 8, 2026 21:46
@shashjar shashjar marked this pull request as ready for review April 8, 2026 21:49
@shashjar shashjar requested review from a team as code owners April 8, 2026 21:49
@shashjar shashjar removed request for a team April 8, 2026 21:49
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: EAP double-read skipped on nodestore optimization path
    • Added EAP double-read comparison logic to the nodestore optimization path so validation now runs consistently for all callsites regardless of which query path is taken.

Create PR

Or push these changes by commenting:

@cursor push 4db9973e34
Preview (4db9973e34)
diff --git a/src/sentry/services/eventstore/snuba/backend.py b/src/sentry/services/eventstore/snuba/backend.py
--- a/src/sentry/services/eventstore/snuba/backend.py
+++ b/src/sentry/services/eventstore/snuba/backend.py
@@ -352,6 +352,58 @@
                     for event in events:
                         node_data = nodestore_dict[(event.event_id, event.project_id)]
                         event.data.bind_data(node_data)
+
+                    callsite = "eventstore.backend.get_events"
+                    if (
+                        eap_conditions is not None
+                        and tenant_ids
+                        and "organization_id" in tenant_ids
+                        and EAPOccurrencesComparator.should_check_experiment(callsite)
+                    ):
+                        occurrence_category = (
+                            OccurrenceCategory.ISSUE_PLATFORM
+                            if dataset == Dataset.IssuePlatform
+                            else OccurrenceCategory.ERROR
+                        )
+                        eap_results = self._get_events_eap(
+                            eap_conditions=eap_conditions,
+                            project_ids=filter.project_ids or [],
+                            organization_id=tenant_ids["organization_id"],
+                            occurrence_category=occurrence_category,
+                            orderby=orderby,
+                            limit=limit,
+                            offset=offset,
+                            referrer=referrer,
+                            start=filter.start,
+                            end=filter.end,
+                            group_ids=filter.group_ids,
+                        )
+                        control_data = {(e.event_id, e.group_id) for e in events}
+                        experimental_data = (
+                            {(row["id"], row["group_id"]) for row in eap_results}
+                            if eap_results is not None
+                            else set()
+                        )
+                        EAPOccurrencesComparator.check_and_choose(
+                            control_data=control_data,
+                            experimental_data=experimental_data,
+                            callsite=callsite,
+                            is_experimental_data_a_null_result=eap_results is None,
+                            reasonable_match_comparator=lambda ctl, exp: exp.issubset(ctl),
+                            debug_context={
+                                "project_ids": list(filter.project_ids)
+                                if filter.project_ids
+                                else [],
+                                "group_ids": list(filter.group_ids) if filter.group_ids else [],
+                                "dataset": dataset.value,
+                                "limit": limit,
+                                "offset": offset,
+                                "referrer": referrer,
+                                "control_count": len(events),
+                                "experimental_count": len(experimental_data),
+                            },
+                        )
+
                     return events
 
             return []

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2c5b26e. Configure here.

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

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant