url_request_throttler_entry.h revision 201ade2fbba22bfb27ae029f4d23fca6ded109a0
13ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// Copyright (c) 2010 The Chromium Authors. All rights reserved. 23ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// Use of this source code is governed by a BSD-style license that can be 33ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// found in the LICENSE file. 43ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru 53ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru#ifndef NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_ 63ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru#define NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_ 73ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru 83ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru#include <queue> 93ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru#include <string> 103ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru 113ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru#include "base/basictypes.h" 123ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru#include "net/url_request/url_request_throttler_entry_interface.h" 133ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru 143ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Querunamespace net { 153ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru 163ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// URLRequestThrottlerEntry represents an entry of URLRequestThrottlerManager. 173ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// It analyzes requests of a specific URL over some period of time, in order to 183ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// deduce the back-off time for every request. 193ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// The back-off algorithm consists of two parts. Firstly, exponential back-off 203ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// is used when receiving 5XX server errors or malformed response bodies. 213ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// The exponential back-off rule is enforced by URLRequestHttpJob. Any request 223ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// sent during the back-off period will be cancelled. 233ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// Secondly, a sliding window is used to count recent requests to a given 243ece7d9e08052989401e008bc397dbcd2557cfd0Jean-Baptiste Queru// destination and provide guidance (to the application level only) on whether 25// too many requests have been sent and when a good time to send the next one 26// would be. This is never used to deny requests at the network level. 27class URLRequestThrottlerEntry : public URLRequestThrottlerEntryInterface { 28 public: 29 // Sliding window period. 30 static const int kDefaultSlidingWindowPeriodMs; 31 32 // Maximum number of requests allowed in sliding window period. 33 static const int kDefaultMaxSendThreshold; 34 35 // Initial delay for exponential back-off. 36 static const int kDefaultInitialBackoffMs; 37 38 // Additional constant to adjust back-off. 39 static const int kDefaultAdditionalConstantMs; 40 41 // Factor by which the waiting time will be multiplied. 42 static const double kDefaultMultiplyFactor; 43 44 // Fuzzing percentage. ex: 10% will spread requests randomly 45 // between 90%-100% of the calculated time. 46 static const double kDefaultJitterFactor; 47 48 // Maximum amount of time we are willing to delay our request. 49 static const int kDefaultMaximumBackoffMs; 50 51 // Time after which the entry is considered outdated. 52 static const int kDefaultEntryLifetimeMs; 53 54 // Name of the header that servers can use to ask clients to delay their next 55 // request. 56 static const char kRetryHeaderName[]; 57 58 URLRequestThrottlerEntry(); 59 60 // The life span of instances created with this constructor is set to 61 // infinite. 62 // It is only used by unit tests. 63 URLRequestThrottlerEntry(int sliding_window_period_ms, 64 int max_send_threshold, 65 int initial_backoff_ms, 66 int additional_constant_ms, 67 double multiply_factor, 68 double jitter_factor, 69 int maximum_backoff_ms); 70 71 // Implementation of URLRequestThrottlerEntryInterface. 72 virtual bool IsDuringExponentialBackoff() const; 73 virtual int64 ReserveSendingTimeForNextRequest( 74 const base::TimeTicks& earliest_time); 75 virtual base::TimeTicks GetExponentialBackoffReleaseTime() const; 76 virtual void UpdateWithResponse( 77 const URLRequestThrottlerHeaderInterface* response); 78 virtual void ReceivedContentWasMalformed(); 79 80 // Used by the manager, returns true if the entry needs to be garbage 81 // collected. 82 bool IsEntryOutdated() const; 83 84 protected: 85 virtual ~URLRequestThrottlerEntry(); 86 87 void Initialize(); 88 89 // Calculates the release time for exponential back-off. 90 base::TimeTicks CalculateExponentialBackoffReleaseTime(); 91 92 // Equivalent to TimeTicks::Now(), virtual to be mockable for testing purpose. 93 virtual base::TimeTicks GetTimeNow() const; 94 95 // Used internally to increase release time following a retry-after header. 96 void HandleCustomRetryAfter(const std::string& header_value); 97 98 // Used by tests. 99 void set_exponential_backoff_release_time( 100 const base::TimeTicks& release_time) { 101 exponential_backoff_release_time_ = release_time; 102 } 103 104 // Used by tests. 105 base::TimeTicks sliding_window_release_time() const { 106 return sliding_window_release_time_; 107 } 108 109 // Used by tests. 110 void set_sliding_window_release_time(const base::TimeTicks& release_time) { 111 sliding_window_release_time_ = release_time; 112 } 113 114 // Used by tests. 115 void set_failure_count(int failure_count) { 116 failure_count_ = failure_count; 117 } 118 119 private: 120 // Timestamp calculated by the exponential back-off algorithm at which we are 121 // allowed to start sending requests again. 122 base::TimeTicks exponential_backoff_release_time_; 123 124 // Number of times we encounter server errors or malformed response bodies. 125 int failure_count_; 126 127 // If true, the last request response was a failure. 128 // Note that this member can be false at the same time as failure_count_ can 129 // be greater than 0, since we gradually decrease failure_count_, instead of 130 // resetting it to 0 directly, when we receive successful responses. 131 bool latest_response_was_failure_; 132 133 // Timestamp calculated by the sliding window algorithm for when we advise 134 // clients the next request should be made, at the earliest. Advisory only, 135 // not used to deny requests. 136 base::TimeTicks sliding_window_release_time_; 137 138 // A list of the recent send events. We use them to decide whether there are 139 // too many requests sent in sliding window. 140 std::queue<base::TimeTicks> send_log_; 141 142 const base::TimeDelta sliding_window_period_; 143 const int max_send_threshold_; 144 const int initial_backoff_ms_; 145 const int additional_constant_ms_; 146 const double multiply_factor_; 147 const double jitter_factor_; 148 const int maximum_backoff_ms_; 149 // Set to -1 if the entry never expires. 150 const int entry_lifetime_ms_; 151 152 DISALLOW_COPY_AND_ASSIGN(URLRequestThrottlerEntry); 153}; 154 155} // namespace net 156 157#endif // NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_ 158