|
7 | 7 | import sentry_sdk
|
8 | 8 | from django.conf import settings
|
9 | 9 | from django.utils import timezone
|
| 10 | +from google.api_core.exceptions import ServiceUnavailable |
10 | 11 |
|
11 | 12 | from sentry import features
|
12 | 13 | from sentry.exceptions import PluginError
|
|
20 | 21 | from sentry.utils.event_frames import get_sdk_name
|
21 | 22 | from sentry.utils.locking import UnableToAcquireLock
|
22 | 23 | from sentry.utils.locking.manager import LockManager
|
| 24 | +from sentry.utils.retries import ConditionalRetryPolicy, exponential_delay |
23 | 25 | from sentry.utils.safe import safe_execute
|
24 | 26 | from sentry.utils.sdk import bind_organization_context, set_current_event_project
|
25 | 27 | from sentry.utils.services import build_instance_from_options
|
@@ -388,6 +390,20 @@ def fetch_buffered_group_stats(group):
|
388 | 390 | group.times_seen_pending = result["times_seen"]
|
389 | 391 |
|
390 | 392 |
|
| 393 | +MAX_FETCH_ATTEMPTS = 3 |
| 394 | + |
| 395 | + |
| 396 | +def should_retry_fetch(attempt: int, e: Exception) -> bool: |
| 397 | + from sentry.issues.occurrence_consumer import EventLookupError |
| 398 | + |
| 399 | + return not attempt > MAX_FETCH_ATTEMPTS and ( |
| 400 | + isinstance(e, ServiceUnavailable) or isinstance(e, EventLookupError) |
| 401 | + ) |
| 402 | + |
| 403 | + |
| 404 | +fetch_retry_policy = ConditionalRetryPolicy(should_retry_fetch, exponential_delay(1.00)) |
| 405 | + |
| 406 | + |
391 | 407 | @instrumented_task(
|
392 | 408 | name="sentry.tasks.post_process.post_process_group",
|
393 | 409 | time_limit=120,
|
@@ -418,6 +434,7 @@ def post_process_group(
|
418 | 434 | from sentry.ingest.transaction_clusterer.datasource.redis import (
|
419 | 435 | record_transaction_name as record_transaction_name_for_clustering,
|
420 | 436 | )
|
| 437 | + from sentry.issues.occurrence_consumer import EventLookupError |
421 | 438 | from sentry.models import Organization, Project
|
422 | 439 | from sentry.reprocessing2 import is_reprocessed_event
|
423 | 440 |
|
@@ -468,9 +485,21 @@ def post_process_group(
|
468 | 485 | return
|
469 | 486 | # Issue platform events don't use `event_processing_store`. Fetch from eventstore
|
470 | 487 | # instead.
|
471 |
| - event = eventstore.get_event_by_id( |
472 |
| - project_id, occurrence.event_id, group_id=group_id, skip_transaction_groupevent=True |
473 |
| - ) |
| 488 | + |
| 489 | + def get_event_raise_exception() -> Event: |
| 490 | + retrieved = eventstore.get_event_by_id( |
| 491 | + project_id, |
| 492 | + occurrence.event_id, |
| 493 | + group_id=group_id, |
| 494 | + skip_transaction_groupevent=True, |
| 495 | + ) |
| 496 | + if retrieved is None: |
| 497 | + raise EventLookupError( |
| 498 | + f"failed to retrieve event(project_id={project_id}, event_id={occurrence.event_id}, group_id={group_id}) from eventstore" |
| 499 | + ) |
| 500 | + return retrieved |
| 501 | + |
| 502 | + event = fetch_retry_policy(get_event_raise_exception) |
474 | 503 |
|
475 | 504 | set_current_event_project(event.project_id)
|
476 | 505 |
|
|
0 commit comments