Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // A Predictor object is instantiated once in the browser process, and manages | 5 // A Predictor object is instantiated once in the browser process, and manages |
| 6 // both preresolution of hostnames, as well as TCP/IP preconnection to expected | 6 // both preresolution of hostnames, as well as TCP/IP preconnection to expected |
| 7 // subresources. | 7 // subresources. |
| 8 // Most hostname lists are provided by the renderer processes, and include URLs | 8 // Most hostname lists are provided by the renderer processes, and include URLs |
| 9 // that *might* be used in the near future by the browsing user. One goal of | 9 // that *might* be used in the near future by the browsing user. One goal of |
| 10 // this class is to cause the underlying DNS structure to lookup a hostname | 10 // this class is to cause the underlying DNS structure to lookup a hostname |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #pragma once | 21 #pragma once |
| 22 | 22 |
| 23 #include <map> | 23 #include <map> |
| 24 #include <queue> | 24 #include <queue> |
| 25 #include <set> | 25 #include <set> |
| 26 #include <string> | 26 #include <string> |
| 27 #include <vector> | 27 #include <vector> |
| 28 | 28 |
| 29 #include "base/gtest_prod_util.h" | 29 #include "base/gtest_prod_util.h" |
| 30 #include "base/memory/ref_counted.h" | 30 #include "base/memory/ref_counted.h" |
| 31 #include "base/memory/scoped_ptr.h" | |
| 31 #include "chrome/browser/net/url_info.h" | 32 #include "chrome/browser/net/url_info.h" |
| 32 #include "chrome/browser/net/referrer.h" | 33 #include "chrome/browser/net/referrer.h" |
| 33 #include "chrome/common/net/predictor_common.h" | 34 #include "chrome/common/net/predictor_common.h" |
| 34 #include "net/base/host_port_pair.h" | 35 #include "net/base/host_port_pair.h" |
| 35 | 36 |
| 36 class ListValue; | 37 class ListValue; |
| 38 class PrefService; | |
| 39 class Profile; | |
| 40 | |
| 41 namespace base { | |
| 42 class WaitableEvent; | |
| 43 } | |
| 37 | 44 |
| 38 namespace net { | 45 namespace net { |
| 39 class HostResolver; | 46 class HostResolver; |
| 40 } // namespace net | 47 } // namespace net |
| 41 | 48 |
| 42 namespace chrome_browser_net { | 49 namespace chrome_browser_net { |
| 43 | 50 |
| 44 typedef chrome_common_net::UrlList UrlList; | 51 typedef chrome_common_net::UrlList UrlList; |
| 45 typedef chrome_common_net::NameList NameList; | 52 typedef chrome_common_net::NameList NameList; |
| 46 typedef std::map<GURL, UrlInfo> Results; | 53 typedef std::map<GURL, UrlInfo> Results; |
| 47 | 54 |
| 48 // Note that Predictor is not thread safe, and must only be called from | 55 // Note that Predictor is not thread safe, and must only be called from |
| 49 // the IO thread. Failure to do so will result in a DCHECK at runtime. | 56 // the IO thread. Failure to do so will result in a DCHECK at runtime. |
|
willchan no longer on Chromium
2011/07/21 12:10:53
This comment is wrong. It is used from both the UI
rpetterson
2011/08/10 02:24:46
I think I've covered everything in this comment. L
| |
| 50 class Predictor : public base::RefCountedThreadSafe<Predictor> { | 57 class Predictor : public base::RefCountedThreadSafe<Predictor> { |
| 51 public: | 58 public: |
| 52 // A version number for prefs that are saved. This should be incremented when | 59 // A version number for prefs that are saved. This should be incremented when |
| 53 // we change the format so that we discard old data. | 60 // we change the format so that we discard old data. |
| 54 enum { PREDICTOR_REFERRER_VERSION = 2 }; | 61 enum { PREDICTOR_REFERRER_VERSION = 2 }; |
| 55 | 62 |
| 56 // |max_concurrent| specifies how many concurrent (parallel) prefetches will | 63 // |max_concurrent| specifies how many concurrent (parallel) prefetches will |
| 57 // be performed. Host lookups will be issued through |host_resolver|. | 64 // be performed. Host lookups will be issued through |host_resolver|. |
| 58 Predictor(net::HostResolver* host_resolver, | 65 Predictor(net::HostResolver* host_resolver, |
| 59 base::TimeDelta max_queue_delay_ms, size_t max_concurrent, | 66 base::TimeDelta max_queue_delay_ms, size_t max_concurrent, |
| 60 bool preconnect_enabled); | 67 bool preconnect_enabled, bool predictor_enabled); |
| 68 | |
| 69 ~Predictor(); | |
| 61 | 70 |
| 62 // Cancel pending requests and prevent new ones from being made. | 71 // Cancel pending requests and prevent new ones from being made. |
| 63 void Shutdown(); | 72 void Shutdown(); |
| 64 | 73 |
| 65 // In some circumstances, for privacy reasons, all results should be | 74 // In some circumstances, for privacy reasons, all results should be |
| 66 // discarded. This method gracefully handles that activity. | 75 // discarded. This method gracefully handles that activity. |
| 67 // Destroy all our internal state, which shows what names we've looked up, and | 76 // Destroy all our internal state, which shows what names we've looked up, and |
| 68 // how long each has taken, etc. etc. We also destroy records of suggesses | 77 // how long each has taken, etc. etc. We also destroy records of suggesses |
| 69 // (cache hits etc.). | 78 // (cache hits etc.). |
| 70 void DiscardAllResults(); | 79 void DiscardAllResults(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 // so that it can be persisted in a pref. | 124 // so that it can be persisted in a pref. |
| 116 void SerializeReferrers(ListValue* referral_list); | 125 void SerializeReferrers(ListValue* referral_list); |
| 117 | 126 |
| 118 // Process a ListValue that contains all the data from a previous reference | 127 // Process a ListValue that contains all the data from a previous reference |
| 119 // list, as constructed by SerializeReferrers(), and add all the identified | 128 // list, as constructed by SerializeReferrers(), and add all the identified |
| 120 // values into the current referrer list. | 129 // values into the current referrer list. |
| 121 void DeserializeReferrers(const ListValue& referral_list); | 130 void DeserializeReferrers(const ListValue& referral_list); |
| 122 | 131 |
| 123 void DeserializeReferrersThenDelete(ListValue* referral_list); | 132 void DeserializeReferrersThenDelete(ListValue* referral_list); |
| 124 | 133 |
| 134 void DiscardInitialNavigationHistory(); | |
| 135 | |
| 136 void FinalizeInitialization(const std::vector<GURL>& urls_to_prefetch, | |
| 137 ListValue* referral_list); | |
| 138 | |
| 139 // During startup, we learn what the first N urls visited are, and then | |
| 140 // resolve the associated hosts ASAP during our next startup. | |
| 141 void LearnAboutInitialNavigation(const GURL& url); | |
| 142 | |
| 143 // Renderer bundles up list and sends to this browser API via IPC. | |
| 144 // TODO(jar): Use UrlList instead to include port and scheme. | |
| 145 void DnsPrefetchList(const NameList& hostnames); | |
| 146 | |
| 147 void Predictor::DnsPrefetchMotivatedList( | |
| 148 const UrlList& urls, | |
| 149 UrlInfo::ResolutionMotivation motivation); | |
| 150 | |
| 151 void SaveStateForNextStartupAndTrim(PrefService* prefs, Profile* profile); | |
| 152 | |
| 153 void SaveDnsPrefetchStateForNextStartupAndTrim( | |
| 154 ListValue* startup_list, | |
| 155 ListValue* referral_list, | |
| 156 base::WaitableEvent* completion); | |
| 157 | |
| 125 // For unit test code only. | 158 // For unit test code only. |
| 126 size_t max_concurrent_dns_lookups() const { | 159 size_t max_concurrent_dns_lookups() const { |
| 127 return max_concurrent_dns_lookups_; | 160 return max_concurrent_dns_lookups_; |
| 128 } | 161 } |
| 129 | 162 |
| 130 // Flag setting to use preconnection instead of just DNS pre-fetching. | 163 // Flag setting to use preconnection instead of just DNS pre-fetching. |
| 131 bool preconnect_enabled() const { return preconnect_enabled_; } | 164 bool preconnect_enabled() const { |
| 165 return preconnect_enabled_; | |
| 166 } | |
| 167 | |
| 168 // Flag setting for whether we are prefetching dns lookups. | |
| 169 bool predictor_enabled() const { | |
| 170 return predictor_enabled_; | |
| 171 } | |
| 172 | |
| 173 void EnablePredictor(bool enable) { | |
| 174 predictor_enabled_ = enable; | |
| 175 } | |
| 176 | |
| 177 // See variable description for explanation. | |
| 178 bool on_the_record() const { | |
| 179 return on_the_record_; | |
| 180 } | |
| 181 | |
| 182 void SetOnTheRecord(bool on_the_record) { | |
| 183 on_the_record_ = on_the_record; | |
| 184 } | |
| 185 | |
| 186 // Return value indicates whether to go back on the record. | |
| 187 bool HandleIncognitoBrowserClosed(); | |
| 188 | |
| 189 void HandleIncognitoBrowserOpened(); | |
| 132 | 190 |
| 133 // Put URL in canonical form, including a scheme, host, and port. | 191 // Put URL in canonical form, including a scheme, host, and port. |
| 134 // Returns GURL::EmptyGURL() if the scheme is not http/https or if the url | 192 // Returns GURL::EmptyGURL() if the scheme is not http/https or if the url |
| 135 // cannot be otherwise canonicalized. | 193 // cannot be otherwise canonicalized. |
| 136 static GURL CanonicalizeUrl(const GURL& url); | 194 static GURL CanonicalizeUrl(const GURL& url); |
| 137 | 195 |
| 196 static UrlList GetPredictedUrlListAtStartup(PrefService* user_prefs, | |
| 197 PrefService* local_state); | |
| 198 | |
| 138 private: | 199 private: |
| 139 friend class base::RefCountedThreadSafe<Predictor>; | 200 friend class base::RefCountedThreadSafe<Predictor>; |
| 140 FRIEND_TEST_ALL_PREFIXES(PredictorTest, BenefitLookupTest); | 201 FRIEND_TEST_ALL_PREFIXES(PredictorTest, BenefitLookupTest); |
| 141 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ShutdownWhenResolutionIsPendingTest); | 202 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ShutdownWhenResolutionIsPendingTest); |
| 142 FRIEND_TEST_ALL_PREFIXES(PredictorTest, SingleLookupTest); | 203 FRIEND_TEST_ALL_PREFIXES(PredictorTest, SingleLookupTest); |
| 143 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ConcurrentLookupTest); | 204 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ConcurrentLookupTest); |
| 144 FRIEND_TEST_ALL_PREFIXES(PredictorTest, MassiveConcurrentLookupTest); | 205 FRIEND_TEST_ALL_PREFIXES(PredictorTest, MassiveConcurrentLookupTest); |
| 145 FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueuePushPopTest); | 206 FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueuePushPopTest); |
| 146 FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueueReorderTest); | 207 FRIEND_TEST_ALL_PREFIXES(PredictorTest, PriorityQueueReorderTest); |
| 147 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ReferrerSerializationTrimTest); | 208 FRIEND_TEST_ALL_PREFIXES(PredictorTest, ReferrerSerializationTrimTest); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 169 private: | 230 private: |
| 170 // The names in the queue that should be serviced (popped) ASAP. | 231 // The names in the queue that should be serviced (popped) ASAP. |
| 171 std::queue<GURL> rush_queue_; | 232 std::queue<GURL> rush_queue_; |
| 172 // The names in the queue that should only be serviced when rush_queue is | 233 // The names in the queue that should only be serviced when rush_queue is |
| 173 // empty. | 234 // empty. |
| 174 std::queue<GURL> background_queue_; | 235 std::queue<GURL> background_queue_; |
| 175 | 236 |
| 176 DISALLOW_COPY_AND_ASSIGN(HostNameQueue); | 237 DISALLOW_COPY_AND_ASSIGN(HostNameQueue); |
| 177 }; | 238 }; |
| 178 | 239 |
| 240 // The InitialObserver monitors navigations made by the network stack. This | |
| 241 // is only used to identify startup time resolutions (for re-resolution | |
| 242 // during our next process startup). | |
| 243 // TODO(jar): Consider preconnecting at startup, which may be faster than | |
| 244 // waiting for render process to start and request a connection. | |
| 245 class InitialObserver { | |
| 246 public: | |
| 247 // Recording of when we observed each navigation. | |
| 248 typedef std::map<GURL, base::TimeTicks> FirstNavigations; | |
| 249 | |
| 250 // Potentially add a new URL to our startup list. | |
| 251 void Append(const GURL& url, Predictor* predictor); | |
| 252 | |
| 253 // Get an HTML version of our current planned first_navigations_. | |
| 254 void GetFirstResolutionsHtml(std::string* output); | |
| 255 | |
| 256 // Persist the current first_navigations_ for storage in a list. | |
| 257 void GetInitialDnsResolutionList(ListValue* startup_list); | |
| 258 | |
| 259 // Discards all initial loading history. | |
| 260 void DiscardInitialNavigationHistory() { first_navigations_.clear(); } | |
| 261 | |
| 262 private: | |
| 263 // List of the first N URL resolutions observed in this run. | |
| 264 FirstNavigations first_navigations_; | |
| 265 | |
| 266 // The number of URLs we'll save for pre-resolving at next startup. | |
| 267 static const size_t kStartupResolutionCount = 10; | |
| 268 }; | |
| 269 | |
| 179 // A map that is keyed with the host/port that we've learned were the cause | 270 // A map that is keyed with the host/port that we've learned were the cause |
| 180 // of loading additional URLs. The list of additional targets is held | 271 // of loading additional URLs. The list of additional targets is held |
| 181 // in a Referrer instance, which is a value in this map. | 272 // in a Referrer instance, which is a value in this map. |
| 182 typedef std::map<GURL, Referrer> Referrers; | 273 typedef std::map<GURL, Referrer> Referrers; |
| 183 | 274 |
| 184 // Depending on the expected_subresource_use_, we may either make a TCP/IP | 275 // Depending on the expected_subresource_use_, we may either make a TCP/IP |
| 185 // preconnection, or merely pre-resolve the hostname via DNS (or even do | 276 // preconnection, or merely pre-resolve the hostname via DNS (or even do |
| 186 // nothing). The following are the threasholds for taking those actions. | 277 // nothing). The following are the threasholds for taking those actions. |
| 187 static const double kPreconnectWorthyExpectedValue; | 278 static const double kPreconnectWorthyExpectedValue; |
| 188 static const double kDNSPreresolutionWorthyExpectedValue; | 279 static const double kDNSPreresolutionWorthyExpectedValue; |
| 189 // Referred hosts with a subresource_use_rate_ that are less than the | 280 // Referred hosts with a subresource_use_rate_ that are less than the |
| 190 // following threshold will be discarded when we Trim() the list. | 281 // following threshold will be discarded when we Trim() the list. |
| 191 static const double kDiscardableExpectedValue; | 282 static const double kDiscardableExpectedValue; |
| 192 // During trimming operation to discard hosts for which we don't have likely | 283 // During trimming operation to discard hosts for which we don't have likely |
| 193 // subresources, we multiply the expected_subresource_use_ value by the | 284 // subresources, we multiply the expected_subresource_use_ value by the |
| 194 // following ratio until that value is less than kDiscardableExpectedValue. | 285 // following ratio until that value is less than kDiscardableExpectedValue. |
| 195 // This number should always be less than 1, an more than 0. | 286 // This number should always be less than 1, an more than 0. |
| 196 static const double kReferrerTrimRatio; | 287 static const double kReferrerTrimRatio; |
| 197 | 288 |
| 198 // Interval between periodic trimming of our whole referrer list. | 289 // Interval between periodic trimming of our whole referrer list. |
| 199 // We only do a major trimming about once an hour, and then only when the user | 290 // We only do a major trimming about once an hour, and then only when the user |
| 200 // is actively browsing. | 291 // is actively browsing. |
| 201 static const base::TimeDelta kDurationBetweenTrimmings; | 292 static const base::TimeDelta kDurationBetweenTrimmings; |
| 202 // Interval between incremental trimmings (to avoid inducing Jank). | 293 // Interval between incremental trimmings (to avoid inducing Jank). |
| 203 static const base::TimeDelta kDurationBetweenTrimmingIncrements; | 294 static const base::TimeDelta kDurationBetweenTrimmingIncrements; |
| 204 // Number of referring URLs processed in an incremental trimming. | 295 // Number of referring URLs processed in an incremental trimming. |
| 205 static const size_t kUrlsTrimmedPerIncrement; | 296 static const size_t kUrlsTrimmedPerIncrement; |
| 206 | 297 |
| 207 ~Predictor(); | |
| 208 | |
| 209 // Perform actual resolution or preconnection to subresources now. This is | 298 // Perform actual resolution or preconnection to subresources now. This is |
| 210 // an internal worker method that is reached via a post task from | 299 // an internal worker method that is reached via a post task from |
| 211 // PredictFrameSubresources(). | 300 // PredictFrameSubresources(). |
| 212 void PrepareFrameSubresources(const GURL& url); | 301 void PrepareFrameSubresources(const GURL& url); |
| 213 | 302 |
| 214 // Only for testing. Returns true if hostname has been successfully resolved | 303 // Only for testing. Returns true if hostname has been successfully resolved |
| 215 // (name found). | 304 // (name found). |
| 216 bool WasFound(const GURL& url) const { | 305 bool WasFound(const GURL& url) const { |
| 217 Results::const_iterator it(results_.find(url)); | 306 Results::const_iterator it(results_.find(url)); |
| 218 return (it != results_.end()) && | 307 return (it != results_.end()) && |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 268 void LoadUrlsForTrimming(); | 357 void LoadUrlsForTrimming(); |
| 269 | 358 |
| 270 // Posts a task to do additional incremental trimming of referrers_. | 359 // Posts a task to do additional incremental trimming of referrers_. |
| 271 void PostIncrementalTrimTask(); | 360 void PostIncrementalTrimTask(); |
| 272 | 361 |
| 273 // Calls Trim() on some or all of urls_being_trimmed_. | 362 // Calls Trim() on some or all of urls_being_trimmed_. |
| 274 // If it does not process all the URLs in that vector, it posts a task to | 363 // If it does not process all the URLs in that vector, it posts a task to |
| 275 // continue with them shortly (i.e., it yeilds and continues). | 364 // continue with them shortly (i.e., it yeilds and continues). |
| 276 void IncrementalTrimReferrers(bool trim_all_now); | 365 void IncrementalTrimReferrers(bool trim_all_now); |
| 277 | 366 |
| 367 scoped_ptr<InitialObserver> initial_observer_; | |
| 368 | |
| 369 // Status of speculative DNS resolution and speculative TCP/IP connection | |
| 370 // feature. | |
| 371 bool predictor_enabled_; | |
| 372 | |
| 373 // If there are any incognito windows at all, we don't want to keep prefetch | |
| 374 // information since it would be visible in about:dns, for example. | |
| 375 int off_the_record_windows_count_; | |
| 376 | |
| 377 // Cached inverted copy of the off_the_record pref. | |
| 378 bool on_the_record_; | |
| 379 | |
| 278 // work_queue_ holds a list of names we need to look up. | 380 // work_queue_ holds a list of names we need to look up. |
| 279 HostNameQueue work_queue_; | 381 HostNameQueue work_queue_; |
| 280 | 382 |
| 281 // results_ contains information for existing/prior prefetches. | 383 // results_ contains information for existing/prior prefetches. |
| 282 Results results_; | 384 Results results_; |
| 283 | 385 |
| 284 std::set<LookupRequest*> pending_lookups_; | 386 std::set<LookupRequest*> pending_lookups_; |
| 285 | 387 |
| 286 // For testing, to verify that we don't exceed the limit. | 388 // For testing, to verify that we don't exceed the limit. |
| 287 size_t peak_pending_lookups_; | 389 size_t peak_pending_lookups_; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 base::TimeTicks next_trim_time_; | 435 base::TimeTicks next_trim_time_; |
| 334 | 436 |
| 335 ScopedRunnableMethodFactory<Predictor> trim_task_factory_; | 437 ScopedRunnableMethodFactory<Predictor> trim_task_factory_; |
| 336 | 438 |
| 337 DISALLOW_COPY_AND_ASSIGN(Predictor); | 439 DISALLOW_COPY_AND_ASSIGN(Predictor); |
| 338 }; | 440 }; |
| 339 | 441 |
| 340 } // namespace chrome_browser_net | 442 } // namespace chrome_browser_net |
| 341 | 443 |
| 342 #endif // CHROME_BROWSER_NET_PREDICTOR_H_ | 444 #endif // CHROME_BROWSER_NET_PREDICTOR_H_ |
| OLD | NEW |