Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: chrome/common/net/url_fetcher_protect.cc

Issue 4194001: Implement exponential back-off mechanism and enforce it at the URLRequestHttpJob level. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/common/net/url_fetcher_protect.h ('k') | chrome/common/net/url_fetcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 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 #include "chrome/common/net/url_fetcher_protect.h"
6
7 #include "base/logging.h"
8
9 // URLFetcherProtectEntry ----------------------------------------------------
10
11 using base::TimeDelta;
12 using base::TimeTicks;
13
14 // Default parameters. Time is in milliseconds.
15 // static
16 const int URLFetcherProtectEntry::kDefaultSlidingWindowPeriod = 2000;
17
18 const int URLFetcherProtectEntry::kDefaultMaxSendThreshold = 20;
19 const int URLFetcherProtectEntry::kDefaultMaxRetries = 0;
20
21 const int URLFetcherProtectEntry::kDefaultInitialTimeout = 100;
22 const double URLFetcherProtectEntry::kDefaultMultiplier = 2.0;
23 const int URLFetcherProtectEntry::kDefaultConstantFactor = 100;
24 const int URLFetcherProtectEntry::kDefaultMaximumTimeout = 60000;
25
26
27 URLFetcherProtectEntry::URLFetcherProtectEntry()
28 : sliding_window_period_(kDefaultSlidingWindowPeriod),
29 max_send_threshold_(kDefaultMaxSendThreshold),
30 max_retries_(kDefaultMaxRetries),
31 initial_timeout_(kDefaultInitialTimeout),
32 multiplier_(kDefaultMultiplier),
33 constant_factor_(kDefaultConstantFactor),
34 maximum_timeout_(kDefaultMaximumTimeout) {
35 ResetBackoff();
36 }
37
38 URLFetcherProtectEntry::URLFetcherProtectEntry(int sliding_window_period,
39 int max_send_threshold,
40 int max_retries,
41 int initial_timeout,
42 double multiplier,
43 int constant_factor,
44 int maximum_timeout)
45 : sliding_window_period_(sliding_window_period),
46 max_send_threshold_(max_send_threshold),
47 max_retries_(max_retries),
48 initial_timeout_(initial_timeout),
49 multiplier_(multiplier),
50 constant_factor_(constant_factor),
51 maximum_timeout_(maximum_timeout) {
52 ResetBackoff();
53 }
54
55 URLFetcherProtectEntry::~URLFetcherProtectEntry() {}
56
57 int64 URLFetcherProtectEntry::UpdateBackoff(EventType event_type) {
58 // request may be sent in different threads
59 AutoLock lock(lock_);
60
61 TimeDelta t;
62 switch (event_type) {
63 case SEND:
64 t = AntiOverload();
65 break;
66 case SUCCESS:
67 t = ResetBackoff();
68 break;
69 case FAILURE:
70 t = IncreaseBackoff();
71 break;
72 default:
73 NOTREACHED();
74 }
75
76 int64 wait = t.InMilliseconds();
77 DCHECK(wait >= 0);
78 return wait;
79 }
80
81 TimeDelta URLFetcherProtectEntry::AntiOverload() {
82 TimeDelta sw = TimeDelta::FromMilliseconds(sliding_window_period_);
83 TimeTicks now = TimeTicks::Now();
84 // Estimate when the next request will be sent.
85 release_time_ = now;
86 if (send_log_.size() > 0) {
87 release_time_ = std::max(release_time_, send_log_.back());
88 }
89 // Checks if there are too many send events in recent time.
90 if (send_log_.size() >= static_cast<unsigned>(max_send_threshold_)) {
91 release_time_ = std::max(release_time_, send_log_.front() + sw);
92 }
93 // Logs the new send event.
94 send_log_.push(release_time_);
95 // Drops the out-of-date events in the event list.
96 while (!send_log_.empty() &&
97 (send_log_.front() + sw <= send_log_.back())) {
98 send_log_.pop();
99 }
100 return release_time_ - now;
101 }
102
103 TimeDelta URLFetcherProtectEntry::ResetBackoff() {
104 timeout_period_ = initial_timeout_;
105 release_time_ = TimeTicks::Now();
106 return TimeDelta::FromMilliseconds(0);
107 }
108
109 TimeDelta URLFetcherProtectEntry::IncreaseBackoff() {
110 TimeTicks now = TimeTicks::Now();
111
112 release_time_ = std::max(release_time_, now) +
113 TimeDelta::FromMilliseconds(timeout_period_);
114
115 // Calculates the new backoff time.
116 timeout_period_ = static_cast<int>
117 (multiplier_ * timeout_period_ + constant_factor_);
118 if (maximum_timeout_ && timeout_period_ > maximum_timeout_)
119 timeout_period_ = maximum_timeout_;
120
121 return release_time_ - now;
122 }
123
124 // URLFetcherProtectManager --------------------------------------------------
125
126 // static
127 scoped_ptr<URLFetcherProtectManager> URLFetcherProtectManager::protect_manager_;
128 Lock URLFetcherProtectManager::lock_;
129
130 URLFetcherProtectManager::~URLFetcherProtectManager() {
131 // Deletes all entries
132 ProtectService::iterator i;
133 for (i = services_.begin(); i != services_.end(); ++i) {
134 if (i->second)
135 delete i->second;
136 }
137 }
138
139 // static
140 URLFetcherProtectManager* URLFetcherProtectManager::GetInstance() {
141 AutoLock lock(lock_);
142
143 if (protect_manager_.get() == NULL) {
144 protect_manager_.reset(new URLFetcherProtectManager());
145 }
146 return protect_manager_.get();
147 }
148
149 URLFetcherProtectEntry* URLFetcherProtectManager::Register(
150 const std::string& id) {
151 AutoLock lock(lock_);
152
153 ProtectService::iterator i = services_.find(id);
154
155 if (i != services_.end()) {
156 // The entry exists.
157 return i->second;
158 }
159
160 // Creates a new entry.
161 URLFetcherProtectEntry* entry = new URLFetcherProtectEntry();
162 services_[id] = entry;
163 return entry;
164 }
165
166 URLFetcherProtectEntry* URLFetcherProtectManager::Register(
167 const std::string& id, URLFetcherProtectEntry* entry) {
168 AutoLock lock(lock_);
169
170 ProtectService::iterator i = services_.find(id);
171 if (i != services_.end()) {
172 // The entry exists.
173 delete i->second;
174 }
175
176 services_[id] = entry;
177 return entry;
178 }
179
180 URLFetcherProtectManager::URLFetcherProtectManager() {}
OLDNEW
« no previous file with comments | « chrome/common/net/url_fetcher_protect.h ('k') | chrome/common/net/url_fetcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698