• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.net.telemetry;
6 
7 import android.os.SystemClock;
8 
9 /**
10  * This allows us to do ratelimiting based on the time difference between the last log action and
11  * the current log action. This class allows us to specify the number of samples/second we want for
12  * each request.
13  */
14 public final class RateLimiter {
15     private static final long ONE_SECOND_MILLIS = 1000L;
16 
17     private final Object mLock = new Object();
18     // The last tracked time
19     private final int mSamplesPerSeconds;
20     private int mSamplesLoggedDuringSecond;
21     private long mLastPermitMillis = Long.MIN_VALUE;
22 
RateLimiter(int samplesPerSeconds)23     public RateLimiter(int samplesPerSeconds) {
24         if (samplesPerSeconds <= 0) {
25             throw new IllegalArgumentException("Expect sample rate to be > 0 sample(s) per second");
26         }
27 
28         this.mSamplesPerSeconds = samplesPerSeconds;
29     }
30 
31     // Check if rate limiting should happen based on a time passed or sample rate.
tryAcquire()32     public boolean tryAcquire() {
33         synchronized (mLock) {
34             long currentMillis = SystemClock.elapsedRealtime();
35 
36             if (mLastPermitMillis + ONE_SECOND_MILLIS <= currentMillis) {
37                 // reset samplesLoggedDuringSecond and stopwatch once a second has passed
38                 mSamplesLoggedDuringSecond = 1;
39                 mLastPermitMillis = currentMillis;
40                 return true;
41             } else if (mSamplesLoggedDuringSecond < mSamplesPerSeconds) {
42                 mSamplesLoggedDuringSecond++;
43                 return true;
44             }
45             return false;
46         }
47     }
48 }
49