Index: chrome/browser/net/predictor.h |
=================================================================== |
--- chrome/browser/net/predictor.h (revision 96503) |
+++ chrome/browser/net/predictor.h (working copy) |
@@ -27,7 +27,7 @@ |
#include <vector> |
#include "base/gtest_prod_util.h" |
-#include "base/memory/ref_counted.h" |
+#include "base/memory/scoped_ptr.h" |
#include "chrome/browser/net/url_info.h" |
#include "chrome/browser/net/referrer.h" |
#include "chrome/common/net/predictor_common.h" |
@@ -37,10 +37,18 @@ |
class ListValue; |
} |
+namespace base { |
+class WaitableEvent; |
+} |
+ |
namespace net { |
class HostResolver; |
} // namespace net |
+class IOThread; |
+class PrefService; |
+class Profile; |
+ |
namespace chrome_browser_net { |
typedef chrome_common_net::UrlList UrlList; |
@@ -49,7 +57,7 @@ |
// Note that Predictor is not thread safe, and must only be called from |
// the IO thread. Failure to do so will result in a DCHECK at runtime. |
willchan no longer on Chromium
2011/08/12 21:51:47
You should update this comment. You should have so
rpetterson
2011/08/13 00:55:17
Done.
|
-class Predictor : public base::RefCountedThreadSafe<Predictor> { |
+class Predictor { |
public: |
// A version number for prefs that are saved. This should be incremented when |
// we change the format so that we discard old data. |
@@ -57,53 +65,74 @@ |
// |max_concurrent| specifies how many concurrent (parallel) prefetches will |
// be performed. Host lookups will be issued through |host_resolver|. |
- Predictor(net::HostResolver* host_resolver, |
- base::TimeDelta max_queue_delay_ms, size_t max_concurrent, |
- bool preconnect_enabled); |
+ Predictor(); |
+ virtual ~Predictor(); |
+ |
+ // ------------- Start UI thread methods. |
+ |
+ virtual void InitNetworkPredictor(PrefService* user_prefs); |
+ |
+ // The Omnibox has proposed a given url to the user, and if it is a search |
+ // URL, then it also indicates that this is preconnectable (i.e., we could |
+ // preconnect to the search server). |
+ virtual void AnticipateOmniboxUrl(const GURL& url, bool preconnectable); |
+ |
+ // Preconnect a URL and all of its subresource domains. |
+ virtual void PreconnectUrlAndSubresources(const GURL& url); |
+ |
+ // Instigate pre-connection to any URLs, or pre-resolution of related host, |
+ // that we predict will be needed after this navigation (typically |
+ // more-embedded resources on a page). This method will actually post a task |
+ // to do the actual work, so as not to jump ahead of the frame navigation that |
+ // instigated this activity. |
+ virtual void PredictFrameSubresources(const GURL& url); |
+ |
+ static UrlList GetPredictedUrlListAtStartup(PrefService* user_prefs, |
+ PrefService* local_state); |
+ |
+ static void set_max_queueing_delay(int max_queueing_delay_ms); |
+ |
+ static void set_max_parallel_resolves(size_t max_parallel_resolves); |
+ |
+ static void RegisterUserPrefs(PrefService* user_prefs); |
+ |
+ virtual void ShutdownOnUIThread(PrefService* user_prefs); |
+ |
+ // ------------- End UI thread methods. |
+ |
+ // ------------- Start IO thread methods. |
+ |
// Cancel pending requests and prevent new ones from being made. |
- void Shutdown(); |
+ virtual void Shutdown(); |
// In some circumstances, for privacy reasons, all results should be |
// discarded. This method gracefully handles that activity. |
// Destroy all our internal state, which shows what names we've looked up, and |
// how long each has taken, etc. etc. We also destroy records of suggesses |
// (cache hits etc.). |
- void DiscardAllResults(); |
+ virtual void DiscardAllResults(); |
// Add hostname(s) to the queue for processing. |
- void ResolveList(const UrlList& urls, |
- UrlInfo::ResolutionMotivation motivation); |
- void Resolve(const GURL& url, |
- UrlInfo::ResolutionMotivation motivation); |
+ virtual void ResolveList(const UrlList& urls, |
+ UrlInfo::ResolutionMotivation motivation); |
- // Instigate pre-connection to any URLs, or pre-resolution of related host, |
- // that we predict will be needed after this navigation (typically |
- // more-embedded resources on a page). This method will actually post a task |
- // to do the actual work, so as not to jump ahead of the frame navigation that |
- // instigated this activity. |
- void PredictFrameSubresources(const GURL& url); |
+ virtual void Resolve(const GURL& url, |
+ UrlInfo::ResolutionMotivation motivation); |
- // The Omnibox has proposed a given url to the user, and if it is a search |
- // URL, then it also indicates that this is preconnectable (i.e., we could |
- // preconnect to the search server). |
- void AnticipateOmniboxUrl(const GURL& url, bool preconnectable); |
- |
- // Preconnect a URL and all of its subresource domains. |
- void PreconnectUrlAndSubresources(const GURL& url); |
- |
// Record details of a navigation so that we can preresolve the host name |
// ahead of time the next time the users navigates to the indicated host. |
// Should only be called when urls are distinct, and they should already be |
// canonicalized to not have a path. |
- void LearnFromNavigation(const GURL& referring_url, const GURL& target_url); |
+ virtual void LearnFromNavigation(const GURL& referring_url, |
+ const GURL& target_url); |
// Dump HTML table containing list of referrers for about:dns. |
- void GetHtmlReferrerLists(std::string* output); |
+ virtual void GetHtmlReferrerLists(std::string* output); |
// Dump the list of currently known referrer domains and related prefetchable |
// domains. |
- void GetHtmlInfo(std::string* output); |
+ virtual void GetHtmlInfo(std::string* output); |
// Discards any referrer for which all the suggested host names are currently |
// annotated with negligible expected-use. Scales down (diminishes) the |
@@ -111,32 +140,106 @@ |
// factor each time we trim (moving the referrer closer to being discarded in |
// a future call). |
// The task is performed synchronously and completes before returing. |
- void TrimReferrersNow(); |
+ virtual void TrimReferrersNow(); |
// Construct a ListValue object that contains all the data in the referrers_ |
// so that it can be persisted in a pref. |
- void SerializeReferrers(base::ListValue* referral_list); |
+ virtual void SerializeReferrers(base::ListValue* referral_list); |
// Process a ListValue that contains all the data from a previous reference |
// list, as constructed by SerializeReferrers(), and add all the identified |
// values into the current referrer list. |
- void DeserializeReferrers(const base::ListValue& referral_list); |
+ virtual void DeserializeReferrers(const base::ListValue& referral_list); |
- void DeserializeReferrersThenDelete(base::ListValue* referral_list); |
+ virtual void DeserializeReferrersThenDelete(base::ListValue* referral_list); |
- // For unit test code only. |
- size_t max_concurrent_dns_lookups() const { |
- return max_concurrent_dns_lookups_; |
- } |
+ virtual void DiscardInitialNavigationHistory(); |
- // Flag setting to use preconnection instead of just DNS pre-fetching. |
- bool preconnect_enabled() const { return preconnect_enabled_; } |
+ virtual void FinalizeInitializationOnIOThread( |
+ const std::vector<GURL>& urls_to_prefetch, |
+ base::ListValue* referral_list, |
+ IOThread* io_thread); |
+ // During startup, we learn what the first N urls visited are, and then |
+ // resolve the associated hosts ASAP during our next startup. |
+ virtual void LearnAboutInitialNavigation(const GURL& url); |
+ |
+ // Renderer bundles up list and sends to this browser API via IPC. |
+ // TODO(jar): Use UrlList instead to include port and scheme. |
+ virtual void DnsPrefetchList(const NameList& hostnames); |
+ |
+ // May be called from either the IO or UI thread and will PostTask |
+ // to the IO thread if necessary. |
+ virtual void Predictor::DnsPrefetchMotivatedList( |
+ const UrlList& urls, |
+ UrlInfo::ResolutionMotivation motivation); |
+ |
+ // May be called from either the IO or UI thread and will PostTask |
+ // to the IO thread if necessary. |
+ virtual void SaveStateForNextStartupAndTrim(PrefService* prefs); |
+ |
+ virtual void SaveDnsPrefetchStateForNextStartupAndTrim( |
+ base::ListValue* startup_list, |
+ base::ListValue* referral_list, |
+ base::WaitableEvent* completion); |
+ |
+ // May be called from either the IO or UI thread and will PostTask |
+ // to the IO thread if necessary. |
+ virtual void EnablePredictor(bool enable); |
+ |
+ virtual void EnablePredictorOnIOThread(bool enable); |
+ |
+ // ------------- End IO thread methods. |
+ |
+ // The following methods may be called on either the IO or UI threads. |
+ |
// Put URL in canonical form, including a scheme, host, and port. |
// Returns GURL::EmptyGURL() if the scheme is not http/https or if the url |
// cannot be otherwise canonicalized. |
static GURL CanonicalizeUrl(const GURL& url); |
+ // Used for testing. |
+ void SetHostResolver(net::HostResolver* host_resolver) { |
+ host_resolver_ = host_resolver; |
+ } |
+ // Used for testing. |
+ size_t max_concurrent_dns_lookups() const { |
+ return max_concurrent_dns_lookups_; |
+ } |
+ |
+ // Flag setting to use preconnection instead of just DNS pre-fetching. |
+ bool preconnect_enabled() const { |
+ return preconnect_enabled_; |
+ } |
+ |
+ // Flag setting for whether we are prefetching dns lookups. |
+ bool predictor_enabled() const { |
+ return predictor_enabled_; |
+ } |
+ |
+ // Given that the underlying Chromium resolver defaults to a total maximum of |
willchan no longer on Chromium
2011/08/12 21:17:29
constants go above methods in class declaration or
rpetterson
2011/08/13 00:55:17
Done.
|
+ // 8 paralell resolutions, we will avoid any chance of starving navigational |
+ // resolutions by limiting the number of paralell speculative resolutions. |
+ // This is used in the field trials and testing. |
+ // TODO(jar): Move this limitation into the resolver. |
+ static const size_t kMaxSpeculativeParallelResolves; |
+ |
+ // To control the congestion avoidance system, we need an estimate of how |
+ // many speculative requests may arrive at once. Since we currently only |
+ // keep 8 subresource names for each frame, we'll use that as our basis. |
+ // Note that when scanning search results lists, we might actually get 10 at |
+ // a time, and wikipedia can often supply (during a page scan) upwards of 50. |
+ // In those odd cases, we may discard some of the later speculative requests |
+ // mistakenly assuming that the resolutions took too long. |
+ static const int kTypicalSpeculativeGroupSize; |
+ |
+// The next constant specifies an amount of queueing delay that is |
+// "too large," and indicative of problems with resolutions (perhaps due to |
+// an overloaded router, or such). When we exceed this delay, congestion |
+// avoidance will kick in and all speculations in the queue will be discarded. |
+ static const int kMaxSpeculativeResolveQueueDelayMs; |
+ |
+ |
private: |
friend class base::RefCountedThreadSafe<Predictor>; |
willchan no longer on Chromium
2011/08/12 21:17:29
Remove this
rpetterson
2011/08/13 00:55:17
Done.
|
FRIEND_TEST_ALL_PREFIXES(PredictorTest, BenefitLookupTest); |
@@ -178,6 +281,36 @@ |
DISALLOW_COPY_AND_ASSIGN(HostNameQueue); |
}; |
+ // The InitialObserver monitors navigations made by the network stack. This |
+ // is only used to identify startup time resolutions (for re-resolution |
+ // during our next process startup). |
+ // TODO(jar): Consider preconnecting at startup, which may be faster than |
+ // waiting for render process to start and request a connection. |
+ class InitialObserver { |
+ public: |
+ // Recording of when we observed each navigation. |
+ typedef std::map<GURL, base::TimeTicks> FirstNavigations; |
+ |
+ // Potentially add a new URL to our startup list. |
+ void Append(const GURL& url, Predictor* predictor); |
+ |
+ // Get an HTML version of our current planned first_navigations_. |
+ void GetFirstResolutionsHtml(std::string* output); |
+ |
+ // Persist the current first_navigations_ for storage in a list. |
+ void GetInitialDnsResolutionList(base::ListValue* startup_list); |
+ |
+ // Discards all initial loading history. |
+ void DiscardInitialNavigationHistory() { first_navigations_.clear(); } |
+ |
+ private: |
+ // List of the first N URL resolutions observed in this run. |
+ FirstNavigations first_navigations_; |
+ |
+ // The number of URLs we'll save for pre-resolving at next startup. |
+ static const size_t kStartupResolutionCount = 10; |
+ }; |
+ |
// A map that is keyed with the host/port that we've learned were the cause |
// of loading additional URLs. The list of additional targets is held |
// in a Referrer instance, which is a value in this map. |
@@ -206,13 +339,6 @@ |
// Number of referring URLs processed in an incremental trimming. |
static const size_t kUrlsTrimmedPerIncrement; |
- ~Predictor(); |
- |
- // Perform actual resolution or preconnection to subresources now. This is |
- // an internal worker method that is reached via a post task from |
- // PredictFrameSubresources(). |
- void PrepareFrameSubresources(const GURL& url); |
- |
// Only for testing. Returns true if hostname has been successfully resolved |
// (name found). |
bool WasFound(const GURL& url) const { |
@@ -232,6 +358,13 @@ |
// Only for testing; |
size_t peak_pending_lookups() const { return peak_pending_lookups_; } |
+ // ------------- Start IO thread methods. |
+ |
+ // Perform actual resolution or preconnection to subresources now. This is |
+ // an internal worker method that is reached via a post task from |
+ // PredictFrameSubresources(). |
+ void PrepareFrameSubresources(const GURL& url); |
+ |
// Access method for use by async lookup request to pass resolution result. |
void OnLookupFinished(LookupRequest* request, const GURL& url, bool found); |
@@ -277,6 +410,14 @@ |
// continue with them shortly (i.e., it yeilds and continues). |
void IncrementalTrimReferrers(bool trim_all_now); |
+ // ------------- End IO thread methods. |
+ |
+ scoped_ptr<InitialObserver> initial_observer_; |
+ |
+ // Status of speculative DNS resolution and speculative TCP/IP connection |
+ // feature. |
+ bool predictor_enabled_; |
+ |
// work_queue_ holds a list of names we need to look up. |
HostNameQueue work_queue_; |
@@ -302,7 +443,7 @@ |
const base::TimeDelta max_dns_queue_delay_; |
// The host resolver we warm DNS entries for. |
- net::HostResolver* const host_resolver_; |
+ net::HostResolver* host_resolver_; |
// Are we currently using preconnection, rather than just DNS resolution, for |
// subresources and omni-box search URLs. |
@@ -334,7 +475,7 @@ |
// A time after which we need to do more trimming of referrers. |
base::TimeTicks next_trim_time_; |
- ScopedRunnableMethodFactory<Predictor> trim_task_factory_; |
+ scoped_ptr<ScopedRunnableMethodFactory<Predictor> > trim_task_factory_; |
DISALLOW_COPY_AND_ASSIGN(Predictor); |
}; |