| 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 |