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

Side by Side Diff: components/precache/core/precache_fetcher.cc

Issue 1859023002: Fix PrecacheFetcher behavior when reaching max_bytes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Extract AppendManifestURLIfNew(). Created 4 years, 8 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 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 <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 int num_bytes, 132 int num_bytes,
133 const net::CompletionCallback& callback) override { 133 const net::CompletionCallback& callback) override {
134 return num_bytes; 134 return num_bytes;
135 } 135 }
136 136
137 int Finish(const net::CompletionCallback& callback) override { 137 int Finish(const net::CompletionCallback& callback) override {
138 return net::OK; 138 return net::OK;
139 } 139 }
140 }; 140 };
141 141
142 void AppendManifestURLIfNew(const std::string& prefix,
143 const std::string& name,
144 base::hash_set<std::string>* seen_manifest_urls,
145 std::list<GURL>* unique_manifest_urls) {
146 const std::string manifest_url = ConstructManifestURL(prefix, name);
147 bool first_seen = seen_manifest_urls->insert(manifest_url).second;
148 if (first_seen)
149 unique_manifest_urls->push_back(GURL(manifest_url));
150 }
151
142 } // namespace 152 } // namespace
143 153
144 PrecacheFetcher::Fetcher::Fetcher( 154 PrecacheFetcher::Fetcher::Fetcher(
145 net::URLRequestContextGetter* request_context, 155 net::URLRequestContextGetter* request_context,
146 const GURL& url, 156 const GURL& url,
147 const base::Callback<void(const Fetcher&)>& callback, 157 const base::Callback<void(const Fetcher&)>& callback,
148 bool is_resource_request, 158 bool is_resource_request,
149 size_t max_bytes) 159 size_t max_bytes)
150 : request_context_(request_context), 160 : request_context_(request_context),
151 url_(url), 161 url_(url),
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 DCHECK(request_context_.get()); // Request context must be non-NULL. 274 DCHECK(request_context_.get()); // Request context must be non-NULL.
265 DCHECK(precache_delegate_); // Precache delegate must be non-NULL. 275 DCHECK(precache_delegate_); // Precache delegate must be non-NULL.
266 276
267 DCHECK_NE(GURL(), GetDefaultConfigURL()) 277 DCHECK_NE(GURL(), GetDefaultConfigURL())
268 << "Could not determine the precache config settings URL."; 278 << "Could not determine the precache config settings URL.";
269 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix()) 279 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix())
270 << "Could not determine the default precache manifest URL prefix."; 280 << "Could not determine the default precache manifest URL prefix.";
271 } 281 }
272 282
273 PrecacheFetcher::~PrecacheFetcher() { 283 PrecacheFetcher::~PrecacheFetcher() {
284 base::TimeDelta time_to_fetch = base::TimeTicks::Now() - start_time_;
285 UMA_HISTOGRAM_CUSTOM_TIMES("Precache.Fetch.TimeToComplete", time_to_fetch,
286 base::TimeDelta::FromSeconds(1),
287 base::TimeDelta::FromHours(4), 50);
288
274 // Number of manifests for which we have downloaded all resources. 289 // Number of manifests for which we have downloaded all resources.
275 int manifests_completed = 290 int manifests_completed =
276 num_manifest_urls_to_fetch_ - manifest_urls_to_fetch_.size(); 291 num_manifest_urls_to_fetch_ - manifest_urls_to_fetch_.size();
277 292
278 // If there are resource URLs left to fetch, the last manifest is not yet 293 // If there are resource URLs left to fetch, the last manifest is not yet
279 // completed. 294 // completed.
280 if (!resource_urls_to_fetch_.empty()) 295 if (!resource_urls_to_fetch_.empty())
281 --manifests_completed; 296 --manifests_completed;
282 297
283 DCHECK_GE(manifests_completed, 0); 298 DCHECK_GE(manifests_completed, 0);
(...skipping 14 matching lines...) Expand all
298 GURL config_url = 313 GURL config_url =
299 config_url_.is_empty() ? GetDefaultConfigURL() : config_url_; 314 config_url_.is_empty() ? GetDefaultConfigURL() : config_url_;
300 315
301 DCHECK(config_url.is_valid()) << "Config URL not valid: " 316 DCHECK(config_url.is_valid()) << "Config URL not valid: "
302 << config_url.possibly_invalid_spec(); 317 << config_url.possibly_invalid_spec();
303 318
304 start_time_ = base::TimeTicks::Now(); 319 start_time_ = base::TimeTicks::Now();
305 320
306 // Fetch the precache configuration settings from the server. 321 // Fetch the precache configuration settings from the server.
307 DCHECK(pool_.IsEmpty()) << "All parallel requests should be available"; 322 DCHECK(pool_.IsEmpty()) << "All parallel requests should be available";
323 VLOG(3) << "Fetching " << config_url;
308 pool_.Add(scoped_ptr<Fetcher>(new Fetcher( 324 pool_.Add(scoped_ptr<Fetcher>(new Fetcher(
309 request_context_.get(), config_url, 325 request_context_.get(), config_url,
310 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, 326 base::Bind(&PrecacheFetcher::OnConfigFetchComplete,
311 base::Unretained(this)), 327 base::Unretained(this)),
312 false /* is_resource_request */, std::numeric_limits<int32_t>::max()))); 328 false /* is_resource_request */, std::numeric_limits<int32_t>::max())));
313 } 329 }
314 330
315 void PrecacheFetcher::StartNextResourceFetch() { 331 void PrecacheFetcher::StartNextResourceFetch() {
316 while (!resource_urls_to_fetch_.empty() && pool_.IsAvailable()) { 332 while (!resource_urls_to_fetch_.empty() && pool_.IsAvailable()) {
317 const size_t max_bytes = 333 const size_t max_bytes =
318 std::min(config_->max_bytes_per_resource(), 334 std::min(config_->max_bytes_per_resource(),
319 config_->max_bytes_total() - total_response_bytes_); 335 config_->max_bytes_total() - total_response_bytes_);
336 VLOG(3) << "Fetching " << resource_urls_to_fetch_.front();
320 pool_.Add(scoped_ptr<Fetcher>( 337 pool_.Add(scoped_ptr<Fetcher>(
321 new Fetcher(request_context_.get(), resource_urls_to_fetch_.front(), 338 new Fetcher(request_context_.get(), resource_urls_to_fetch_.front(),
322 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, 339 base::Bind(&PrecacheFetcher::OnResourceFetchComplete,
323 base::Unretained(this)), 340 base::Unretained(this)),
324 true /* is_resource_request */, max_bytes))); 341 true /* is_resource_request */, max_bytes)));
325 342
326 resource_urls_to_fetch_.pop_front(); 343 resource_urls_to_fetch_.pop_front();
327 } 344 }
328 } 345 }
329 346
330 void PrecacheFetcher::StartNextManifestFetch() { 347 void PrecacheFetcher::StartNextManifestFetch() {
331 if (manifest_urls_to_fetch_.empty()) 348 if (manifest_urls_to_fetch_.empty())
332 return; 349 return;
333 350
334 // We only fetch one manifest at a time to keep the size of 351 // We only fetch one manifest at a time to keep the size of
335 // resource_urls_to_fetch_ as small as possible. 352 // resource_urls_to_fetch_ as small as possible.
336 DCHECK(pool_.IsAvailable()) 353 DCHECK(pool_.IsAvailable())
337 << "There are no available parallel requests to fetch the next manifest. " 354 << "There are no available parallel requests to fetch the next manifest. "
338 "Did you forget to call Delete?"; 355 "Did you forget to call Delete?";
356 VLOG(3) << "Fetching " << manifest_urls_to_fetch_.front();
339 pool_.Add(scoped_ptr<Fetcher>(new Fetcher( 357 pool_.Add(scoped_ptr<Fetcher>(new Fetcher(
340 request_context_.get(), manifest_urls_to_fetch_.front(), 358 request_context_.get(), manifest_urls_to_fetch_.front(),
341 base::Bind(&PrecacheFetcher::OnManifestFetchComplete, 359 base::Bind(&PrecacheFetcher::OnManifestFetchComplete,
342 base::Unretained(this)), 360 base::Unretained(this)),
343 false /* is_resource_request */, std::numeric_limits<int32_t>::max()))); 361 false /* is_resource_request */, std::numeric_limits<int32_t>::max())));
344 362
345 manifest_urls_to_fetch_.pop_front(); 363 manifest_urls_to_fetch_.pop_front();
346 } 364 }
347 365
348 void PrecacheFetcher::StartNextFetch() { 366 void PrecacheFetcher::StartNextFetch() {
349 // If over the precache total size cap, then stop prefetching. 367 // If over the precache total size cap, then stop prefetching.
350 if (total_response_bytes_ > config_->max_bytes_total()) { 368 if (total_response_bytes_ > config_->max_bytes_total()) {
351 resource_urls_to_fetch_.clear(); 369 precache_delegate_->OnDone();
352 manifest_urls_to_fetch_.clear(); 370 return;
353 } 371 }
354 372
355 StartNextResourceFetch(); 373 StartNextResourceFetch();
356 StartNextManifestFetch(); 374 StartNextManifestFetch();
357 375
358 if (pool_.IsEmpty()) { 376 if (pool_.IsEmpty()) {
359 // There are no more URLs to fetch, so end the precache cycle. 377 // There are no more URLs to fetch, so end the precache cycle.
360 base::TimeDelta time_to_fetch = base::TimeTicks::Now() - start_time_;
361 UMA_HISTOGRAM_CUSTOM_TIMES("Precache.Fetch.TimeToComplete", time_to_fetch,
362 base::TimeDelta::FromSeconds(1),
363 base::TimeDelta::FromHours(4), 50);
364
365 precache_delegate_->OnDone(); 378 precache_delegate_->OnDone();
366 // OnDone may have deleted this PrecacheFetcher, so don't do anything after 379 // OnDone may have deleted this PrecacheFetcher, so don't do anything after
367 // it is called. 380 // it is called.
368 } 381 }
369 } 382 }
370 383
371 void PrecacheFetcher::OnConfigFetchComplete(const Fetcher& source) { 384 void PrecacheFetcher::OnConfigFetchComplete(const Fetcher& source) {
372 UpdateStats(source.response_bytes(), source.network_response_bytes()); 385 UpdateStats(source.response_bytes(), source.network_response_bytes());
373 if (source.network_url_fetcher() == nullptr) { 386 if (source.network_url_fetcher() == nullptr) {
374 pool_.DeleteAll(); // Cancel any other ongoing request. 387 pool_.DeleteAll(); // Cancel any other ongoing request.
375 } else { 388 } else {
376 // Attempt to parse the config proto. On failure, continue on with the 389 // Attempt to parse the config proto. On failure, continue on with the
377 // default configuration. 390 // default configuration.
378 ParseProtoFromFetchResponse(*source.network_url_fetcher(), config_.get()); 391 ParseProtoFromFetchResponse(*source.network_url_fetcher(), config_.get());
379 392
380 std::string prefix = manifest_url_prefix_.empty() 393 std::string prefix = manifest_url_prefix_.empty()
381 ? GetDefaultManifestURLPrefix() 394 ? GetDefaultManifestURLPrefix()
382 : manifest_url_prefix_; 395 : manifest_url_prefix_;
383 DCHECK_NE(std::string(), prefix) 396 DCHECK_NE(std::string(), prefix)
384 << "Could not determine the precache manifest URL prefix."; 397 << "Could not determine the precache manifest URL prefix.";
385 398
386 // Keep track of manifest URLs that are being fetched, in order to remove 399 // Keep track of manifest URLs that are being fetched, in order to elide
387 // duplicates. 400 // duplicates.
388 base::hash_set<std::string> unique_manifest_urls; 401 base::hash_set<std::string> seen_manifest_urls;
389 402
390 // Attempt to fetch manifests for starting hosts up to the maximum top sites 403 // Attempt to fetch manifests for starting hosts up to the maximum top sites
391 // count. If a manifest does not exist for a particular starting host, then 404 // count. If a manifest does not exist for a particular starting host, then
392 // the fetch will fail, and that starting host will be ignored. 405 // the fetch will fail, and that starting host will be ignored.
393 int64_t rank = 0; 406 int64_t rank = 0;
394 for (const std::string& host : starting_hosts_) { 407 for (const std::string& host : starting_hosts_) {
395 ++rank; 408 ++rank;
396 if (rank > config_->top_sites_count()) 409 if (rank > config_->top_sites_count())
397 break; 410 break;
398 unique_manifest_urls.insert(ConstructManifestURL(prefix, host)); 411 AppendManifestURLIfNew(prefix, host, &seen_manifest_urls,
412 &manifest_urls_to_fetch_);
399 } 413 }
400 414
401 for (const std::string& url : config_->forced_site()) 415 for (const std::string& host : config_->forced_site())
402 unique_manifest_urls.insert(ConstructManifestURL(prefix, url)); 416 AppendManifestURLIfNew(prefix, host, &seen_manifest_urls,
417 &manifest_urls_to_fetch_);
403 418
404 for (const std::string& manifest_url : unique_manifest_urls)
405 manifest_urls_to_fetch_.push_back(GURL(manifest_url));
406 num_manifest_urls_to_fetch_ = manifest_urls_to_fetch_.size(); 419 num_manifest_urls_to_fetch_ = manifest_urls_to_fetch_.size();
407 } 420 }
408 pool_.Delete(source); 421 pool_.Delete(source);
409 422
410 StartNextFetch(); 423 StartNextFetch();
411 } 424 }
412 425
413 void PrecacheFetcher::OnManifestFetchComplete(const Fetcher& source) { 426 void PrecacheFetcher::OnManifestFetchComplete(const Fetcher& source) {
414 UpdateStats(source.response_bytes(), source.network_response_bytes()); 427 UpdateStats(source.response_bytes(), source.network_response_bytes());
415 if (source.network_url_fetcher() == nullptr) { 428 if (source.network_url_fetcher() == nullptr) {
(...skipping 24 matching lines...) Expand all
440 StartNextFetch(); 453 StartNextFetch();
441 } 454 }
442 455
443 void PrecacheFetcher::UpdateStats(int64_t response_bytes, 456 void PrecacheFetcher::UpdateStats(int64_t response_bytes,
444 int64_t network_response_bytes) { 457 int64_t network_response_bytes) {
445 total_response_bytes_ += response_bytes; 458 total_response_bytes_ += response_bytes;
446 network_response_bytes_ += network_response_bytes; 459 network_response_bytes_ += network_response_bytes;
447 } 460 }
448 461
449 } // namespace precache 462 } // namespace precache
OLDNEW
« no previous file with comments | « components/precache/content/precache_manager_unittest.cc ('k') | components/precache/core/precache_fetcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698