1*1a96fba6SXin Li // Copyright 2015 The Chromium OS Authors. All rights reserved. 2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be 3*1a96fba6SXin Li // found in the LICENSE file. 4*1a96fba6SXin Li 5*1a96fba6SXin Li #ifndef LIBBRILLO_BRILLO_BACKOFF_ENTRY_H_ 6*1a96fba6SXin Li #define LIBBRILLO_BRILLO_BACKOFF_ENTRY_H_ 7*1a96fba6SXin Li 8*1a96fba6SXin Li #include <base/time/time.h> 9*1a96fba6SXin Li #include <brillo/brillo_export.h> 10*1a96fba6SXin Li 11*1a96fba6SXin Li namespace brillo { 12*1a96fba6SXin Li 13*1a96fba6SXin Li // Provides the core logic needed for randomized exponential back-off 14*1a96fba6SXin Li // on requests to a given resource, given a back-off policy. 15*1a96fba6SXin Li // 16*1a96fba6SXin Li // This class is largely taken from net/base/backoff_entry.h from Chromium. 17*1a96fba6SXin Li // TODO(avakulenko): Consider packaging portions of Chrome's //net functionality 18*1a96fba6SXin Li // into the current libchrome library. 19*1a96fba6SXin Li class BRILLO_EXPORT BackoffEntry { 20*1a96fba6SXin Li public: 21*1a96fba6SXin Li // The set of parameters that define a back-off policy. 22*1a96fba6SXin Li struct Policy { 23*1a96fba6SXin Li // Number of initial errors (in sequence) to ignore before applying 24*1a96fba6SXin Li // exponential back-off rules. 25*1a96fba6SXin Li int num_errors_to_ignore; 26*1a96fba6SXin Li 27*1a96fba6SXin Li // Initial delay. The interpretation of this value depends on 28*1a96fba6SXin Li // always_use_initial_delay. It's either how long we wait between 29*1a96fba6SXin Li // requests before backoff starts, or how much we delay the first request 30*1a96fba6SXin Li // after backoff starts. 31*1a96fba6SXin Li int initial_delay_ms; 32*1a96fba6SXin Li 33*1a96fba6SXin Li // Factor by which the waiting time will be multiplied. 34*1a96fba6SXin Li double multiply_factor; 35*1a96fba6SXin Li 36*1a96fba6SXin Li // Fuzzing percentage. ex: 10% will spread requests randomly 37*1a96fba6SXin Li // between 90%-100% of the calculated time. 38*1a96fba6SXin Li double jitter_factor; 39*1a96fba6SXin Li 40*1a96fba6SXin Li // Maximum amount of time we are willing to delay our request, -1 41*1a96fba6SXin Li // for no maximum. 42*1a96fba6SXin Li int64_t maximum_backoff_ms; 43*1a96fba6SXin Li 44*1a96fba6SXin Li // Time to keep an entry from being discarded even when it 45*1a96fba6SXin Li // has no significant state, -1 to never discard. 46*1a96fba6SXin Li int64_t entry_lifetime_ms; 47*1a96fba6SXin Li 48*1a96fba6SXin Li // If true, we always use a delay of initial_delay_ms, even before 49*1a96fba6SXin Li // we've seen num_errors_to_ignore errors. Otherwise, initial_delay_ms 50*1a96fba6SXin Li // is the first delay once we start exponential backoff. 51*1a96fba6SXin Li // 52*1a96fba6SXin Li // So if we're ignoring 1 error, we'll see (N, N, Nm, Nm^2, ...) if true, 53*1a96fba6SXin Li // and (0, 0, N, Nm, ...) when false, where N is initial_backoff_ms and 54*1a96fba6SXin Li // m is multiply_factor, assuming we've already seen one success. 55*1a96fba6SXin Li bool always_use_initial_delay; 56*1a96fba6SXin Li }; 57*1a96fba6SXin Li 58*1a96fba6SXin Li // Lifetime of policy must enclose lifetime of BackoffEntry. The 59*1a96fba6SXin Li // pointer must be valid but is not dereferenced during construction. 60*1a96fba6SXin Li explicit BackoffEntry(const Policy* const policy); 61*1a96fba6SXin Li virtual ~BackoffEntry() = default; 62*1a96fba6SXin Li 63*1a96fba6SXin Li // Inform this item that a request for the network resource it is 64*1a96fba6SXin Li // tracking was made, and whether it failed or succeeded. 65*1a96fba6SXin Li void InformOfRequest(bool succeeded); 66*1a96fba6SXin Li 67*1a96fba6SXin Li // Returns true if a request for the resource this item tracks should 68*1a96fba6SXin Li // be rejected at the present time due to exponential back-off policy. 69*1a96fba6SXin Li bool ShouldRejectRequest() const; 70*1a96fba6SXin Li 71*1a96fba6SXin Li // Returns the absolute time after which this entry (given its present 72*1a96fba6SXin Li // state) will no longer reject requests. 73*1a96fba6SXin Li base::TimeTicks GetReleaseTime() const; 74*1a96fba6SXin Li 75*1a96fba6SXin Li // Returns the time until a request can be sent. 76*1a96fba6SXin Li base::TimeDelta GetTimeUntilRelease() const; 77*1a96fba6SXin Li 78*1a96fba6SXin Li // Causes this object reject requests until the specified absolute time. 79*1a96fba6SXin Li // This can be used to e.g. implement support for a Retry-After header. 80*1a96fba6SXin Li void SetCustomReleaseTime(const base::TimeTicks& release_time); 81*1a96fba6SXin Li 82*1a96fba6SXin Li // Returns true if this object has no significant state (i.e. you could 83*1a96fba6SXin Li // just as well start with a fresh BackoffEntry object), and hasn't 84*1a96fba6SXin Li // had for Policy::entry_lifetime_ms. 85*1a96fba6SXin Li bool CanDiscard() const; 86*1a96fba6SXin Li 87*1a96fba6SXin Li // Resets this entry to a fresh (as if just constructed) state. 88*1a96fba6SXin Li void Reset(); 89*1a96fba6SXin Li 90*1a96fba6SXin Li // Returns the failure count for this entry. failure_count()91*1a96fba6SXin Li int failure_count() const { return failure_count_; } 92*1a96fba6SXin Li 93*1a96fba6SXin Li protected: 94*1a96fba6SXin Li // Equivalent to TimeTicks::Now(), virtual so unit tests can override. 95*1a96fba6SXin Li virtual base::TimeTicks ImplGetTimeNow() const; 96*1a96fba6SXin Li 97*1a96fba6SXin Li private: 98*1a96fba6SXin Li // Calculates when requests should again be allowed through. 99*1a96fba6SXin Li base::TimeTicks CalculateReleaseTime() const; 100*1a96fba6SXin Li 101*1a96fba6SXin Li // Timestamp calculated by the exponential back-off algorithm at which we are 102*1a96fba6SXin Li // allowed to start sending requests again. 103*1a96fba6SXin Li base::TimeTicks exponential_backoff_release_time_; 104*1a96fba6SXin Li 105*1a96fba6SXin Li // Counts request errors; decremented on success. 106*1a96fba6SXin Li int failure_count_; 107*1a96fba6SXin Li 108*1a96fba6SXin Li const Policy* const policy_; 109*1a96fba6SXin Li 110*1a96fba6SXin Li DISALLOW_COPY_AND_ASSIGN(BackoffEntry); 111*1a96fba6SXin Li }; 112*1a96fba6SXin Li 113*1a96fba6SXin Li } // namespace brillo 114*1a96fba6SXin Li 115*1a96fba6SXin Li #endif // LIBBRILLO_BRILLO_BACKOFF_ENTRY_H_ 116