OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/url_request/url_request_throttler_entry.h" | 5 #include "net/url_request/url_request_throttler_entry.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 DCHECK_GE(initial_backoff_ms_, 0); | 58 DCHECK_GE(initial_backoff_ms_, 0); |
59 DCHECK_GE(additional_constant_ms_, 0); | 59 DCHECK_GE(additional_constant_ms_, 0); |
60 DCHECK_GT(multiply_factor_, 0); | 60 DCHECK_GT(multiply_factor_, 0); |
61 DCHECK_GE(jitter_factor_, 0); | 61 DCHECK_GE(jitter_factor_, 0); |
62 DCHECK_LT(jitter_factor_, 1); | 62 DCHECK_LT(jitter_factor_, 1); |
63 DCHECK_GE(maximum_backoff_ms_, 0); | 63 DCHECK_GE(maximum_backoff_ms_, 0); |
64 | 64 |
65 Initialize(); | 65 Initialize(); |
66 } | 66 } |
67 | 67 |
68 URLRequestThrottlerEntry::~URLRequestThrottlerEntry() { | 68 bool URLRequestThrottlerEntry::IsEntryOutdated() const { |
69 } | 69 if (entry_lifetime_ms_ == -1) |
| 70 return false; |
70 | 71 |
71 void URLRequestThrottlerEntry::Initialize() { | 72 base::TimeTicks now = GetTimeNow(); |
72 // Since this method is called by the constructors, GetTimeNow() (a virtual | |
73 // method) is not used. | |
74 exponential_backoff_release_time_ = base::TimeTicks::Now(); | |
75 failure_count_ = 0; | |
76 latest_response_was_failure_ = false; | |
77 | 73 |
78 sliding_window_release_time_ = base::TimeTicks::Now(); | 74 // If there are send events in the sliding window period, we still need this |
| 75 // entry. |
| 76 if (send_log_.size() > 0 && |
| 77 send_log_.back() + sliding_window_period_ > now) { |
| 78 return false; |
| 79 } |
| 80 |
| 81 int64 unused_since_ms = |
| 82 (now - exponential_backoff_release_time_).InMilliseconds(); |
| 83 |
| 84 // Release time is further than now, we are managing it. |
| 85 if (unused_since_ms < 0) |
| 86 return false; |
| 87 |
| 88 // latest_response_was_failure_ is true indicates that the latest one or |
| 89 // more requests encountered server errors or had malformed response bodies. |
| 90 // In that case, we don't want to collect the entry unless it hasn't been used |
| 91 // for longer than the maximum allowed back-off. |
| 92 if (latest_response_was_failure_) |
| 93 return unused_since_ms > std::max(maximum_backoff_ms_, entry_lifetime_ms_); |
| 94 |
| 95 // Otherwise, consider the entry is outdated if it hasn't been used for the |
| 96 // specified lifetime period. |
| 97 return unused_since_ms > entry_lifetime_ms_; |
79 } | 98 } |
80 | 99 |
81 bool URLRequestThrottlerEntry::IsDuringExponentialBackoff() const { | 100 bool URLRequestThrottlerEntry::IsDuringExponentialBackoff() const { |
82 return exponential_backoff_release_time_ > GetTimeNow(); | 101 return exponential_backoff_release_time_ > GetTimeNow(); |
83 } | 102 } |
84 | 103 |
85 int64 URLRequestThrottlerEntry::ReserveSendingTimeForNextRequest( | 104 int64 URLRequestThrottlerEntry::ReserveSendingTimeForNextRequest( |
86 const base::TimeTicks& earliest_time) { | 105 const base::TimeTicks& earliest_time) { |
87 base::TimeTicks now = GetTimeNow(); | 106 base::TimeTicks now = GetTimeNow(); |
88 // If a lot of requests were successfully made recently, | 107 // If a lot of requests were successfully made recently, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 // will then need to wait the delay caused by the 2 failures. | 165 // will then need to wait the delay caused by the 2 failures. |
147 exponential_backoff_release_time_ = std::max( | 166 exponential_backoff_release_time_ = std::max( |
148 GetTimeNow(), exponential_backoff_release_time_); | 167 GetTimeNow(), exponential_backoff_release_time_); |
149 | 168 |
150 std::string retry_header = response->GetNormalizedValue(kRetryHeaderName); | 169 std::string retry_header = response->GetNormalizedValue(kRetryHeaderName); |
151 if (!retry_header.empty()) | 170 if (!retry_header.empty()) |
152 HandleCustomRetryAfter(retry_header); | 171 HandleCustomRetryAfter(retry_header); |
153 } | 172 } |
154 } | 173 } |
155 | 174 |
156 bool URLRequestThrottlerEntry::IsEntryOutdated() const { | |
157 if (entry_lifetime_ms_ == -1) | |
158 return false; | |
159 | |
160 base::TimeTicks now = GetTimeNow(); | |
161 | |
162 // If there are send events in the sliding window period, we still need this | |
163 // entry. | |
164 if (send_log_.size() > 0 && | |
165 send_log_.back() + sliding_window_period_ > now) { | |
166 return false; | |
167 } | |
168 | |
169 int64 unused_since_ms = | |
170 (now - exponential_backoff_release_time_).InMilliseconds(); | |
171 | |
172 // Release time is further than now, we are managing it. | |
173 if (unused_since_ms < 0) | |
174 return false; | |
175 | |
176 // latest_response_was_failure_ is true indicates that the latest one or | |
177 // more requests encountered server errors or had malformed response bodies. | |
178 // In that case, we don't want to collect the entry unless it hasn't been used | |
179 // for longer than the maximum allowed back-off. | |
180 if (latest_response_was_failure_) | |
181 return unused_since_ms > std::max(maximum_backoff_ms_, entry_lifetime_ms_); | |
182 | |
183 // Otherwise, consider the entry is outdated if it hasn't been used for the | |
184 // specified lifetime period. | |
185 return unused_since_ms > entry_lifetime_ms_; | |
186 } | |
187 | |
188 void URLRequestThrottlerEntry::ReceivedContentWasMalformed() { | 175 void URLRequestThrottlerEntry::ReceivedContentWasMalformed() { |
189 // For any response that is marked as malformed now, we have probably | 176 // For any response that is marked as malformed now, we have probably |
190 // considered it as a success when receiving it and decreased the failure | 177 // considered it as a success when receiving it and decreased the failure |
191 // count by 1. As a result, we increase the failure count by 2 here to undo | 178 // count by 1. As a result, we increase the failure count by 2 here to undo |
192 // the effect and record a failure. | 179 // the effect and record a failure. |
193 // | 180 // |
194 // Please note that this may lead to a larger failure count than expected, | 181 // Please note that this may lead to a larger failure count than expected, |
195 // because we don't decrease the failure count for successful responses when | 182 // because we don't decrease the failure count for successful responses when |
196 // it has already reached 0. | 183 // it has already reached 0. |
197 failure_count_ += 2; | 184 failure_count_ += 2; |
198 latest_response_was_failure_ = true; | 185 latest_response_was_failure_ = true; |
199 exponential_backoff_release_time_ = CalculateExponentialBackoffReleaseTime(); | 186 exponential_backoff_release_time_ = CalculateExponentialBackoffReleaseTime(); |
200 } | 187 } |
201 | 188 |
| 189 URLRequestThrottlerEntry::~URLRequestThrottlerEntry() { |
| 190 } |
| 191 |
| 192 void URLRequestThrottlerEntry::Initialize() { |
| 193 // Since this method is called by the constructors, GetTimeNow() (a virtual |
| 194 // method) is not used. |
| 195 exponential_backoff_release_time_ = base::TimeTicks::Now(); |
| 196 failure_count_ = 0; |
| 197 latest_response_was_failure_ = false; |
| 198 |
| 199 sliding_window_release_time_ = base::TimeTicks::Now(); |
| 200 } |
| 201 |
202 base::TimeTicks | 202 base::TimeTicks |
203 URLRequestThrottlerEntry::CalculateExponentialBackoffReleaseTime() { | 203 URLRequestThrottlerEntry::CalculateExponentialBackoffReleaseTime() { |
204 double delay = initial_backoff_ms_; | 204 double delay = initial_backoff_ms_; |
205 delay *= pow(multiply_factor_, failure_count_); | 205 delay *= pow(multiply_factor_, failure_count_); |
206 delay += additional_constant_ms_; | 206 delay += additional_constant_ms_; |
207 delay -= base::RandDouble() * jitter_factor_ * delay; | 207 delay -= base::RandDouble() * jitter_factor_ * delay; |
208 | 208 |
209 // Ensure that we do not exceed maximum delay. | 209 // Ensure that we do not exceed maximum delay. |
210 int64 delay_int = static_cast<int64>(delay + 0.5); | 210 int64 delay_int = static_cast<int64>(delay + 0.5); |
211 delay_int = std::min(delay_int, static_cast<int64>(maximum_backoff_ms_)); | 211 delay_int = std::min(delay_int, static_cast<int64>(maximum_backoff_ms_)); |
(...skipping 21 matching lines...) Expand all Loading... |
233 | 233 |
234 if (maximum_backoff_ms_ < value_ms || value_ms < 0) | 234 if (maximum_backoff_ms_ < value_ms || value_ms < 0) |
235 return; | 235 return; |
236 | 236 |
237 exponential_backoff_release_time_ = std::max( | 237 exponential_backoff_release_time_ = std::max( |
238 (GetTimeNow() + base::TimeDelta::FromMilliseconds(value_ms)), | 238 (GetTimeNow() + base::TimeDelta::FromMilliseconds(value_ms)), |
239 exponential_backoff_release_time_); | 239 exponential_backoff_release_time_); |
240 } | 240 } |
241 | 241 |
242 } // namespace net | 242 } // namespace net |
OLD | NEW |