Index: chrome/browser/prerender/prerender_manager.cc |
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc |
index d30bc9135c9e81f2c3f35701dae39a972a8a6b4c..ca750689ae56dc18698cf6d511fcc5b3879619e4 100644 |
--- a/chrome/browser/prerender/prerender_manager.cc |
+++ b/chrome/browser/prerender/prerender_manager.cc |
@@ -24,6 +24,12 @@ namespace prerender { |
base::TimeTicks PrerenderManager::last_prefetch_seen_time_; |
// static |
+base::TimeTicks PrerenderManager::last_prerender_start_time_; |
+ |
+// static |
+bool PrerenderManager::rate_limit_enabled_ = true; |
+ |
+// static |
PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ = |
PRERENDER_MODE_ENABLED; |
@@ -92,10 +98,21 @@ bool PrerenderManager::AddPreload(const GURL& url, |
RecordFinalStatus(FINAL_STATUS_TOO_MANY_PROCESSES); |
return false; |
} |
+ |
+ // Check if enough time has passed since the last prerender. |
+ if (!DoesRateLimitAllowPrerender()) { |
+ // Cancel the prerender. We could add it to the pending prerender list but |
+ // this doesn't make sense as the next prerender request will be triggered |
+ // by a navigation and is unlikely to be the same site. |
+ RecordFinalStatus(FINAL_STATUS_RATE_LIMIT_EXCEEDED); |
+ return false; |
+ } |
+ |
// TODO(cbentzel): Move invalid checks here instead of PrerenderContents? |
PrerenderContentsData data(CreatePrerenderContents(url, alias_urls, referrer), |
GetCurrentTime()); |
prerender_list_.push_back(data); |
+ last_prerender_start_time_ = base::TimeTicks::Now(); |
data.contents_->StartPrerendering(); |
while (prerender_list_.size() > max_elements_) { |
data = prerender_list_.front(); |
@@ -277,6 +294,22 @@ bool PrerenderManager::ShouldRecordWindowedPPLT() { |
return elapsed_time <= base::TimeDelta::FromSeconds(kWindowedPPLTSeconds); |
} |
+// static |
+bool PrerenderManager::DoesRateLimitAllowPrerender() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (!rate_limit_enabled_) |
+ return true; |
+ if (last_prerender_start_time_.is_null()) |
+ return true; |
+ base::TimeDelta elapsed_time = |
+ base::TimeTicks::Now() - last_prerender_start_time_; |
+ UMA_HISTOGRAM_ENUMERATION("Prerender.TimeBetweenRequests", |
tburkard
2011/03/11 23:49:07
To clarify the name, maybe call it TimeBetweenPrer
|
+ elapsed_time.InMilliseconds(), |
+ kMaxTimeBetweenPrerendersMs); |
+ return elapsed_time > |
+ base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); |
+} |
+ |
void PrerenderManager::StartSchedulingPeriodicCleanups() { |
if (repeating_timer_.IsRunning()) |
return; |