From 58d2e003bca861d5b164b2afe6566f54005cbd47 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Thu, 31 Oct 2024 19:59:42 +0100 Subject: [PATCH] feat: allow mutation rate limiter configuration (#1506) --- src/extensions/replay/mutation-rate-limiter.ts | 15 +++++++++++++-- src/extensions/replay/sessionrecording.ts | 2 ++ src/types.ts | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/extensions/replay/mutation-rate-limiter.ts b/src/extensions/replay/mutation-rate-limiter.ts index a85416cc5..4c515ebc2 100644 --- a/src/extensions/replay/mutation-rate-limiter.ts +++ b/src/extensions/replay/mutation-rate-limiter.ts @@ -1,5 +1,6 @@ import type { eventWithTime, mutationCallbackParam } from '@rrweb/types' import { INCREMENTAL_SNAPSHOT_EVENT_TYPE, MUTATION_SOURCE_TYPE, rrwebRecord } from './sessionrecording-utils' +import { clampToRange } from '../../utils/number-utils' export class MutationRateLimiter { private bucketSize = 100 @@ -15,8 +16,18 @@ export class MutationRateLimiter { onBlockedNode?: (id: number, node: Node | null) => void } = {} ) { - this.refillRate = this.options.refillRate ?? this.refillRate - this.bucketSize = this.options.bucketSize ?? this.bucketSize + this.refillRate = clampToRange( + this.options.refillRate ?? this.refillRate, + 0, + 100, + 'mutation throttling refill rate' + ) + this.bucketSize = clampToRange( + this.options.bucketSize ?? this.bucketSize, + 0, + 100, + 'mutation throttling bucket size' + ) setInterval(() => { this.refillBuckets() }, 1000) diff --git a/src/extensions/replay/sessionrecording.ts b/src/extensions/replay/sessionrecording.ts index 771976460..f46b64d8f 100644 --- a/src/extensions/replay/sessionrecording.ts +++ b/src/extensions/replay/sessionrecording.ts @@ -890,6 +890,8 @@ export class SessionRecording { this.mutationRateLimiter = this.mutationRateLimiter ?? new MutationRateLimiter(this.rrwebRecord, { + refillRate: this.instance.config.session_recording.__mutationRateLimiterRefillRate, + bucketSize: this.instance.config.session_recording.__mutationRateLimiterBucketSize, onBlockedNode: (id, node) => { const message = `Too many mutations on node '${id}'. Rate limiting. This could be due to SVG animations or something similar` logger.info(message, { diff --git a/src/types.ts b/src/types.ts index ea0674763..0f6c5cfc9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -309,6 +309,20 @@ export interface SessionRecordingOptions { Default is 5 minutes. */ session_idle_threshold_ms?: number + /* + ADVANCED: alters the refill rate for the token bucket mutation throttling + Normally only altered alongside posthog support guidance. + Accepts values between 0 and 100 + Default is 10. + */ + __mutationRateLimiterRefillRate?: number + /* + ADVANCED: alters the bucket size for the token bucket mutation throttling + Normally only altered alongside posthog support guidance. + Accepts values between 0 and 100 + Default is 100. + */ + __mutationRateLimiterBucketSize?: number } export type SessionIdChangedCallback = (