Skip to content

Commit

Permalink
draft of rate limiter
Browse files Browse the repository at this point in the history
  • Loading branch information
roggenkemper committed Oct 8, 2024
1 parent 136cc0a commit d417da7
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/sentry/issues/occurrence_consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from sentry_sdk.tracing import NoOpSpan, Span, Transaction

from sentry import features, nodestore
from sentry import ratelimits as ratelimiter
from sentry.event_manager import GroupInfo
from sentry.eventstore.models import Event
from sentry.issues.grouptype import get_group_type_by_type_id
Expand Down Expand Up @@ -319,6 +320,21 @@ def process_occurrence_message(
txn.set_tag("result", "dropped_feature_disabled")
return None

# Rate limit based on project and fingerprint
rate_limit_key = f"occurrence_rate_limit:{occurrence_data['fingerprint']}"
if ratelimiter.is_limited(
rate_limit_key,
limit=10,
window=60, # 10 occurrences per minute
):
metrics.incr(
"occurrence_ingest.dropped_rate_limited",
sample_rate=1.0,
tags=metric_tags,
)
txn.set_tag("result", "dropped_rate_limited")
return None

if "event_data" in kwargs and is_buffered_spans:
return create_event_and_issue_occurrence(kwargs["occurrence_data"], kwargs["event_data"])
elif "event_data" in kwargs:
Expand Down
11 changes: 11 additions & 0 deletions tests/sentry/issues/test_occurrence_consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from datetime import timezone
from typing import Any
from unittest import mock
from unittest.mock import patch

import pytest
from django.core.cache import cache
Expand Down Expand Up @@ -243,6 +244,16 @@ def test_new_group_with_invalid_user_assignee(self) -> None:
with pytest.raises(GroupAssignee.DoesNotExist):
GroupAssignee.objects.get(group=group)

@patch(
"sentry.issues.occurrence_consumer.ratelimiter.backend.is_limited",
return_value=True,
)
def test_rate_limit(self, is_limited) -> None:
message = get_test_message(self.project.id)
with self.feature("organizations:profile-file-io-main-thread-ingest"):
result = _process_message(message)
assert result is None


class IssueOccurrenceLookupEventIdTest(IssueOccurrenceTestBase):
def test_lookup_event_doesnt_exist(self) -> None:
Expand Down

0 comments on commit d417da7

Please sign in to comment.