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

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: 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>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/containers/mru_cache.h" 14 #include "base/containers/mru_cache.h"
15 #include "base/feature_list.h" 15 #include "base/feature_list.h"
16 #include "base/location.h" 16 #include "base/location.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/macros.h" 18 #include "base/macros.h"
19 #include "base/metrics/histogram.h" 19 #include "base/metrics/histogram.h"
20 #include "base/single_thread_task_runner.h" 20 #include "base/single_thread_task_runner.h"
21 #include "base/stl_util.h" 21 #include "base/stl_util.h"
22 #include "base/strings/string_split.h" 22 #include "base/strings/string_split.h"
23 #include "base/strings/string_util.h" 23 #include "base/strings/string_util.h"
24 #include "base/strings/stringprintf.h"
25 #include "base/synchronization/waitable_event.h" 24 #include "base/synchronization/waitable_event.h"
26 #include "base/threading/thread_restrictions.h" 25 #include "base/threading/thread_restrictions.h"
27 #include "base/threading/thread_task_runner_handle.h" 26 #include "base/threading/thread_task_runner_handle.h"
28 #include "base/time/time.h" 27 #include "base/time/time.h"
29 #include "base/values.h" 28 #include "base/values.h"
30 #include "chrome/browser/io_thread.h" 29 #include "chrome/browser/io_thread.h"
31 #include "chrome/browser/prefs/session_startup_pref.h" 30 #include "chrome/browser/prefs/session_startup_pref.h"
32 #include "chrome/browser/profiles/profile_io_data.h" 31 #include "chrome/browser/profiles/profile_io_data.h"
33 #include "chrome/common/chrome_switches.h" 32 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/pref_names.h" 33 #include "chrome/common/pref_names.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 96
98 static int g_max_queueing_delay_ms = 97 static int g_max_queueing_delay_ms =
99 Predictor::kMaxSpeculativeResolveQueueDelayMs; 98 Predictor::kMaxSpeculativeResolveQueueDelayMs;
100 static size_t g_max_parallel_resolves = 99 static size_t g_max_parallel_resolves =
101 Predictor::kMaxSpeculativeParallelResolves; 100 Predictor::kMaxSpeculativeParallelResolves;
102 101
103 // A version number for prefs that are saved. This should be incremented when 102 // A version number for prefs that are saved. This should be incremented when
104 // we change the format so that we discard old data. 103 // we change the format so that we discard old data.
105 static const int kPredictorStartupFormatVersion = 1; 104 static const int kPredictorStartupFormatVersion = 1;
106 105
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) 106 Predictor::Predictor(bool preconnect_enabled, bool predictor_enabled)
152 : url_request_context_getter_(NULL), 107 : url_request_context_getter_(NULL),
153 predictor_enabled_(predictor_enabled), 108 predictor_enabled_(predictor_enabled),
154 user_prefs_(NULL), 109 user_prefs_(NULL),
155 profile_io_data_(NULL), 110 profile_io_data_(NULL),
111 num_pending_lookups_(0),
156 peak_pending_lookups_(0), 112 peak_pending_lookups_(0),
157 shutdown_(false), 113 shutdown_(false),
158 max_concurrent_dns_lookups_(g_max_parallel_resolves), 114 max_concurrent_dns_lookups_(g_max_parallel_resolves),
159 max_dns_queue_delay_( 115 max_dns_queue_delay_(
160 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)), 116 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)),
161 host_resolver_(NULL),
162 transport_security_state_(NULL), 117 transport_security_state_(NULL),
163 ssl_config_service_(NULL), 118 ssl_config_service_(NULL),
164 proxy_service_(NULL), 119 proxy_service_(NULL),
165 preconnect_enabled_(preconnect_enabled), 120 preconnect_enabled_(preconnect_enabled),
166 consecutive_omnibox_preconnect_count_(0), 121 consecutive_omnibox_preconnect_count_(0),
167 next_trim_time_(base::TimeTicks::Now() + 122 next_trim_time_(base::TimeTicks::Now() +
168 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)), 123 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)),
169 observer_(NULL) { 124 observer_(NULL) {
170 DCHECK_CURRENTLY_ON(BrowserThread::UI); 125 DCHECK_CURRENTLY_ON(BrowserThread::UI);
171 } 126 }
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 } 346 }
392 347
393 // ---------------------- End UI methods. ------------------------------------- 348 // ---------------------- End UI methods. -------------------------------------
394 349
395 // --------------------- Start IO methods. ------------------------------------ 350 // --------------------- Start IO methods. ------------------------------------
396 351
397 void Predictor::Shutdown() { 352 void Predictor::Shutdown() {
398 DCHECK_CURRENTLY_ON(BrowserThread::IO); 353 DCHECK_CURRENTLY_ON(BrowserThread::IO);
399 DCHECK(!shutdown_); 354 DCHECK(!shutdown_);
400 shutdown_ = true; 355 shutdown_ = true;
401
402 STLDeleteElements(&pending_lookups_);
403 } 356 }
404 357
405 void Predictor::DiscardAllResults() { 358 void Predictor::DiscardAllResults() {
406 DCHECK_CURRENTLY_ON(BrowserThread::IO); 359 DCHECK_CURRENTLY_ON(BrowserThread::IO);
407 // Delete anything listed so far in this session that shows in about:dns. 360 // Delete anything listed so far in this session that shows in about:dns.
408 referrers_.clear(); 361 referrers_.clear();
409 362
410 363
411 // Try to delete anything in our work queue. 364 // Try to delete anything in our work queue.
412 while (!work_queue_.IsEmpty()) { 365 while (!work_queue_.IsEmpty()) {
413 // Emulate processing cycle as though host was not found. 366 // Emulate processing cycle as though host was not found.
414 GURL url = work_queue_.Pop(); 367 GURL url = work_queue_.Pop();
415 UrlInfo* info = &results_[url]; 368 UrlInfo* info = &results_[url];
416 DCHECK(info->HasUrl(url)); 369 DCHECK(info->HasUrl(url));
417 info->SetAssignedState(); 370 info->SetAssignedState();
418 info->SetNoSuchNameState(); 371 info->SetNoSuchNameState();
419 } 372 }
420 // Now every result_ is either resolved, or is being resolved 373 // Now every result_ is either resolved, or is being resolved.
421 // (see LookupRequest).
422 374
423 // Step through result_, recording names of all hosts that can't be erased. 375 // Step through result_, recording names of all hosts that can't be erased.
424 // We can't erase anything being worked on. 376 // We can't erase anything being worked on.
425 Results assignees; 377 Results assignees;
426 for (Results::iterator it = results_.begin(); results_.end() != it; ++it) { 378 for (Results::iterator it = results_.begin(); results_.end() != it; ++it) {
427 GURL url(it->first); 379 GURL url(it->first);
428 UrlInfo* info = &it->second; 380 UrlInfo* info = &it->second;
429 DCHECK(info->HasUrl(url)); 381 DCHECK(info->HasUrl(url));
430 if (info->is_assigned()) { 382 if (info->is_assigned()) {
431 info->SetPendingDeleteState(); 383 info->SetPendingDeleteState();
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 638
687 void Predictor::FinalizeInitializationOnIOThread( 639 void Predictor::FinalizeInitializationOnIOThread(
688 const UrlList& startup_urls, 640 const UrlList& startup_urls,
689 base::ListValue* referral_list, 641 base::ListValue* referral_list,
690 IOThread* io_thread, 642 IOThread* io_thread,
691 ProfileIOData* profile_io_data) { 643 ProfileIOData* profile_io_data) {
692 DCHECK_CURRENTLY_ON(BrowserThread::IO); 644 DCHECK_CURRENTLY_ON(BrowserThread::IO);
693 645
694 profile_io_data_ = profile_io_data; 646 profile_io_data_ = profile_io_data;
695 initial_observer_.reset(new InitialObserver()); 647 initial_observer_.reset(new InitialObserver());
696 host_resolver_ = io_thread->globals()->host_resolver.get();
697 648
698 net::URLRequestContext* context = 649 net::URLRequestContext* context =
699 url_request_context_getter_->GetURLRequestContext(); 650 url_request_context_getter_->GetURLRequestContext();
700 transport_security_state_ = context->transport_security_state(); 651 transport_security_state_ = context->transport_security_state();
701 ssl_config_service_ = context->ssl_config_service(); 652 ssl_config_service_ = context->ssl_config_service();
702 proxy_service_ = context->proxy_service(); 653 proxy_service_ = context->proxy_service();
703 654
704 // base::WeakPtrFactory instances need to be created and destroyed 655 // base::WeakPtrFactory instances need to be created and destroyed
705 // on the same thread. The predictor lives on the IO thread and will die 656 // 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 657 // from there so now that we're on the IO thread we need to properly
(...skipping 309 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 = content::PreresolveUrl(
1135 1083 url_request_context_getter_.get(), url,
1136 int status = request->Start(); 1084 base::Bind(&Predictor::OnLookupFinished, base::Unretained(this), url));
1137 if (status == net::ERR_IO_PENDING) { 1085 if (status == net::ERR_IO_PENDING) {
1138 // Will complete asynchronously. 1086 // Will complete asynchronously.
1139 pending_lookups_.insert(request); 1087 num_pending_lookups_++;
1140 peak_pending_lookups_ = std::max(peak_pending_lookups_, 1088 peak_pending_lookups_ =
1141 pending_lookups_.size()); 1089 std::max(peak_pending_lookups_, num_pending_lookups_);
1142 } else { 1090 } else {
1143 // Completed synchronously (was already cached by HostResolver), or else 1091 // Completed synchronously (was already cached by HostResolver), or else
1144 // there was (equivalently) some network error that prevents us from 1092 // there was (equivalently) some network error that prevents us from
1145 // finding the name. Status net::OK means it was "found." 1093 // finding the name. Status net::OK means it was "found."
1146 LookupFinished(request, url, status == net::OK); 1094 LookupFinished(url, status == net::OK);
1147 delete request;
1148 } 1095 }
1149 } 1096 }
1150 } 1097 }
1151 1098
1152 void Predictor::TrimReferrers() { 1099 void Predictor::TrimReferrers() {
1153 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1100 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1154 if (!urls_being_trimmed_.empty()) 1101 if (!urls_being_trimmed_.empty())
1155 return; // There is incremental trimming in progress already. 1102 return; // There is incremental trimming in progress already.
1156 1103
1157 // Check to see if it is time to trim yet. 1104 // Check to see if it is time to trim yet.
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 } 1306 }
1360 1307
1361 void SimplePredictor::ShutdownOnUIThread() { 1308 void SimplePredictor::ShutdownOnUIThread() {
1362 SetShutdown(true); 1309 SetShutdown(true);
1363 } 1310 }
1364 1311
1365 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } 1312 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; }
1366 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } 1313 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; }
1367 1314
1368 } // namespace chrome_browser_net 1315 } // namespace chrome_browser_net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698