OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/precache/core/precache_fetcher.h" | 5 #include "components/precache/core/precache_fetcher.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/containers/hash_tables.h" | 14 #include "base/containers/hash_tables.h" |
15 #include "base/metrics/histogram_macros.h" | |
15 #include "components/precache/core/precache_switches.h" | 16 #include "components/precache/core/precache_switches.h" |
16 #include "components/precache/core/proto/precache.pb.h" | 17 #include "components/precache/core/proto/precache.pb.h" |
17 #include "net/base/escape.h" | 18 #include "net/base/escape.h" |
18 #include "net/base/load_flags.h" | 19 #include "net/base/load_flags.h" |
19 #include "net/url_request/url_fetcher.h" | 20 #include "net/url_request/url_fetcher.h" |
20 #include "net/url_request/url_fetcher_delegate.h" | 21 #include "net/url_request/url_fetcher_delegate.h" |
21 #include "net/url_request/url_request_context_getter.h" | 22 #include "net/url_request/url_request_context_getter.h" |
22 #include "net/url_request/url_request_status.h" | 23 #include "net/url_request/url_request_status.h" |
23 | 24 |
24 using net::URLFetcher; | 25 using net::URLFetcher; |
25 | 26 |
26 namespace precache { | 27 namespace precache { |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
31 // The 99%ile number of bytes we expect to receive during prefetch, and the max | |
bengr
2015/06/30 19:26:19
99%ile -> 99th percentile
and the max -> which wi
twifkak
2015/06/30 20:23:51
Done.
| |
32 // for the histogram. | |
33 const int kMaxResponseBytes = 100 * 1024 * 1024; | |
34 | |
30 GURL GetConfigURL() { | 35 GURL GetConfigURL() { |
31 const base::CommandLine& command_line = | 36 const base::CommandLine& command_line = |
32 *base::CommandLine::ForCurrentProcess(); | 37 *base::CommandLine::ForCurrentProcess(); |
33 if (command_line.HasSwitch(switches::kPrecacheConfigSettingsURL)) { | 38 if (command_line.HasSwitch(switches::kPrecacheConfigSettingsURL)) { |
34 return GURL( | 39 return GURL( |
35 command_line.GetSwitchValueASCII(switches::kPrecacheConfigSettingsURL)); | 40 command_line.GetSwitchValueASCII(switches::kPrecacheConfigSettingsURL)); |
36 } | 41 } |
37 | 42 |
38 #if defined(PRECACHE_CONFIG_SETTINGS_URL) | 43 #if defined(PRECACHE_CONFIG_SETTINGS_URL) |
39 return GURL(PRECACHE_CONFIG_SETTINGS_URL); | 44 return GURL(PRECACHE_CONFIG_SETTINGS_URL); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 // response to different kinds of fetches, e.g. OnConfigFetchComplete when | 106 // response to different kinds of fetches, e.g. OnConfigFetchComplete when |
102 // configuration settings are fetched, OnManifestFetchComplete when a manifest | 107 // configuration settings are fetched, OnManifestFetchComplete when a manifest |
103 // is fetched, etc. | 108 // is fetched, etc. |
104 class PrecacheFetcher::Fetcher : public net::URLFetcherDelegate { | 109 class PrecacheFetcher::Fetcher : public net::URLFetcherDelegate { |
105 public: | 110 public: |
106 // Construct a new Fetcher. This will create and start a new URLFetcher for | 111 // Construct a new Fetcher. This will create and start a new URLFetcher for |
107 // the specified URL using the specified request context. | 112 // the specified URL using the specified request context. |
108 Fetcher(net::URLRequestContextGetter* request_context, const GURL& url, | 113 Fetcher(net::URLRequestContextGetter* request_context, const GURL& url, |
109 const base::Callback<void(const URLFetcher&)>& callback); | 114 const base::Callback<void(const URLFetcher&)>& callback); |
110 ~Fetcher() override {} | 115 ~Fetcher() override {} |
116 void OnURLFetchDownloadProgress(const URLFetcher* source, | |
117 int64 current, | |
118 int64 total) override; | |
111 void OnURLFetchComplete(const URLFetcher* source) override; | 119 void OnURLFetchComplete(const URLFetcher* source) override; |
120 int response_bytes() { return response_bytes_; } | |
112 | 121 |
113 private: | 122 private: |
114 const base::Callback<void(const URLFetcher&)> callback_; | 123 const base::Callback<void(const URLFetcher&)> callback_; |
115 scoped_ptr<URLFetcher> url_fetcher_; | 124 scoped_ptr<URLFetcher> url_fetcher_; |
125 int response_bytes_; | |
116 | 126 |
117 DISALLOW_COPY_AND_ASSIGN(Fetcher); | 127 DISALLOW_COPY_AND_ASSIGN(Fetcher); |
118 }; | 128 }; |
119 | 129 |
120 PrecacheFetcher::Fetcher::Fetcher( | 130 PrecacheFetcher::Fetcher::Fetcher( |
121 net::URLRequestContextGetter* request_context, const GURL& url, | 131 net::URLRequestContextGetter* request_context, |
132 const GURL& url, | |
122 const base::Callback<void(const URLFetcher&)>& callback) | 133 const base::Callback<void(const URLFetcher&)>& callback) |
123 : callback_(callback) { | 134 : callback_(callback), response_bytes_(0) { |
124 url_fetcher_ = URLFetcher::Create(url, URLFetcher::GET, this); | 135 url_fetcher_ = URLFetcher::Create(url, URLFetcher::GET, this); |
125 url_fetcher_->SetRequestContext(request_context); | 136 url_fetcher_->SetRequestContext(request_context); |
126 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | | 137 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | |
127 net::LOAD_DO_NOT_SEND_COOKIES); | 138 net::LOAD_DO_NOT_SEND_COOKIES); |
128 url_fetcher_->Start(); | 139 url_fetcher_->Start(); |
129 } | 140 } |
130 | 141 |
142 void PrecacheFetcher::Fetcher::OnURLFetchDownloadProgress( | |
143 const URLFetcher* source, | |
144 int64 current, | |
145 int64 total) { | |
146 response_bytes_ = current; | |
147 } | |
148 | |
131 void PrecacheFetcher::Fetcher::OnURLFetchComplete(const URLFetcher* source) { | 149 void PrecacheFetcher::Fetcher::OnURLFetchComplete(const URLFetcher* source) { |
132 callback_.Run(*source); | 150 callback_.Run(*source); |
133 } | 151 } |
134 | 152 |
135 PrecacheFetcher::PrecacheFetcher( | 153 PrecacheFetcher::PrecacheFetcher( |
136 const std::vector<std::string>& starting_hosts, | 154 const std::vector<std::string>& starting_hosts, |
137 net::URLRequestContextGetter* request_context, | 155 net::URLRequestContextGetter* request_context, |
138 const std::string& manifest_url_prefix, | 156 const std::string& manifest_url_prefix, |
139 PrecacheFetcher::PrecacheDelegate* precache_delegate) | 157 PrecacheFetcher::PrecacheDelegate* precache_delegate) |
140 : starting_hosts_(starting_hosts), | 158 : starting_hosts_(starting_hosts), |
141 request_context_(request_context), | 159 request_context_(request_context), |
142 manifest_url_prefix_(manifest_url_prefix), | 160 manifest_url_prefix_(manifest_url_prefix), |
143 precache_delegate_(precache_delegate) { | 161 precache_delegate_(precache_delegate), |
162 total_response_bytes_(0), | |
163 num_manifest_urls_to_fetch_(0) { | |
144 DCHECK(request_context_.get()); // Request context must be non-NULL. | 164 DCHECK(request_context_.get()); // Request context must be non-NULL. |
145 DCHECK(precache_delegate_); // Precache delegate must be non-NULL. | 165 DCHECK(precache_delegate_); // Precache delegate must be non-NULL. |
146 | 166 |
147 DCHECK_NE(GURL(), GetConfigURL()) | 167 DCHECK_NE(GURL(), GetConfigURL()) |
148 << "Could not determine the precache config settings URL."; | 168 << "Could not determine the precache config settings URL."; |
149 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix()) | 169 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix()) |
150 << "Could not determine the default precache manifest URL prefix."; | 170 << "Could not determine the default precache manifest URL prefix."; |
151 } | 171 } |
152 | 172 |
153 PrecacheFetcher::~PrecacheFetcher() { | 173 PrecacheFetcher::~PrecacheFetcher() { |
174 // Number of manifests for which we have downloaded all resources. | |
175 int manifests_completed = | |
176 num_manifest_urls_to_fetch_ - manifest_urls_to_fetch_.size(); | |
177 | |
178 // If there are resource URLs left to fetch, the last manifest is not yet | |
179 // completed. | |
180 if (!resource_urls_to_fetch_.empty()) | |
181 --manifests_completed; | |
182 | |
183 int percent_completed = | |
184 manifests_completed == 0 ? 0 : (static_cast<double>(manifests_completed) / | |
185 num_manifest_urls_to_fetch_ * 100); | |
bengr
2015/06/30 19:26:19
Can num_manifest_urls_to_fetch_ be 0?
twifkak
2015/06/30 20:23:51
Yes, but if num_manifests_urls_to_fetch_ is 0, so
bengr
2015/07/06 17:31:08
DCHECK(num_manifest_urls_to_fetch_ >= manifests_co
twifkak
2015/07/07 00:26:28
OK, added a different DCHECK, but changed the cond
| |
186 UMA_HISTOGRAM_PERCENTAGE("Precache.Fetch.PercentCompleted", | |
187 percent_completed); | |
188 UMA_HISTOGRAM_CUSTOM_COUNTS("Precache.Fetch.ResponseBytes", | |
189 total_response_bytes_, 1, kMaxResponseBytes, 50); | |
154 } | 190 } |
155 | 191 |
156 void PrecacheFetcher::Start() { | 192 void PrecacheFetcher::Start() { |
157 DCHECK(!fetcher_); // Start shouldn't be called repeatedly. | 193 DCHECK(!fetcher_); // Start shouldn't be called repeatedly. |
158 | 194 |
159 GURL config_url = GetConfigURL(); | 195 GURL config_url = GetConfigURL(); |
160 DCHECK(config_url.is_valid()); | 196 DCHECK(config_url.is_valid()); |
161 | 197 |
162 // Fetch the precache configuration settings from the server. | 198 // Fetch the precache configuration settings from the server. |
163 fetcher_.reset(new Fetcher(request_context_.get(), | 199 fetcher_.reset(new Fetcher(request_context_.get(), |
164 config_url, | 200 config_url, |
165 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, | 201 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, |
166 base::Unretained(this)))); | 202 base::Unretained(this)))); |
167 } | 203 } |
168 | 204 |
169 void PrecacheFetcher::StartNextFetch() { | 205 void PrecacheFetcher::StartNextFetch() { |
206 total_response_bytes_ += fetcher_->response_bytes(); | |
207 | |
170 if (!resource_urls_to_fetch_.empty()) { | 208 if (!resource_urls_to_fetch_.empty()) { |
171 // Fetch the next resource URL. | 209 // Fetch the next resource URL. |
172 fetcher_.reset( | 210 fetcher_.reset( |
173 new Fetcher(request_context_.get(), | 211 new Fetcher(request_context_.get(), |
174 resource_urls_to_fetch_.front(), | 212 resource_urls_to_fetch_.front(), |
175 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, | 213 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, |
176 base::Unretained(this)))); | 214 base::Unretained(this)))); |
177 | 215 |
178 resource_urls_to_fetch_.pop_front(); | 216 resource_urls_to_fetch_.pop_front(); |
179 return; | 217 return; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 if (rank > config.top_sites_count()) | 260 if (rank > config.top_sites_count()) |
223 break; | 261 break; |
224 unique_manifest_urls.insert(ConstructManifestURL(prefix, host)); | 262 unique_manifest_urls.insert(ConstructManifestURL(prefix, host)); |
225 } | 263 } |
226 | 264 |
227 for (const std::string& url : config.forced_site()) | 265 for (const std::string& url : config.forced_site()) |
228 unique_manifest_urls.insert(ConstructManifestURL(prefix, url)); | 266 unique_manifest_urls.insert(ConstructManifestURL(prefix, url)); |
229 | 267 |
230 for (const std::string& manifest_url : unique_manifest_urls) | 268 for (const std::string& manifest_url : unique_manifest_urls) |
231 manifest_urls_to_fetch_.push_back(GURL(manifest_url)); | 269 manifest_urls_to_fetch_.push_back(GURL(manifest_url)); |
270 num_manifest_urls_to_fetch_ = manifest_urls_to_fetch_.size(); | |
232 | 271 |
233 StartNextFetch(); | 272 StartNextFetch(); |
234 } | 273 } |
235 | 274 |
236 void PrecacheFetcher::OnManifestFetchComplete(const URLFetcher& source) { | 275 void PrecacheFetcher::OnManifestFetchComplete(const URLFetcher& source) { |
237 PrecacheManifest manifest; | 276 PrecacheManifest manifest; |
238 | 277 |
239 if (ParseProtoFromFetchResponse(source, &manifest)) { | 278 if (ParseProtoFromFetchResponse(source, &manifest)) { |
240 for (int i = 0; i < manifest.resource_size(); ++i) { | 279 for (int i = 0; i < manifest.resource_size(); ++i) { |
241 if (manifest.resource(i).has_url()) { | 280 if (manifest.resource(i).has_url()) { |
242 resource_urls_to_fetch_.push_back(GURL(manifest.resource(i).url())); | 281 resource_urls_to_fetch_.push_back(GURL(manifest.resource(i).url())); |
243 } | 282 } |
244 } | 283 } |
245 } | 284 } |
246 | 285 |
247 StartNextFetch(); | 286 StartNextFetch(); |
248 } | 287 } |
249 | 288 |
250 void PrecacheFetcher::OnResourceFetchComplete(const URLFetcher& source) { | 289 void PrecacheFetcher::OnResourceFetchComplete(const URLFetcher& source) { |
251 // The resource has already been put in the cache during the fetch process, so | 290 // The resource has already been put in the cache during the fetch process, so |
252 // nothing more needs to be done for the resource. | 291 // nothing more needs to be done for the resource. |
253 StartNextFetch(); | 292 StartNextFetch(); |
254 } | 293 } |
255 | 294 |
256 } // namespace precache | 295 } // namespace precache |
OLD | NEW |