Skip to content

Commit

Permalink
fix(replays): Use different enforcement category for replay video (#4459
Browse files Browse the repository at this point in the history
)

We currently offer unlimited replay mobile events for beta customers
until April 6th. Customers who exhaust their web quota have their mobile
quota blocked because they share the same category. I've updated the
enforcement to use different counts for each event type. This is
temporary and will be removed after the grace period expires.

---------

Co-authored-by: Joris Bayer <[email protected]>
  • Loading branch information
cmanallen and jjbayer authored Jan 21, 2025
1 parent d57a848 commit 520187f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

## 25.1.0

**Features**:

- Use a separate rate-limit enforcement category for replay-video envelope items. ([#4459](https://github.com/getsentry/relay/pull/4459))

**Internal**:

- Updates performance score calculation on spans and events to also store cdf values as measurements. ([#4438](https://github.com/getsentry/relay/pull/4438))
Expand Down
3 changes: 2 additions & 1 deletion relay-server/src/envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,9 +700,10 @@ impl Item {
ItemType::UserReport => smallvec![],
ItemType::UserReportV2 => smallvec![(DataCategory::UserReportV2, 1)],
ItemType::Profile => smallvec![(DataCategory::Profile, 1)],
ItemType::ReplayEvent | ItemType::ReplayRecording | ItemType::ReplayVideo => {
ItemType::ReplayEvent | ItemType::ReplayRecording => {
smallvec![(DataCategory::Replay, 1)]
}
ItemType::ReplayVideo => smallvec![(DataCategory::ReplayVideo, 1)],
ItemType::ClientReport => smallvec![],
ItemType::CheckIn => smallvec![(DataCategory::Monitor, 1)],
ItemType::Span | ItemType::OtelSpan => smallvec![(DataCategory::Span, 1)],
Expand Down
50 changes: 45 additions & 5 deletions relay-server/src/utils/rate_limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ pub struct EnvelopeSummary {
/// The number of replays.
pub replay_quantity: usize,

/// The number of replay videos.
pub replay_video_quantity: usize,

/// The number of monitor check-ins.
pub monitor_quantity: usize,

Expand Down Expand Up @@ -236,7 +239,7 @@ impl EnvelopeSummary {
DataCategory::Session => &mut self.session_quantity,
DataCategory::Profile => &mut self.profile_quantity,
DataCategory::Replay => &mut self.replay_quantity,
DataCategory::ReplayVideo => &mut self.replay_quantity,
DataCategory::ReplayVideo => &mut self.replay_video_quantity,
DataCategory::Monitor => &mut self.monitor_quantity,
DataCategory::Span => &mut self.span_quantity,
DataCategory::ProfileChunk => &mut self.profile_chunk_quantity,
Expand Down Expand Up @@ -342,6 +345,8 @@ pub struct Enforcement {
pub profiles_indexed: CategoryLimit,
/// The combined replay item rate limit.
pub replays: CategoryLimit,
/// The combined replay video item rate limit.
pub replay_videos: CategoryLimit,
/// The combined check-in item rate limit.
pub check_ins: CategoryLimit,
/// The combined spans rate limit.
Expand Down Expand Up @@ -384,6 +389,7 @@ impl Enforcement {
profiles,
profiles_indexed,
replays,
replay_videos,
check_ins,
spans,
spans_indexed,
Expand All @@ -399,6 +405,7 @@ impl Enforcement {
profiles,
profiles_indexed,
replays,
replay_videos,
check_ins,
spans,
spans_indexed,
Expand Down Expand Up @@ -485,7 +492,7 @@ impl Enforcement {
ItemType::Session => !self.sessions.is_active(),
ItemType::Profile => !self.profiles_indexed.is_active(),
ItemType::ReplayEvent => !self.replays.is_active(),
ItemType::ReplayVideo => !self.replays.is_active(),
ItemType::ReplayVideo => !self.replay_videos.is_active(),
ItemType::ReplayRecording => !self.replays.is_active(),
ItemType::CheckIn => !self.check_ins.is_active(),
ItemType::Span | ItemType::OtelSpan | ItemType::OtelTracesData => {
Expand Down Expand Up @@ -757,6 +764,21 @@ where
rate_limits.merge(replay_limits);
}

// Handle replay video.
// Remove: 2025-04-06
if summary.replay_video_quantity > 0 {
let item_scoping = scoping.item(DataCategory::ReplayVideo);
let replay_limits = self
.check
.apply(item_scoping, summary.replay_video_quantity)?;
enforcement.replay_videos = CategoryLimit::new(
DataCategory::ReplayVideo,
summary.replay_video_quantity,
replay_limits.longest(),
);
rate_limits.merge(replay_limits);
}

// Handle monitor checkins.
if summary.monitor_quantity > 0 {
let item_scoping = scoping.item(DataCategory::Monitor);
Expand Down Expand Up @@ -1270,16 +1292,34 @@ mod tests {
/// Limit replays.
#[test]
fn test_enforce_limit_replays() {
let mut envelope = envelope![ReplayEvent, ReplayRecording, ReplayVideo];
let mut envelope = envelope![ReplayEvent, ReplayRecording];

let mut mock = MockLimiter::default().deny(DataCategory::Replay);
let (enforcement, limits) = enforce_and_apply(&mut mock, &mut envelope, None);

assert!(limits.is_limited());
assert_eq!(envelope.envelope().len(), 0);
mock.assert_call(DataCategory::Replay, 3);
mock.assert_call(DataCategory::Replay, 2);

assert_eq!(get_outcomes(enforcement), vec![(DataCategory::Replay, 2),]);
}

/// Limit replays.
#[test]
fn test_enforce_limit_replay_video() {
let mut envelope = envelope![ReplayVideo];

let mut mock = MockLimiter::default().deny(DataCategory::ReplayVideo);
let (enforcement, limits) = enforce_and_apply(&mut mock, &mut envelope, None);

assert!(limits.is_limited());
assert_eq!(envelope.envelope().len(), 0);
mock.assert_call(DataCategory::ReplayVideo, 1);

assert_eq!(get_outcomes(enforcement), vec![(DataCategory::Replay, 3),]);
assert_eq!(
get_outcomes(enforcement),
vec![(DataCategory::ReplayVideo, 1),]
);
}

/// Limit monitor checkins.
Expand Down

0 comments on commit 520187f

Please sign in to comment.