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

Side by Side Diff: chrome/browser/net/predictor.cc

Issue 15675002: Add the UMA recording recall of URLRequests preconnected. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add missing files Created 7 years, 7 months 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
« no previous file with comments | « chrome/browser/net/predictor.h ('k') | chrome/browser/net/timed_cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/net/predictor.h" 5 #include "chrome/browser/net/predictor.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <set> 9 #include <set>
10 #include <sstream> 10 #include <sstream>
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // connections. Once this falls below kDiscardableExpectedValue the referrer 57 // connections. Once this falls below kDiscardableExpectedValue the referrer
58 // will be discarded. 58 // will be discarded.
59 // TODO(jar): Measure size of referrer lists in the field. Consider an adaptive 59 // TODO(jar): Measure size of referrer lists in the field. Consider an adaptive
60 // system that uses a higher trim ratio when the list is large. 60 // system that uses a higher trim ratio when the list is large.
61 // static 61 // static
62 const double Predictor::kReferrerTrimRatio = 0.97153; 62 const double Predictor::kReferrerTrimRatio = 0.97153;
63 const int64 Predictor::kDurationBetweenTrimmingsHours = 1; 63 const int64 Predictor::kDurationBetweenTrimmingsHours = 1;
64 const int64 Predictor::kDurationBetweenTrimmingIncrementsSeconds = 15; 64 const int64 Predictor::kDurationBetweenTrimmingIncrementsSeconds = 15;
65 const size_t Predictor::kUrlsTrimmedPerIncrement = 5u; 65 const size_t Predictor::kUrlsTrimmedPerIncrement = 5u;
66 const size_t Predictor::kMaxSpeculativeParallelResolves = 3; 66 const size_t Predictor::kMaxSpeculativeParallelResolves = 3;
67 const int Predictor::kMaxUnusedSocketLifetimeSecondsWithoutAGet = 10;
67 // To control our congestion avoidance system, which discards a queue when 68 // To control our congestion avoidance system, which discards a queue when
68 // resolutions are "taking too long," we need an expected resolution time. 69 // resolutions are "taking too long," we need an expected resolution time.
69 // Common average is in the range of 300-500ms. 70 // Common average is in the range of 300-500ms.
70 const int kExpectedResolutionTimeMs = 500; 71 const int kExpectedResolutionTimeMs = 500;
71 const int Predictor::kTypicalSpeculativeGroupSize = 8; 72 const int Predictor::kTypicalSpeculativeGroupSize = 8;
72 const int Predictor::kMaxSpeculativeResolveQueueDelayMs = 73 const int Predictor::kMaxSpeculativeResolveQueueDelayMs =
73 (kExpectedResolutionTimeMs * Predictor::kTypicalSpeculativeGroupSize) / 74 (kExpectedResolutionTimeMs * Predictor::kTypicalSpeculativeGroupSize) /
74 Predictor::kMaxSpeculativeParallelResolves; 75 Predictor::kMaxSpeculativeParallelResolves;
75 76
76 static int g_max_queueing_delay_ms = 77 static int g_max_queueing_delay_ms =
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 url_request_context_getter_(NULL), 130 url_request_context_getter_(NULL),
130 predictor_enabled_(true), 131 predictor_enabled_(true),
131 peak_pending_lookups_(0), 132 peak_pending_lookups_(0),
132 shutdown_(false), 133 shutdown_(false),
133 max_concurrent_dns_lookups_(g_max_parallel_resolves), 134 max_concurrent_dns_lookups_(g_max_parallel_resolves),
134 max_dns_queue_delay_( 135 max_dns_queue_delay_(
135 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)), 136 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)),
136 host_resolver_(NULL), 137 host_resolver_(NULL),
137 preconnect_enabled_(preconnect_enabled), 138 preconnect_enabled_(preconnect_enabled),
138 consecutive_omnibox_preconnect_count_(0), 139 consecutive_omnibox_preconnect_count_(0),
140 recent_preconnects_(
141 TimeDelta::FromSeconds(kMaxUnusedSocketLifetimeSecondsWithoutAGet)),
139 next_trim_time_(base::TimeTicks::Now() + 142 next_trim_time_(base::TimeTicks::Now() +
140 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)) { 143 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)) {
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
142 } 145 }
143 146
144 Predictor::~Predictor() { 147 Predictor::~Predictor() {
145 // TODO(rlp): Add DCHECK for CurrentlyOn(BrowserThread::IO) when the 148 // TODO(rlp): Add DCHECK for CurrentlyOn(BrowserThread::IO) when the
146 // ProfileManagerTest has been updated with a mock profile. 149 // ProfileManagerTest has been updated with a mock profile.
147 DCHECK(shutdown_); 150 DCHECK(shutdown_);
148 } 151 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 // pool. Currently, we just do a connect, which MAY be reset if we 239 // pool. Currently, we just do a connect, which MAY be reset if we
237 // don't use it in 10 secondes!!! As a result, we may do more 240 // don't use it in 10 secondes!!! As a result, we may do more
238 // connections, and actually cost the server more than if we did a real 241 // connections, and actually cost the server more than if we did a real
239 // get with a fake request (/gen_204 might be the good path on Google). 242 // get with a fake request (/gen_204 might be the good path on Google).
240 const int kMaxSearchKeepaliveSeconds(10); 243 const int kMaxSearchKeepaliveSeconds(10);
241 if ((now - last_omnibox_preconnect_).InSeconds() < 244 if ((now - last_omnibox_preconnect_).InSeconds() <
242 kMaxSearchKeepaliveSeconds) 245 kMaxSearchKeepaliveSeconds)
243 return; // We've done a preconnect recently. 246 return; // We've done a preconnect recently.
244 last_omnibox_preconnect_ = now; 247 last_omnibox_preconnect_ = now;
245 const int kConnectionsNeeded = 1; 248 const int kConnectionsNeeded = 1;
246 PreconnectOnUIThread(CanonicalizeUrl(url), GURL(), motivation, 249 PreconnectUrl(CanonicalizeUrl(url), GURL(), motivation,
247 kConnectionsNeeded, 250 kConnectionsNeeded);
248 url_request_context_getter_);
249 return; // Skip pre-resolution, since we'll open a connection. 251 return; // Skip pre-resolution, since we'll open a connection.
250 } 252 }
251 } else { 253 } else {
252 consecutive_omnibox_preconnect_count_ = 0; 254 consecutive_omnibox_preconnect_count_ = 0;
253 } 255 }
254 } 256 }
255 257
256 // Fall through and consider pre-resolution. 258 // Fall through and consider pre-resolution.
257 259
258 // Omnibox tends to call in pairs (just a few milliseconds apart), and we 260 // Omnibox tends to call in pairs (just a few milliseconds apart), and we
(...skipping 18 matching lines...) Expand all
277 const GURL& first_party_for_cookies) { 279 const GURL& first_party_for_cookies) {
278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || 280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
279 BrowserThread::CurrentlyOn(BrowserThread::IO)); 281 BrowserThread::CurrentlyOn(BrowserThread::IO));
280 if (!predictor_enabled_ || !preconnect_enabled() || 282 if (!predictor_enabled_ || !preconnect_enabled() ||
281 !url.is_valid() || !url.has_host()) 283 !url.is_valid() || !url.has_host())
282 return; 284 return;
283 285
284 std::string host = url.HostNoBrackets(); 286 std::string host = url.HostNoBrackets();
285 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); 287 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED);
286 const int kConnectionsNeeded = 1; 288 const int kConnectionsNeeded = 1;
287 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { 289 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies,
288 PreconnectOnUIThread(CanonicalizeUrl(url), first_party_for_cookies, 290 motivation, kConnectionsNeeded);
289 motivation, kConnectionsNeeded,
290 url_request_context_getter_);
291 } else {
292 PreconnectOnIOThread(CanonicalizeUrl(url), first_party_for_cookies,
293 motivation, kConnectionsNeeded,
294 url_request_context_getter_);
295 }
296 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); 291 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies);
297 } 292 }
298 293
299 UrlList Predictor::GetPredictedUrlListAtStartup( 294 UrlList Predictor::GetPredictedUrlListAtStartup(
300 PrefService* user_prefs, 295 PrefService* user_prefs,
301 PrefService* local_state) { 296 PrefService* local_state) {
302 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 297 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
303 UrlList urls; 298 UrlList urls;
304 // Recall list of URLs we learned about during last session. 299 // Recall list of URLs we learned about during last session.
305 // This may catch secondary hostnames, pulled in by the homepages. It will 300 // This may catch secondary hostnames, pulled in by the homepages. It will
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 base::Bind(&Predictor::EnablePredictorOnIOThread, 817 base::Bind(&Predictor::EnablePredictorOnIOThread,
823 base::Unretained(this), enable)); 818 base::Unretained(this), enable));
824 } 819 }
825 } 820 }
826 821
827 void Predictor::EnablePredictorOnIOThread(bool enable) { 822 void Predictor::EnablePredictorOnIOThread(bool enable) {
828 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 823 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
829 predictor_enabled_ = enable; 824 predictor_enabled_ = enable;
830 } 825 }
831 826
827 void Predictor::PreconnectUrl(const GURL& url,
828 const GURL& first_party_for_cookies,
829 UrlInfo::ResolutionMotivation motivation,
830 int count) {
831 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
832 BrowserThread::CurrentlyOn(BrowserThread::IO));
833
834 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
835 PreconnectUrlOnIOThread(url, first_party_for_cookies, motivation, count);
836 } else {
837 BrowserThread::PostTask(
838 BrowserThread::IO,
839 FROM_HERE,
840 base::Bind(&Predictor::PreconnectUrlOnIOThread,
841 base::Unretained(this), url, first_party_for_cookies,
842 motivation, count));
843 }
844 }
845
846 void Predictor::PreconnectUrlOnIOThread(
847 const GURL& url, const GURL& first_party_for_cookies,
848 UrlInfo::ResolutionMotivation motivation, int count) {
849 GURL canonical_url(CanonicalizeUrl(url));
850 recent_preconnects_.SetRecentlySeen(canonical_url);
851
852 PreconnectOnIOThread(url, first_party_for_cookies, motivation, count,
853 url_request_context_getter_);
854 }
855
856 void Predictor::RecordPreconnectNavigationStats(const GURL& url) {
857 UMA_HISTOGRAM_BOOLEAN(
858 "Net.PreconnectedNavigation",
859 recent_preconnects_.WasRecentlySeen(url));
860 }
861
832 void Predictor::PredictFrameSubresources(const GURL& url, 862 void Predictor::PredictFrameSubresources(const GURL& url,
833 const GURL& first_party_for_cookies) { 863 const GURL& first_party_for_cookies) {
834 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || 864 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
835 BrowserThread::CurrentlyOn(BrowserThread::IO)); 865 BrowserThread::CurrentlyOn(BrowserThread::IO));
836 if (!predictor_enabled_) 866 if (!predictor_enabled_)
837 return; 867 return;
838 DCHECK_EQ(url.GetWithEmptyPath(), url); 868 DCHECK_EQ(url.GetWithEmptyPath(), url);
839 // Add one pass through the message loop to allow current navigation to 869 // Add one pass through the message loop to allow current navigation to
840 // proceed. 870 // proceed.
841 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { 871 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
(...skipping 20 matching lines...) Expand all
862 DCHECK_EQ(url.GetWithEmptyPath(), url); 892 DCHECK_EQ(url.GetWithEmptyPath(), url);
863 Referrers::iterator it = referrers_.find(url); 893 Referrers::iterator it = referrers_.find(url);
864 if (referrers_.end() == it) { 894 if (referrers_.end() == it) {
865 // Only when we don't know anything about this url, make 2 connections 895 // Only when we don't know anything about this url, make 2 connections
866 // available. We could do this completely via learning (by prepopulating 896 // available. We could do this completely via learning (by prepopulating
867 // the referrer_ list with this expected value), but it would swell the 897 // the referrer_ list with this expected value), but it would swell the
868 // size of the list with all the "Leaf" nodes in the tree (nodes that don't 898 // size of the list with all the "Leaf" nodes in the tree (nodes that don't
869 // load any subresources). If we learn about this resource, we will instead 899 // load any subresources). If we learn about this resource, we will instead
870 // provide a more carefully estimated preconnection count. 900 // provide a more carefully estimated preconnection count.
871 if (preconnect_enabled_) { 901 if (preconnect_enabled_) {
872 PreconnectOnIOThread(url, first_party_for_cookies, 902 PreconnectUrlOnIOThread(url, first_party_for_cookies,
873 UrlInfo::SELF_REFERAL_MOTIVATED, 2, 903 UrlInfo::SELF_REFERAL_MOTIVATED, 2);
874 url_request_context_getter_);
875 } 904 }
876 return; 905 return;
877 } 906 }
878 907
879 Referrer* referrer = &(it->second); 908 Referrer* referrer = &(it->second);
880 referrer->IncrementUseCount(); 909 referrer->IncrementUseCount();
881 const UrlInfo::ResolutionMotivation motivation = 910 const UrlInfo::ResolutionMotivation motivation =
882 UrlInfo::LEARNED_REFERAL_MOTIVATED; 911 UrlInfo::LEARNED_REFERAL_MOTIVATED;
883 for (Referrer::iterator future_url = referrer->begin(); 912 for (Referrer::iterator future_url = referrer->begin();
884 future_url != referrer->end(); ++future_url) { 913 future_url != referrer->end(); ++future_url) {
885 SubresourceValue evalution(TOO_NEW); 914 SubresourceValue evalution(TOO_NEW);
886 double connection_expectation = future_url->second.subresource_use_rate(); 915 double connection_expectation = future_url->second.subresource_use_rate();
887 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation", 916 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation",
888 static_cast<int>(connection_expectation * 100), 917 static_cast<int>(connection_expectation * 100),
889 10, 5000, 50); 918 10, 5000, 50);
890 future_url->second.ReferrerWasObserved(); 919 future_url->second.ReferrerWasObserved();
891 if (preconnect_enabled_ && 920 if (preconnect_enabled_ &&
892 connection_expectation > kPreconnectWorthyExpectedValue) { 921 connection_expectation > kPreconnectWorthyExpectedValue) {
893 evalution = PRECONNECTION; 922 evalution = PRECONNECTION;
894 future_url->second.IncrementPreconnectionCount(); 923 future_url->second.IncrementPreconnectionCount();
895 int count = static_cast<int>(std::ceil(connection_expectation)); 924 int count = static_cast<int>(std::ceil(connection_expectation));
896 if (url.host() == future_url->first.host()) 925 if (url.host() == future_url->first.host())
897 ++count; 926 ++count;
898 PreconnectOnIOThread(future_url->first, first_party_for_cookies, 927 PreconnectUrlOnIOThread(future_url->first, first_party_for_cookies,
899 motivation, count, url_request_context_getter_); 928 motivation, count);
900 } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) { 929 } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) {
901 evalution = PRERESOLUTION; 930 evalution = PRERESOLUTION;
902 future_url->second.preresolution_increment(); 931 future_url->second.preresolution_increment();
903 UrlInfo* queued_info = AppendToResolutionQueue(future_url->first, 932 UrlInfo* queued_info = AppendToResolutionQueue(future_url->first,
904 motivation); 933 motivation);
905 if (queued_info) 934 if (queued_info)
906 queued_info->SetReferringHostname(url); 935 queued_info->SetReferringHostname(url);
907 } 936 }
908 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution, 937 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution,
909 SUBRESOURCE_VALUE_MAX); 938 SUBRESOURCE_VALUE_MAX);
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 IOThread* io_thread, 1224 IOThread* io_thread,
1196 net::URLRequestContextGetter* getter) { 1225 net::URLRequestContextGetter* getter) {
1197 // Empty function for unittests. 1226 // Empty function for unittests.
1198 } 1227 }
1199 1228
1200 void SimplePredictor::ShutdownOnUIThread(PrefService* user_prefs) { 1229 void SimplePredictor::ShutdownOnUIThread(PrefService* user_prefs) {
1201 SetShutdown(true); 1230 SetShutdown(true);
1202 } 1231 }
1203 1232
1204 } // namespace chrome_browser_net 1233 } // namespace chrome_browser_net
OLDNEW
« no previous file with comments | « chrome/browser/net/predictor.h ('k') | chrome/browser/net/timed_cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698