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