1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_BASE_BACKOFF_ITEM_H_ 6 #define NET_BASE_BACKOFF_ITEM_H_ 7 #pragma once 8 9 #include "base/threading/non_thread_safe.h" 10 #include "base/time.h" 11 12 namespace net { 13 14 // Provides the core logic needed for randomized exponential back-off 15 // on requests to a given resource, given a back-off policy. 16 // 17 // This utility class knows nothing about network specifics; it is 18 // intended for reuse in various networking scenarios. 19 class BackoffEntry : public base::NonThreadSafe { 20 public: 21 // The set of parameters that define a back-off policy. 22 struct Policy { 23 // Number of initial errors (in sequence) to ignore before applying 24 // exponential back-off rules. 25 int num_errors_to_ignore; 26 27 // Initial delay for exponential back-off. 28 int initial_backoff_ms; 29 30 // Factor by which the waiting time will be multiplied. 31 double multiply_factor; 32 33 // Fuzzing percentage. ex: 10% will spread requests randomly 34 // between 90%-100% of the calculated time. 35 double jitter_factor; 36 37 // Maximum amount of time we are willing to delay our request. 38 int maximum_backoff_ms; 39 40 // Time to keep an entry from being discarded even when it 41 // has no significant state, -1 to never discard. 42 int entry_lifetime_ms; 43 }; 44 45 // Lifetime of policy must enclose lifetime of BackoffEntry. The 46 // pointer must be valid but is not dereferenced during construction. 47 explicit BackoffEntry(const Policy* const policy); 48 virtual ~BackoffEntry(); 49 50 // Inform this item that a request for the network resource it is 51 // tracking was made, and whether it failed or succeeded. 52 void InformOfRequest(bool succeeded); 53 54 // Returns true if a request for the resource this item tracks should 55 // be rejected at the present time due to exponential back-off policy. 56 bool ShouldRejectRequest() const; 57 58 // Returns the absolute time after which this entry (given its present 59 // state) will no longer reject requests. 60 base::TimeTicks GetReleaseTime() const; 61 62 // Causes this object reject requests until the specified absolute time. 63 // This can be used to e.g. implement support for a Retry-After header. 64 void SetCustomReleaseTime(const base::TimeTicks& release_time); 65 66 // Returns true if this object has no significant state (i.e. you could 67 // just as well start with a fresh BackoffEntry object), and hasn't 68 // had for Policy::entry_lifetime_ms_. 69 bool CanDiscard() const; 70 71 protected: 72 // Equivalent to TimeTicks::Now(), virtual so unit tests can override. 73 // TODO(joi): Switch to constructor-time dependency injection? 74 virtual base::TimeTicks GetTimeNow() const; 75 76 private: 77 // Calculates when requests should again be allowed through. 78 base::TimeTicks CalculateReleaseTime() const; 79 80 // Timestamp calculated by the exponential back-off algorithm at which we are 81 // allowed to start sending requests again. 82 base::TimeTicks exponential_backoff_release_time_; 83 84 // Counts request errors; reset on success. 85 int failure_count_; 86 87 const Policy* const policy_; 88 89 DISALLOW_COPY_AND_ASSIGN(BackoffEntry); 90 }; 91 92 } // namespace net 93 94 #endif // NET_BASE_BACKOFF_ITEM_H_ 95