summaryrefslogtreecommitdiffstats
path: root/chrome/browser/url_fetcher_protect.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/url_fetcher_protect.cc
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/url_fetcher_protect.cc')
-rw-r--r--chrome/browser/url_fetcher_protect.cc192
1 files changed, 192 insertions, 0 deletions
diff --git a/chrome/browser/url_fetcher_protect.cc b/chrome/browser/url_fetcher_protect.cc
new file mode 100644
index 0000000..42f4556
--- /dev/null
+++ b/chrome/browser/url_fetcher_protect.cc
@@ -0,0 +1,192 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/browser/url_fetcher_protect.h"
+
+// ProtectEntry --------------------------------------------------------------
+
+
+// Default parameters. Time is in milliseconds.
+// static
+const int ProtectEntry::kDefaultSlidingWindowPeriod = 2000;
+
+const int ProtectEntry::kDefaultMaxSendThreshold = 20;
+const int ProtectEntry::kDefaultMaxRetries = 0;
+
+const int ProtectEntry::kDefaultInitialTimeout = 100;
+const double ProtectEntry::kDefaultMultiplier = 2.0;
+const int ProtectEntry::kDefaultConstantFactor = 100;
+const int ProtectEntry::kDefaultMaximumTimeout = 60000;
+
+
+ProtectEntry::ProtectEntry()
+ : sliding_window_period_(kDefaultSlidingWindowPeriod),
+ max_send_threshold_(kDefaultMaxSendThreshold),
+ max_retries_(kDefaultMaxRetries),
+ initial_timeout_(kDefaultInitialTimeout),
+ multiplier_(kDefaultMultiplier),
+ constant_factor_(kDefaultConstantFactor),
+ maximum_timeout_(kDefaultMaximumTimeout) {
+ ResetBackoff();
+}
+
+ProtectEntry::ProtectEntry(int sliding_window_period, int max_send_threshold,
+ int max_retries, int initial_timeout,
+ double multiplier, int constant_factor,
+ int maximum_timeout)
+ : sliding_window_period_(sliding_window_period),
+ max_send_threshold_(max_send_threshold),
+ max_retries_(max_retries),
+ initial_timeout_(initial_timeout),
+ multiplier_(multiplier),
+ constant_factor_(constant_factor),
+ maximum_timeout_(maximum_timeout) {
+ ResetBackoff();
+}
+
+int ProtectEntry::UpdateBackoff(EventType event_type) {
+ // request may be sent in different threads
+ AutoLock lock(lock_);
+
+ TimeDelta t;
+ switch (event_type) {
+ case SEND:
+ t = AntiOverload();
+ break;
+ case SUCCESS:
+ t = ResetBackoff();
+ break;
+ case FAILURE:
+ t = IncreaseBackoff();
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ int wait = static_cast<int>(t.InMilliseconds());
+ DCHECK(wait >= 0);
+ return wait;
+}
+
+TimeDelta ProtectEntry::AntiOverload() {
+ TimeDelta sw = TimeDelta::FromMilliseconds(sliding_window_period_);
+ TimeTicks now = TimeTicks::Now();
+ // Estimate when the next request will be sent.
+ release_time_ = now;
+ if (send_log_.size() > 0) {
+ release_time_ = std::max(release_time_, send_log_.back());
+ }
+ // Checks if there are too many send events in recent time.
+ if (send_log_.size() >= static_cast<unsigned>(max_send_threshold_)) {
+ release_time_ = std::max(release_time_, send_log_.front() + sw);
+ }
+ // Logs the new send event.
+ send_log_.push(release_time_);
+ // Drops the out-of-date events in the event list.
+ while (!send_log_.empty() &&
+ (send_log_.front() + sw <= send_log_.back())) {
+ send_log_.pop();
+ }
+ return release_time_ - now;
+}
+
+TimeDelta ProtectEntry::ResetBackoff() {
+ timeout_period_ = initial_timeout_;
+ release_time_ = TimeTicks::Now();
+ return TimeDelta::FromMilliseconds(0);
+}
+
+TimeDelta ProtectEntry::IncreaseBackoff() {
+ TimeTicks now = TimeTicks::Now();
+
+ release_time_ = std::max(release_time_, now) +
+ TimeDelta::FromMilliseconds(timeout_period_);
+
+ // Calculates the new backoff time.
+ timeout_period_ = static_cast<int>
+ (multiplier_ * timeout_period_ + constant_factor_);
+ if (maximum_timeout_ && timeout_period_ > maximum_timeout_)
+ timeout_period_ = maximum_timeout_;
+
+ return release_time_ - now;
+}
+
+// ProtectManager ------------------------------------------------------------
+
+// static
+scoped_ptr<ProtectManager> ProtectManager::protect_manager_;
+Lock ProtectManager::lock_;
+
+ProtectManager::~ProtectManager() {
+ // Deletes all entries
+ ProtectService::iterator i;
+ for (i = services_.begin(); i != services_.end(); ++i) {
+ if (i->second)
+ delete i->second;
+ }
+}
+
+// static
+ProtectManager* ProtectManager::GetInstance() {
+ AutoLock lock(lock_);
+
+ if (protect_manager_.get() == NULL) {
+ protect_manager_.reset(new ProtectManager());
+ }
+ return protect_manager_.get();
+}
+
+ProtectEntry* ProtectManager::Register(std::string id) {
+ AutoLock lock(lock_);
+
+ ProtectService::iterator i = services_.find(id);
+
+ if (i != services_.end()) {
+ // The entry exists.
+ return i->second;
+ }
+
+ // Creates a new entry.
+ ProtectEntry* entry = new ProtectEntry();
+ services_[id] = entry;
+ return entry;
+}
+
+ProtectEntry* ProtectManager::Register(std::string id, ProtectEntry* entry) {
+ AutoLock lock(lock_);
+
+ ProtectService::iterator i = services_.find(id);
+ if (i != services_.end()) {
+ // The entry exists.
+ delete i->second;
+ }
+
+ services_[id] = entry;
+ return entry;
+}