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

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

Issue 2004453002: Add a Dns preresolve interface in //content (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@predictor_dns_browsertest
Patch Set: remove controller class Created 4 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
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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 97
98 static int g_max_queueing_delay_ms = 98 static int g_max_queueing_delay_ms =
99 Predictor::kMaxSpeculativeResolveQueueDelayMs; 99 Predictor::kMaxSpeculativeResolveQueueDelayMs;
100 static size_t g_max_parallel_resolves = 100 static size_t g_max_parallel_resolves =
101 Predictor::kMaxSpeculativeParallelResolves; 101 Predictor::kMaxSpeculativeParallelResolves;
102 102
103 // A version number for prefs that are saved. This should be incremented when 103 // A version number for prefs that are saved. This should be incremented when
104 // we change the format so that we discard old data. 104 // we change the format so that we discard old data.
105 static const int kPredictorStartupFormatVersion = 1; 105 static const int kPredictorStartupFormatVersion = 1;
106 106
107 class Predictor::LookupRequest {
108 public:
109 LookupRequest(Predictor* predictor,
110 net::HostResolver* host_resolver,
111 const GURL& url)
112 : predictor_(predictor),
113 url_(url),
114 resolver_(host_resolver) {
115 }
116
117 // Return underlying network resolver status.
118 // net::OK ==> Host was found synchronously.
119 // net:ERR_IO_PENDING ==> Network will callback later with result.
120 // anything else ==> Host was not found synchronously.
121 int Start() {
122 net::HostResolver::RequestInfo resolve_info(
123 net::HostPortPair::FromURL(url_));
124
125 // Make a note that this is a speculative resolve request. This allows us
126 // to separate it from real navigations in the observer's callback, and
127 // lets the HostResolver know it can de-prioritize it.
128 resolve_info.set_is_speculative(true);
129 return resolver_.Resolve(
130 resolve_info,
131 net::DEFAULT_PRIORITY,
132 &addresses_,
133 base::Bind(&LookupRequest::OnLookupFinished, base::Unretained(this)),
134 net::BoundNetLog());
135 }
136
137 private:
138 void OnLookupFinished(int result) {
139 predictor_->OnLookupFinished(this, url_, result == net::OK);
140 }
141
142 Predictor* predictor_; // The predictor which started us.
143
144 const GURL url_; // Hostname to resolve.
145 net::SingleRequestHostResolver resolver_;
146 net::AddressList addresses_;
147
148 DISALLOW_COPY_AND_ASSIGN(LookupRequest);
149 };
150
151 Predictor::Predictor(bool preconnect_enabled, bool predictor_enabled) 107 Predictor::Predictor(bool preconnect_enabled, bool predictor_enabled)
152 : url_request_context_getter_(NULL), 108 : url_request_context_getter_(NULL),
153 predictor_enabled_(predictor_enabled), 109 predictor_enabled_(predictor_enabled),
154 user_prefs_(NULL), 110 user_prefs_(NULL),
achuithb 2016/05/25 21:17:10 Could you please replace NULLs with nullptr in thi
Charlie Harrison 2016/05/25 21:36:19 Replaced all NULLs with nullptr. I don't think hea
achuithb 2016/05/25 21:54:32 I'm not an owner here, so it's up to you if you wa
Charlie Harrison 2016/05/25 22:06:55 Thanks for the link. I'd prefer not to in this cas
155 profile_io_data_(NULL), 111 profile_io_data_(NULL),
112 num_pending_lookups_(0),
156 peak_pending_lookups_(0), 113 peak_pending_lookups_(0),
157 shutdown_(false), 114 shutdown_(false),
158 max_concurrent_dns_lookups_(g_max_parallel_resolves), 115 max_concurrent_dns_lookups_(g_max_parallel_resolves),
159 max_dns_queue_delay_( 116 max_dns_queue_delay_(
160 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)), 117 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)),
161 host_resolver_(NULL),
162 transport_security_state_(NULL), 118 transport_security_state_(NULL),
163 ssl_config_service_(NULL), 119 ssl_config_service_(NULL),
164 proxy_service_(NULL), 120 proxy_service_(NULL),
165 preconnect_enabled_(preconnect_enabled), 121 preconnect_enabled_(preconnect_enabled),
166 consecutive_omnibox_preconnect_count_(0), 122 consecutive_omnibox_preconnect_count_(0),
167 next_trim_time_(base::TimeTicks::Now() + 123 next_trim_time_(base::TimeTicks::Now() +
168 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)), 124 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)),
169 observer_(NULL) { 125 observer_(NULL) {
170 DCHECK_CURRENTLY_ON(BrowserThread::UI); 126 DCHECK_CURRENTLY_ON(BrowserThread::UI);
171 } 127 }
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 } 347 }
392 348
393 // ---------------------- End UI methods. ------------------------------------- 349 // ---------------------- End UI methods. -------------------------------------
394 350
395 // --------------------- Start IO methods. ------------------------------------ 351 // --------------------- Start IO methods. ------------------------------------
396 352
397 void Predictor::Shutdown() { 353 void Predictor::Shutdown() {
398 DCHECK_CURRENTLY_ON(BrowserThread::IO); 354 DCHECK_CURRENTLY_ON(BrowserThread::IO);
399 DCHECK(!shutdown_); 355 DCHECK(!shutdown_);
400 shutdown_ = true; 356 shutdown_ = true;
401
402 STLDeleteElements(&pending_lookups_);
403 } 357 }
404 358
405 void Predictor::DiscardAllResults() { 359 void Predictor::DiscardAllResults() {
406 DCHECK_CURRENTLY_ON(BrowserThread::IO); 360 DCHECK_CURRENTLY_ON(BrowserThread::IO);
407 // Delete anything listed so far in this session that shows in about:dns. 361 // Delete anything listed so far in this session that shows in about:dns.
408 referrers_.clear(); 362 referrers_.clear();
409 363
410 364
411 // Try to delete anything in our work queue. 365 // Try to delete anything in our work queue.
412 while (!work_queue_.IsEmpty()) { 366 while (!work_queue_.IsEmpty()) {
413 // Emulate processing cycle as though host was not found. 367 // Emulate processing cycle as though host was not found.
414 GURL url = work_queue_.Pop(); 368 GURL url = work_queue_.Pop();
415 UrlInfo* info = &results_[url]; 369 UrlInfo* info = &results_[url];
416 DCHECK(info->HasUrl(url)); 370 DCHECK(info->HasUrl(url));
417 info->SetAssignedState(); 371 info->SetAssignedState();
418 info->SetNoSuchNameState(); 372 info->SetNoSuchNameState();
419 } 373 }
420 // Now every result_ is either resolved, or is being resolved 374 // Now every result_ is either resolved, or is being resolved.
421 // (see LookupRequest).
422 375
423 // Step through result_, recording names of all hosts that can't be erased. 376 // Step through result_, recording names of all hosts that can't be erased.
424 // We can't erase anything being worked on. 377 // We can't erase anything being worked on.
425 Results assignees; 378 Results assignees;
426 for (Results::iterator it = results_.begin(); results_.end() != it; ++it) { 379 for (Results::iterator it = results_.begin(); results_.end() != it; ++it) {
427 GURL url(it->first); 380 GURL url(it->first);
428 UrlInfo* info = &it->second; 381 UrlInfo* info = &it->second;
429 DCHECK(info->HasUrl(url)); 382 DCHECK(info->HasUrl(url));
430 if (info->is_assigned()) { 383 if (info->is_assigned()) {
431 info->SetPendingDeleteState(); 384 info->SetPendingDeleteState();
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 639
687 void Predictor::FinalizeInitializationOnIOThread( 640 void Predictor::FinalizeInitializationOnIOThread(
688 const UrlList& startup_urls, 641 const UrlList& startup_urls,
689 base::ListValue* referral_list, 642 base::ListValue* referral_list,
690 IOThread* io_thread, 643 IOThread* io_thread,
691 ProfileIOData* profile_io_data) { 644 ProfileIOData* profile_io_data) {
692 DCHECK_CURRENTLY_ON(BrowserThread::IO); 645 DCHECK_CURRENTLY_ON(BrowserThread::IO);
693 646
694 profile_io_data_ = profile_io_data; 647 profile_io_data_ = profile_io_data;
695 initial_observer_.reset(new InitialObserver()); 648 initial_observer_.reset(new InitialObserver());
696 host_resolver_ = io_thread->globals()->host_resolver.get();
697 649
698 net::URLRequestContext* context = 650 net::URLRequestContext* context =
699 url_request_context_getter_->GetURLRequestContext(); 651 url_request_context_getter_->GetURLRequestContext();
700 transport_security_state_ = context->transport_security_state(); 652 transport_security_state_ = context->transport_security_state();
701 ssl_config_service_ = context->ssl_config_service(); 653 ssl_config_service_ = context->ssl_config_service();
702 proxy_service_ = context->proxy_service(); 654 proxy_service_ = context->proxy_service();
703 655
704 // base::WeakPtrFactory instances need to be created and destroyed 656 // base::WeakPtrFactory instances need to be created and destroyed
705 // on the same thread. The predictor lives on the IO thread and will die 657 // on the same thread. The predictor lives on the IO thread and will die
706 // from there so now that we're on the IO thread we need to properly 658 // from there so now that we're on the IO thread we need to properly
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 void Predictor::PreconnectUrlOnIOThread( 821 void Predictor::PreconnectUrlOnIOThread(
870 const GURL& original_url, 822 const GURL& original_url,
871 const GURL& first_party_for_cookies, 823 const GURL& first_party_for_cookies,
872 UrlInfo::ResolutionMotivation motivation, 824 UrlInfo::ResolutionMotivation motivation,
873 bool allow_credentials, 825 bool allow_credentials,
874 int count) { 826 int count) {
875 // Skip the HSTS redirect. 827 // Skip the HSTS redirect.
876 GURL url = GetHSTSRedirectOnIOThread(original_url); 828 GURL url = GetHSTSRedirectOnIOThread(original_url);
877 829
878 // TODO(csharrison): The observer should only be notified after the null check 830 // TODO(csharrison): The observer should only be notified after the null check
879 // for the URLRequestContextGetter. The predictor tests should be fixed to 831 // for the ProfileIOData. The predictor tests should be fixed to allow for
880 // allow for this, as they currently expect a callback with no getter. 832 // this, as they currently expect a callback with no getter.
881 // URLRequestContextGetter is null. Tests rely on this behavior.
882 if (observer_) { 833 if (observer_) {
883 observer_->OnPreconnectUrl( 834 observer_->OnPreconnectUrl(
884 url, first_party_for_cookies, motivation, count); 835 url, first_party_for_cookies, motivation, count);
885 } 836 }
886 837
887 net::URLRequestContextGetter* getter = url_request_context_getter_.get(); 838 if (!profile_io_data_)
888 if (!getter)
889 return; 839 return;
890 840
891 // Translate the motivation from UrlRequest motivations to HttpRequest 841 // Translate the motivation from UrlRequest motivations to HttpRequest
892 // motivations. 842 // motivations.
893 net::HttpRequestInfo::RequestMotivation request_motivation = 843 net::HttpRequestInfo::RequestMotivation request_motivation =
894 net::HttpRequestInfo::NORMAL_MOTIVATION; 844 net::HttpRequestInfo::NORMAL_MOTIVATION;
895 switch (motivation) { 845 switch (motivation) {
896 case UrlInfo::OMNIBOX_MOTIVATED: 846 case UrlInfo::OMNIBOX_MOTIVATED:
897 request_motivation = net::HttpRequestInfo::OMNIBOX_MOTIVATED; 847 request_motivation = net::HttpRequestInfo::OMNIBOX_MOTIVATED;
898 break; 848 break;
899 case UrlInfo::LEARNED_REFERAL_MOTIVATED: 849 case UrlInfo::LEARNED_REFERAL_MOTIVATED:
900 request_motivation = net::HttpRequestInfo::PRECONNECT_MOTIVATED; 850 request_motivation = net::HttpRequestInfo::PRECONNECT_MOTIVATED;
901 break; 851 break;
902 case UrlInfo::MOUSE_OVER_MOTIVATED: 852 case UrlInfo::MOUSE_OVER_MOTIVATED:
903 case UrlInfo::SELF_REFERAL_MOTIVATED: 853 case UrlInfo::SELF_REFERAL_MOTIVATED:
904 case UrlInfo::EARLY_LOAD_MOTIVATED: 854 case UrlInfo::EARLY_LOAD_MOTIVATED:
905 request_motivation = net::HttpRequestInfo::EARLY_LOAD_MOTIVATED; 855 request_motivation = net::HttpRequestInfo::EARLY_LOAD_MOTIVATED;
906 break; 856 break;
907 default: 857 default:
908 // Other motivations should never happen here. 858 // Other motivations should never happen here.
909 NOTREACHED(); 859 NOTREACHED();
910 break; 860 break;
911 } 861 }
912 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectMotivation", motivation, 862 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectMotivation", motivation,
913 UrlInfo::MAX_MOTIVATED); 863 UrlInfo::MAX_MOTIVATED);
914 content::PreconnectUrl(getter, url, first_party_for_cookies, count, 864 content::PreconnectUrl(profile_io_data_->GetResourceContext(), url,
915 allow_credentials, request_motivation); 865 first_party_for_cookies, count, allow_credentials,
866 request_motivation);
916 } 867 }
917 868
918 void Predictor::PredictFrameSubresources(const GURL& url, 869 void Predictor::PredictFrameSubresources(const GURL& url,
919 const GURL& first_party_for_cookies) { 870 const GURL& first_party_for_cookies) {
920 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || 871 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
921 BrowserThread::CurrentlyOn(BrowserThread::IO)); 872 BrowserThread::CurrentlyOn(BrowserThread::IO));
922 if (!predictor_enabled_) 873 if (!predictor_enabled_)
923 return; 874 return;
924 if (!CanPreresolveAndPreconnect()) 875 if (!CanPreresolveAndPreconnect())
925 return; 876 return;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 UrlInfo* queued_info = AppendToResolutionQueue(future_url->first, 967 UrlInfo* queued_info = AppendToResolutionQueue(future_url->first,
1017 motivation); 968 motivation);
1018 if (queued_info) 969 if (queued_info)
1019 queued_info->SetReferringHostname(url); 970 queued_info->SetReferringHostname(url);
1020 } 971 }
1021 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution, 972 UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution,
1022 SUBRESOURCE_VALUE_MAX); 973 SUBRESOURCE_VALUE_MAX);
1023 } 974 }
1024 } 975 }
1025 976
1026 void Predictor::OnLookupFinished(LookupRequest* request, const GURL& url, 977 void Predictor::OnLookupFinished(const GURL& url, int result) {
1027 bool found) {
1028 DCHECK_CURRENTLY_ON(BrowserThread::IO); 978 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1029 979
1030 LookupFinished(request, url, found); 980 LookupFinished(url, result == net::OK);
1031 pending_lookups_.erase(request); 981 DCHECK_GT(num_pending_lookups_, 0u);
1032 delete request; 982 num_pending_lookups_--;
1033
1034 StartSomeQueuedResolutions(); 983 StartSomeQueuedResolutions();
1035 } 984 }
1036 985
1037 void Predictor::LookupFinished(LookupRequest* request, const GURL& url, 986 void Predictor::LookupFinished(const GURL& url, bool found) {
1038 bool found) {
1039 DCHECK_CURRENTLY_ON(BrowserThread::IO); 987 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1040 UrlInfo* info = &results_[url]; 988 UrlInfo* info = &results_[url];
1041 DCHECK(info->HasUrl(url)); 989 DCHECK(info->HasUrl(url));
1042 if (info->is_marked_to_delete()) { 990 if (info->is_marked_to_delete()) {
1043 results_.erase(url); 991 results_.erase(url);
1044 } else { 992 } else {
1045 if (found) 993 if (found)
1046 info->SetFoundState(); 994 info->SetFoundState();
1047 else 995 else
1048 info->SetNoSuchNameState(); 996 info->SetNoSuchNameState();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 break; 1056 break;
1109 info = &results_[work_queue_.Pop()]; 1057 info = &results_[work_queue_.Pop()];
1110 info->SetAssignedState(); 1058 info->SetAssignedState();
1111 } 1059 }
1112 return true; 1060 return true;
1113 } 1061 }
1114 1062
1115 void Predictor::StartSomeQueuedResolutions() { 1063 void Predictor::StartSomeQueuedResolutions() {
1116 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1064 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1117 1065
1118 // If the queue is disabled, just make LookupRequests for all entries. 1066 // If the queue is disabled, just make requests for all entries.
1119 bool enable_queue = base::FeatureList::IsEnabled(kUsePredictorDNSQueue); 1067 bool enable_queue = base::FeatureList::IsEnabled(kUsePredictorDNSQueue);
1120 while (!work_queue_.IsEmpty() && 1068 while (
1121 (!enable_queue || 1069 !work_queue_.IsEmpty() &&
1122 pending_lookups_.size() < max_concurrent_dns_lookups_)) { 1070 (!enable_queue || num_pending_lookups_ < max_concurrent_dns_lookups_)) {
1123 const GURL url(work_queue_.Pop()); 1071 const GURL url(work_queue_.Pop());
1124 UrlInfo* info = &results_[url]; 1072 UrlInfo* info = &results_[url];
1125 DCHECK(info->HasUrl(url)); 1073 DCHECK(info->HasUrl(url));
1126 info->SetAssignedState(); 1074 info->SetAssignedState();
1127 1075
1128 // Only perform congestion control if the queue is enabled. 1076 // Only perform congestion control if the queue is enabled.
1129 if (enable_queue && CongestionControlPerformed(info)) { 1077 if (enable_queue && CongestionControlPerformed(info)) {
1130 DCHECK(work_queue_.IsEmpty()); 1078 DCHECK(work_queue_.IsEmpty());
1131 return; 1079 return;
1132 } 1080 }
1133 1081
1134 LookupRequest* request = new LookupRequest(this, host_resolver_, url); 1082 int status =
1135 1083 content::PreresolveUrl(profile_io_data_->GetResourceContext(), url,
1136 int status = request->Start(); 1084 base::Bind(&Predictor::OnLookupFinished,
1085 weak_factory_->GetWeakPtr(), url));
1137 if (status == net::ERR_IO_PENDING) { 1086 if (status == net::ERR_IO_PENDING) {
1138 // Will complete asynchronously. 1087 // Will complete asynchronously.
1139 pending_lookups_.insert(request); 1088 num_pending_lookups_++;
1140 peak_pending_lookups_ = std::max(peak_pending_lookups_, 1089 peak_pending_lookups_ =
1141 pending_lookups_.size()); 1090 std::max(peak_pending_lookups_, num_pending_lookups_);
1142 } else { 1091 } else {
1143 // Completed synchronously (was already cached by HostResolver), or else 1092 // Completed synchronously (was already cached by HostResolver), or else
1144 // there was (equivalently) some network error that prevents us from 1093 // there was (equivalently) some network error that prevents us from
1145 // finding the name. Status net::OK means it was "found." 1094 // finding the name. Status net::OK means it was "found."
1146 LookupFinished(request, url, status == net::OK); 1095 LookupFinished(url, status == net::OK);
1147 delete request;
1148 } 1096 }
1149 } 1097 }
1150 } 1098 }
1151 1099
1152 void Predictor::TrimReferrers() { 1100 void Predictor::TrimReferrers() {
1153 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1101 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1154 if (!urls_being_trimmed_.empty()) 1102 if (!urls_being_trimmed_.empty())
1155 return; // There is incremental trimming in progress already. 1103 return; // There is incremental trimming in progress already.
1156 1104
1157 // Check to see if it is time to trim yet. 1105 // Check to see if it is time to trim yet.
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 } 1307 }
1360 1308
1361 void SimplePredictor::ShutdownOnUIThread() { 1309 void SimplePredictor::ShutdownOnUIThread() {
1362 SetShutdown(true); 1310 SetShutdown(true);
1363 } 1311 }
1364 1312
1365 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } 1313 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; }
1366 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } 1314 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; }
1367 1315
1368 } // namespace chrome_browser_net 1316 } // namespace chrome_browser_net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698