Skip to content

Commit 10ddb84

Browse files
committed
fragment-sampling
1 parent 3523548 commit 10ddb84

File tree

2 files changed

+51
-29
lines changed

2 files changed

+51
-29
lines changed

firebase-perf/src/main/java/com/google/firebase/perf/transport/RateLimiter.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ final class RateLimiter {
4949
/** The app's bucket ID for sampling, a number in [0.0f, 1.0f). */
5050
private final float samplingBucketId;
5151

52+
private final float fragmentBucketId;
53+
5254
private RateLimiterImpl traceLimiter = null;
5355
private RateLimiterImpl networkLimiter = null;
5456

@@ -63,7 +65,13 @@ final class RateLimiter {
6365
* @param capacity token bucket capacity
6466
*/
6567
public RateLimiter(@NonNull Context appContext, final Rate rate, final long capacity) {
66-
this(rate, capacity, new Clock(), getSamplingBucketId(), ConfigResolver.getInstance());
68+
this(
69+
rate,
70+
capacity,
71+
new Clock(),
72+
getSamplingBucketId(),
73+
getSamplingBucketId(),
74+
ConfigResolver.getInstance());
6775
this.isLogcatEnabled = Utils.isDebugLoggingEnabled(appContext);
6876
}
6977

@@ -78,11 +86,16 @@ static float getSamplingBucketId() {
7886
final long capacity,
7987
final Clock clock,
8088
float samplingBucketId,
89+
float fragmentBucketId,
8190
ConfigResolver configResolver) {
8291
Utils.checkArgument(
83-
0.0f <= samplingBucketId && samplingBucketId < 1.0f,
92+
0.0f <= samplingBucketId
93+
&& samplingBucketId < 1.0f
94+
&& 0.0f <= fragmentBucketId
95+
&& fragmentBucketId < 1.0f,
8496
"Sampling bucket ID should be in range [0.0f, 1.0f).");
8597
this.samplingBucketId = samplingBucketId;
98+
this.fragmentBucketId = fragmentBucketId;
8699
this.configResolver = configResolver;
87100

88101
traceLimiter =
@@ -110,7 +123,7 @@ private boolean isDeviceAllowedToSendNetworkEvents() {
110123
*/
111124
private boolean isDeviceAllowedToSendFragmentScreenTraces() {
112125
float validFragmentSamplingBucketIdThreshold = configResolver.getFragmentSamplingRate();
113-
return samplingBucketId < validFragmentSamplingBucketIdThreshold;
126+
return fragmentBucketId < validFragmentSamplingBucketIdThreshold;
114127
}
115128

116129
/** Identifies if the {@link PerfMetric} is a Fragment screen trace */

firebase-perf/src/test/java/com/google/firebase/perf/transport/RateLimiterTest.java

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ public void testRateLimit() {
318318
// clock is 0, token count is 2.
319319

320320
RateLimiter limiter =
321-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, mockConfigResolver);
321+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, 0, mockConfigResolver);
322322
PerfMetric metric = PerfMetric.getDefaultInstance();
323323
// if PerfMetric object has neither TraceMetric or NetworkRequestMetric field set, always return
324324
// true.
@@ -379,7 +379,7 @@ public void testDeviceSampling_tracesEnabledButNetworkDisabled() {
379379
when(mockConfigResolver.getNetworkRequestSamplingRate()).thenReturn(0.02f);
380380

381381
RateLimiter limiter =
382-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, mockConfigResolver);
382+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, 0, mockConfigResolver);
383383

384384
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isTrue();
385385
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isFalse();
@@ -392,7 +392,7 @@ public void testDeviceSampling_tracesDisabledButNetworkEnabled() {
392392
when(mockConfigResolver.getNetworkRequestSamplingRate()).thenReturn(0.5f);
393393

394394
RateLimiter limiter =
395-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, mockConfigResolver);
395+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, 0, mockConfigResolver);
396396

397397
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isTrue();
398398
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isFalse();
@@ -405,7 +405,7 @@ public void testDeviceSampling_tracesEnabledButFragmentDisabled_dropsFragmentTra
405405
when(mockConfigResolver.getFragmentSamplingRate()).thenReturn(0.02f);
406406

407407
RateLimiter limiter =
408-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, mockConfigResolver);
408+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, 0.49f, mockConfigResolver);
409409

410410
assertThat(limiter.getIsDeviceAllowedToSendFragmentScreenTraces()).isFalse();
411411
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isTrue();
@@ -441,7 +441,7 @@ public void testDeviceSampling_tracesDisabledButFragmentEnabled_dropsFragmentTra
441441
when(mockConfigResolver.getFragmentSamplingRate()).thenReturn(0.5f);
442442

443443
RateLimiter limiter =
444-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, mockConfigResolver);
444+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, 0.49f, mockConfigResolver);
445445

446446
assertThat(limiter.getIsDeviceAllowedToSendFragmentScreenTraces()).isTrue();
447447
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isFalse();
@@ -465,7 +465,7 @@ public void getIsDeviceAllowedToSendTraces_8digitSamplingRate_traceIsEnabled() {
465465
when(mockConfigResolver.getTraceSamplingRate()).thenReturn(0.00000001f);
466466

467467
RateLimiter limiter =
468-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000005f, mockConfigResolver);
468+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000005f, 0, mockConfigResolver);
469469

470470
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isTrue();
471471
}
@@ -476,7 +476,7 @@ public void getIsDeviceAllowedToSendTraces_8digitSamplingRate_traceIsDisabled()
476476
when(mockConfigResolver.getTraceSamplingRate()).thenReturn(0.00000001f);
477477

478478
RateLimiter limiter =
479-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000011f, mockConfigResolver);
479+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000011f, 0, mockConfigResolver);
480480

481481
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isFalse();
482482
}
@@ -487,7 +487,7 @@ public void getIsDeviceAllowedToSendNetwork_8digitSamplingRate_networkIsEnabled(
487487
when(mockConfigResolver.getNetworkRequestSamplingRate()).thenReturn(0.00000001f);
488488

489489
RateLimiter limiter =
490-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000005f, mockConfigResolver);
490+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000005f, 0, mockConfigResolver);
491491

492492
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isTrue();
493493
}
@@ -498,7 +498,7 @@ public void getIsDeviceAllowedToSendNetwork_8digitSamplingRate_networkIsDisabled
498498
when(mockConfigResolver.getNetworkRequestSamplingRate()).thenReturn(0.00000001f);
499499

500500
RateLimiter limiter =
501-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000011f, mockConfigResolver);
501+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000011f, 0, mockConfigResolver);
502502

503503
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isFalse();
504504
}
@@ -509,7 +509,7 @@ public void getIsDeviceAllowedToSendFragmentScreenTraces_8digitSamplingRate_frag
509509
when(mockConfigResolver.getFragmentSamplingRate()).thenReturn(0.00000001f);
510510

511511
RateLimiter limiter =
512-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000005f, mockConfigResolver);
512+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 1, 0.000000005f, mockConfigResolver);
513513

514514
assertThat(limiter.getIsDeviceAllowedToSendFragmentScreenTraces()).isTrue();
515515
}
@@ -520,7 +520,7 @@ public void getIsDeviceAllowedToSendFragmentScreenTraces_8digitSamplingRate_frag
520520
when(mockConfigResolver.getFragmentSamplingRate()).thenReturn(0.00000001f);
521521

522522
RateLimiter limiter =
523-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.000000011f, mockConfigResolver);
523+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0, 0.000000011f, mockConfigResolver);
524524

525525
assertThat(limiter.getIsDeviceAllowedToSendFragmentScreenTraces()).isFalse();
526526
}
@@ -532,7 +532,7 @@ public void testDeviceSampling_bothTracesAndNetworkEnabled() {
532532
when(mockConfigResolver.getNetworkRequestSamplingRate()).thenReturn(0.5f);
533533

534534
RateLimiter limiter =
535-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, mockConfigResolver);
535+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, 0, mockConfigResolver);
536536

537537
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isTrue();
538538
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isTrue();
@@ -545,7 +545,7 @@ public void testDeviceSampling_bothTracesAndNetworkDisabled() {
545545
when(mockConfigResolver.getNetworkRequestSamplingRate()).thenReturn(0.5f);
546546

547547
RateLimiter limiter =
548-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.51f, mockConfigResolver);
548+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.51f, 0, mockConfigResolver);
549549

550550
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isFalse();
551551
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isFalse();
@@ -558,7 +558,7 @@ public void testDeviceSampling_bothTracesAndFragmentEnabled_acceptsFragmentTrace
558558
when(mockConfigResolver.getFragmentSamplingRate()).thenReturn(0.5f);
559559

560560
RateLimiter limiter =
561-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, mockConfigResolver);
561+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.49f, 0.49f, mockConfigResolver);
562562

563563
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isTrue();
564564
assertThat(limiter.getIsDeviceAllowedToSendFragmentScreenTraces()).isTrue();
@@ -581,7 +581,7 @@ public void testDeviceSampling_changeInTraceSamplingRateIsImmediatelyEffective()
581581
when(mockConfigResolver.getTraceSamplingRate()).thenReturn(0.5f);
582582

583583
RateLimiter limiter =
584-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.51f, mockConfigResolver);
584+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.51f, 0, mockConfigResolver);
585585

586586
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isFalse();
587587

@@ -596,7 +596,7 @@ public void testDeviceSampling_changeInNetworkSamplingRateIsImmediatelyEffective
596596
when(mockConfigResolver.getNetworkRequestSamplingRate()).thenReturn(0.5f);
597597

598598
RateLimiter limiter =
599-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.51f, mockConfigResolver);
599+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.51f, 0, mockConfigResolver);
600600

601601
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isFalse();
602602

@@ -611,7 +611,7 @@ public void testDeviceSampling_changeInFragmentSamplingRateIsImmediatelyEffectiv
611611
when(mockConfigResolver.getFragmentSamplingRate()).thenReturn(0.5f);
612612

613613
RateLimiter limiter =
614-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.51f, mockConfigResolver);
614+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0, 0.51f, mockConfigResolver);
615615

616616
assertThat(limiter.getIsDeviceAllowedToSendFragmentScreenTraces()).isFalse();
617617

@@ -793,7 +793,7 @@ public void samplingBucketIdRandomness() {
793793
public void testBackgroundTraceWithCountersIsNotRateLimitApplicable() {
794794
makeConfigResolverReturnDefaultValues();
795795
RateLimiter limiter =
796-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, mockConfigResolver);
796+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, 0.99f, mockConfigResolver);
797797

798798
PerfMetric metric =
799799
PerfMetric.newBuilder()
@@ -810,7 +810,7 @@ public void testBackgroundTraceWithCountersIsNotRateLimitApplicable() {
810810
public void testBackgroundTraceWithoutCountersIsRateLimitApplicable() {
811811
makeConfigResolverReturnDefaultValues();
812812
RateLimiter limiter =
813-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, mockConfigResolver);
813+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, 0.99f, mockConfigResolver);
814814

815815
PerfMetric metric =
816816
PerfMetric.newBuilder()
@@ -826,7 +826,7 @@ public void testBackgroundTraceWithoutCountersIsRateLimitApplicable() {
826826
public void testForegroundTraceWithCountersIsNotRateLimitApplicable() {
827827
makeConfigResolverReturnDefaultValues();
828828
RateLimiter limiter =
829-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, mockConfigResolver);
829+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, 0.99f, mockConfigResolver);
830830

831831
PerfMetric metric =
832832
PerfMetric.newBuilder()
@@ -843,7 +843,7 @@ public void testForegroundTraceWithCountersIsNotRateLimitApplicable() {
843843
public void testForegroundTraceWithoutCountersIsRateLimitApplicable() {
844844
makeConfigResolverReturnDefaultValues();
845845
RateLimiter limiter =
846-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, mockConfigResolver);
846+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, 0.99f, mockConfigResolver);
847847

848848
PerfMetric metric =
849849
PerfMetric.newBuilder()
@@ -858,7 +858,7 @@ public void testForegroundTraceWithoutCountersIsRateLimitApplicable() {
858858
public void testGaugeMetricIsNotRateLimitApplicable() {
859859
makeConfigResolverReturnDefaultValues();
860860
RateLimiter limiter =
861-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, mockConfigResolver);
861+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, 0.99f, mockConfigResolver);
862862

863863
PerfMetric metric =
864864
PerfMetric.newBuilder().setGaugeMetric(GaugeMetric.getDefaultInstance()).build();
@@ -870,7 +870,7 @@ public void testGaugeMetricIsNotRateLimitApplicable() {
870870
public void testTraceMetricNoSpecialNameIsRateLimitApplicable() {
871871
makeConfigResolverReturnDefaultValues();
872872
RateLimiter limiter =
873-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, mockConfigResolver);
873+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, 0.99f, mockConfigResolver);
874874

875875
PerfMetric metric =
876876
PerfMetric.newBuilder()
@@ -884,7 +884,7 @@ public void testTraceMetricNoSpecialNameIsRateLimitApplicable() {
884884
public void testNetworkRequestMetricIsRateLimitApplicable() {
885885
makeConfigResolverReturnDefaultValues();
886886
RateLimiter limiter =
887-
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, mockConfigResolver);
887+
new RateLimiter(TWO_TOKENS_PER_MINUTE, 2, mClock, 0.99f, 0.99f, mockConfigResolver);
888888

889889
PerfMetric metric =
890890
PerfMetric.newBuilder()
@@ -907,6 +907,7 @@ public void testTracesAreNotSampledWhenSessionIsVerboseAndSamplingEnabled() {
907907
/* capacity= */ 2,
908908
mClock,
909909
/* samplingBucketId= */ 0.71f,
910+
/* fragmentBucketId= */ 0,
910911
mockConfigResolver);
911912
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isFalse();
912913

@@ -933,6 +934,7 @@ public void testNetworkRequestsAreNotSampledWhenSessionIsVerboseAndSamplingEnabl
933934
/* capacity= */ 2,
934935
mClock,
935936
/* samplingBucketId= */ 0.71f,
937+
/* fragmentBucketId= */ 0,
936938
mockConfigResolver);
937939
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isFalse();
938940

@@ -958,8 +960,10 @@ public void isEventSampled_verboseSessionEnabledAndDiceRollFailed_returnsTrue()
958960
/* rate= */ TWO_TOKENS_PER_SECOND,
959961
/* capacity= */ 2,
960962
mClock,
961-
/* samplingBucketId= */ 0.71f,
963+
/* samplingBucketId= */ 0,
964+
/* fragmentBucketId= */ 0.71f,
962965
mockConfigResolver);
966+
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isTrue();
963967
assertThat(limiter.getIsDeviceAllowedToSendFragmentScreenTraces()).isFalse();
964968

965969
PerfMetric trace =
@@ -985,6 +989,7 @@ public void testTracesAreSampledWhenSessionIsNonVerboseAndSamplingEnabled() {
985989
/* capacity= */ 2,
986990
mClock,
987991
/* samplingBucketId= */ 0.71f,
992+
/* fragmentBucketId= */ 0,
988993
mockConfigResolver);
989994
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isFalse();
990995

@@ -1011,6 +1016,7 @@ public void testNetworkRequestsAreSampledWhenSessionIsNonVerboseAndSamplingEnabl
10111016
/* capacity= */ 2,
10121017
mClock,
10131018
/* samplingBucketId= */ 0.71f,
1019+
/* fragmentBucketId= */ 0,
10141020
mockConfigResolver);
10151021
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isFalse();
10161022

@@ -1036,8 +1042,10 @@ public void isEventSampled_verboseSessionDisabledAndDiceRollFailed_returnsFalse(
10361042
/* rate= */ TWO_TOKENS_PER_SECOND,
10371043
/* capacity= */ 2,
10381044
mClock,
1039-
/* samplingBucketId= */ 0.71f,
1045+
/* samplingBucketId= */ 0,
1046+
/* fragmentBucketId= */ 0.71f,
10401047
mockConfigResolver);
1048+
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isTrue();
10411049
assertThat(limiter.getIsDeviceAllowedToSendFragmentScreenTraces()).isFalse();
10421050

10431051
PerfMetric trace =
@@ -1064,6 +1072,7 @@ public void testGaugesAreNeverSampled() {
10641072
/* capacity= */ 2,
10651073
mClock,
10661074
/* samplingBucketId= */ 0.71f,
1075+
/* fragmentBucketId= */ 1,
10671076
mockConfigResolver);
10681077
assertThat(limiter.getIsDeviceAllowedToSendTraces()).isFalse();
10691078
assertThat(limiter.getIsDeviceAllowedToSendNetworkEvents()).isFalse();

0 commit comments

Comments
 (0)