xref: /aosp_15_r20/external/cronet/net/base/backoff_entry.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef NET_BASE_BACKOFF_ENTRY_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_BASE_BACKOFF_ENTRY_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_checker.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker namespace base {
16*6777b538SAndroid Build Coastguard Worker class TickClock;
17*6777b538SAndroid Build Coastguard Worker }
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker namespace net {
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker // Provides the core logic needed for randomized exponential back-off
22*6777b538SAndroid Build Coastguard Worker // on requests to a given resource, given a back-off policy.
23*6777b538SAndroid Build Coastguard Worker //
24*6777b538SAndroid Build Coastguard Worker // This utility class knows nothing about network specifics; it is
25*6777b538SAndroid Build Coastguard Worker // intended for reuse in various networking scenarios.
26*6777b538SAndroid Build Coastguard Worker class NET_EXPORT BackoffEntry {
27*6777b538SAndroid Build Coastguard Worker  public:
28*6777b538SAndroid Build Coastguard Worker   // The set of parameters that define a back-off policy. When modifying this,
29*6777b538SAndroid Build Coastguard Worker   // increment SERIALIZATION_VERSION_NUMBER in backoff_entry_serializer.cc.
30*6777b538SAndroid Build Coastguard Worker   struct Policy {
31*6777b538SAndroid Build Coastguard Worker     // Number of initial errors (in sequence) to ignore before applying
32*6777b538SAndroid Build Coastguard Worker     // exponential back-off rules.
33*6777b538SAndroid Build Coastguard Worker     int num_errors_to_ignore;
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker     // Initial delay.  The interpretation of this value depends on
36*6777b538SAndroid Build Coastguard Worker     // always_use_initial_delay.  It's either how long we wait between
37*6777b538SAndroid Build Coastguard Worker     // requests before backoff starts, or how much we delay the first request
38*6777b538SAndroid Build Coastguard Worker     // after backoff starts.
39*6777b538SAndroid Build Coastguard Worker     int initial_delay_ms;
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker     // Factor by which the waiting time will be multiplied.
42*6777b538SAndroid Build Coastguard Worker     double multiply_factor;
43*6777b538SAndroid Build Coastguard Worker 
44*6777b538SAndroid Build Coastguard Worker     // Fuzzing percentage. ex: 10% will spread requests randomly
45*6777b538SAndroid Build Coastguard Worker     // between 90%-100% of the calculated time.
46*6777b538SAndroid Build Coastguard Worker     double jitter_factor;
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker     // Maximum amount of time we are willing to delay our request, -1
49*6777b538SAndroid Build Coastguard Worker     // for no maximum.
50*6777b538SAndroid Build Coastguard Worker     int64_t maximum_backoff_ms;
51*6777b538SAndroid Build Coastguard Worker 
52*6777b538SAndroid Build Coastguard Worker     // Time to keep an entry from being discarded even when it
53*6777b538SAndroid Build Coastguard Worker     // has no significant state, -1 to never discard.
54*6777b538SAndroid Build Coastguard Worker     int64_t entry_lifetime_ms;
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker     // If true, we always use a delay of initial_delay_ms, even before
57*6777b538SAndroid Build Coastguard Worker     // we've seen num_errors_to_ignore errors.  Otherwise, initial_delay_ms
58*6777b538SAndroid Build Coastguard Worker     // is the first delay once we start exponential backoff.
59*6777b538SAndroid Build Coastguard Worker     //
60*6777b538SAndroid Build Coastguard Worker     // So if we're ignoring 1 error, we'll see (N, N, Nm, Nm^2, ...) if true,
61*6777b538SAndroid Build Coastguard Worker     // and (0, 0, N, Nm, ...) when false, where N is initial_backoff_ms and
62*6777b538SAndroid Build Coastguard Worker     // m is multiply_factor, assuming we've already seen one success.
63*6777b538SAndroid Build Coastguard Worker     bool always_use_initial_delay;
64*6777b538SAndroid Build Coastguard Worker   };
65*6777b538SAndroid Build Coastguard Worker 
66*6777b538SAndroid Build Coastguard Worker   // Lifetime of policy must enclose lifetime of BackoffEntry. The
67*6777b538SAndroid Build Coastguard Worker   // pointer must be valid but is not dereferenced during construction.
68*6777b538SAndroid Build Coastguard Worker   explicit BackoffEntry(const Policy* policy);
69*6777b538SAndroid Build Coastguard Worker   // Lifetime of policy and clock must enclose lifetime of BackoffEntry.
70*6777b538SAndroid Build Coastguard Worker   // |policy| pointer must be valid but isn't dereferenced during construction.
71*6777b538SAndroid Build Coastguard Worker   // |clock| pointer may be null.
72*6777b538SAndroid Build Coastguard Worker   BackoffEntry(const Policy* policy, const base::TickClock* clock);
73*6777b538SAndroid Build Coastguard Worker   BackoffEntry(const BackoffEntry&) = delete;
74*6777b538SAndroid Build Coastguard Worker   BackoffEntry& operator=(const BackoffEntry&) = delete;
75*6777b538SAndroid Build Coastguard Worker   virtual ~BackoffEntry();
76*6777b538SAndroid Build Coastguard Worker 
77*6777b538SAndroid Build Coastguard Worker   // Inform this item that a request for the network resource it is
78*6777b538SAndroid Build Coastguard Worker   // tracking was made, and whether it failed or succeeded.
79*6777b538SAndroid Build Coastguard Worker   void InformOfRequest(bool succeeded);
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker   // Returns true if a request for the resource this item tracks should
82*6777b538SAndroid Build Coastguard Worker   // be rejected at the present time due to exponential back-off policy.
83*6777b538SAndroid Build Coastguard Worker   bool ShouldRejectRequest() const;
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker   // Returns the absolute time after which this entry (given its present
86*6777b538SAndroid Build Coastguard Worker   // state) will no longer reject requests.
87*6777b538SAndroid Build Coastguard Worker   base::TimeTicks GetReleaseTime() const;
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker   // Returns the time until a request can be sent (will be zero if the release
90*6777b538SAndroid Build Coastguard Worker   // time is in the past).
91*6777b538SAndroid Build Coastguard Worker   base::TimeDelta GetTimeUntilRelease() const;
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker   // Converts |backoff_duration| to a release time, by adding it to
94*6777b538SAndroid Build Coastguard Worker   // GetTimeTicksNow(), limited by maximum_backoff_ms.
95*6777b538SAndroid Build Coastguard Worker   base::TimeTicks BackoffDurationToReleaseTime(
96*6777b538SAndroid Build Coastguard Worker       base::TimeDelta backoff_duration) const;
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker   // Causes this object reject requests until the specified absolute time.
99*6777b538SAndroid Build Coastguard Worker   // This can be used to e.g. implement support for a Retry-After header.
100*6777b538SAndroid Build Coastguard Worker   void SetCustomReleaseTime(const base::TimeTicks& release_time);
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker   // Returns true if this object has no significant state (i.e. you could
103*6777b538SAndroid Build Coastguard Worker   // just as well start with a fresh BackoffEntry object), and hasn't
104*6777b538SAndroid Build Coastguard Worker   // had for Policy::entry_lifetime_ms.
105*6777b538SAndroid Build Coastguard Worker   bool CanDiscard() const;
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   // Resets this entry to a fresh (as if just constructed) state.
108*6777b538SAndroid Build Coastguard Worker   void Reset();
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker   // Returns the failure count for this entry.
failure_count()111*6777b538SAndroid Build Coastguard Worker   int failure_count() const { return failure_count_; }
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker   // Equivalent to TimeTicks::Now(), using clock_ if provided.
114*6777b538SAndroid Build Coastguard Worker   base::TimeTicks GetTimeTicksNow() const;
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker  private:
117*6777b538SAndroid Build Coastguard Worker   // Calculates when requests should again be allowed through.
118*6777b538SAndroid Build Coastguard Worker   base::TimeTicks CalculateReleaseTime() const;
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker   // Timestamp calculated by the exponential back-off algorithm at which we are
121*6777b538SAndroid Build Coastguard Worker   // allowed to start sending requests again.
122*6777b538SAndroid Build Coastguard Worker   base::TimeTicks exponential_backoff_release_time_;
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker   // Counts request errors; decremented on success.
125*6777b538SAndroid Build Coastguard Worker   int failure_count_;
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker   const raw_ptr<const Policy> policy_;  // Not owned.
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker   const raw_ptr<const base::TickClock> clock_;  // Not owned.
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker   THREAD_CHECKER(thread_checker_);
132*6777b538SAndroid Build Coastguard Worker };
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker }  // namespace net
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker #endif  // NET_BASE_BACKOFF_ENTRY_H_
137