Chromium Code Reviews| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 DCHECK(request_context_.get()); // Request context must be non-NULL. | 264 DCHECK(request_context_.get()); // Request context must be non-NULL. |
| 265 DCHECK(precache_delegate_); // Precache delegate must be non-NULL. | 265 DCHECK(precache_delegate_); // Precache delegate must be non-NULL. |
| 266 | 266 |
| 267 DCHECK_NE(GURL(), GetDefaultConfigURL()) | 267 DCHECK_NE(GURL(), GetDefaultConfigURL()) |
| 268 << "Could not determine the precache config settings URL."; | 268 << "Could not determine the precache config settings URL."; |
| 269 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix()) | 269 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix()) |
| 270 << "Could not determine the default precache manifest URL prefix."; | 270 << "Could not determine the default precache manifest URL prefix."; |
| 271 } | 271 } |
| 272 | 272 |
| 273 PrecacheFetcher::~PrecacheFetcher() { | 273 PrecacheFetcher::~PrecacheFetcher() { |
| 274 base::TimeDelta time_to_fetch = base::TimeTicks::Now() - start_time_; | |
| 275 UMA_HISTOGRAM_CUSTOM_TIMES("Precache.Fetch.TimeToComplete", time_to_fetch, | |
| 276 base::TimeDelta::FromSeconds(1), | |
| 277 base::TimeDelta::FromHours(4), 50); | |
| 278 | |
| 274 // Number of manifests for which we have downloaded all resources. | 279 // Number of manifests for which we have downloaded all resources. |
| 275 int manifests_completed = | 280 int manifests_completed = |
| 276 num_manifest_urls_to_fetch_ - manifest_urls_to_fetch_.size(); | 281 num_manifest_urls_to_fetch_ - manifest_urls_to_fetch_.size(); |
| 277 | 282 |
| 278 // If there are resource URLs left to fetch, the last manifest is not yet | 283 // If there are resource URLs left to fetch, the last manifest is not yet |
| 279 // completed. | 284 // completed. |
| 280 if (!resource_urls_to_fetch_.empty()) | 285 if (!resource_urls_to_fetch_.empty()) |
| 281 --manifests_completed; | 286 --manifests_completed; |
| 282 | 287 |
| 283 DCHECK_GE(manifests_completed, 0); | 288 DCHECK_GE(manifests_completed, 0); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 298 GURL config_url = | 303 GURL config_url = |
| 299 config_url_.is_empty() ? GetDefaultConfigURL() : config_url_; | 304 config_url_.is_empty() ? GetDefaultConfigURL() : config_url_; |
| 300 | 305 |
| 301 DCHECK(config_url.is_valid()) << "Config URL not valid: " | 306 DCHECK(config_url.is_valid()) << "Config URL not valid: " |
| 302 << config_url.possibly_invalid_spec(); | 307 << config_url.possibly_invalid_spec(); |
| 303 | 308 |
| 304 start_time_ = base::TimeTicks::Now(); | 309 start_time_ = base::TimeTicks::Now(); |
| 305 | 310 |
| 306 // Fetch the precache configuration settings from the server. | 311 // Fetch the precache configuration settings from the server. |
| 307 DCHECK(pool_.IsEmpty()) << "All parallel requests should be available"; | 312 DCHECK(pool_.IsEmpty()) << "All parallel requests should be available"; |
| 313 VLOG(3) << "Fetching " << config_url; | |
| 308 pool_.Add(scoped_ptr<Fetcher>(new Fetcher( | 314 pool_.Add(scoped_ptr<Fetcher>(new Fetcher( |
| 309 request_context_.get(), config_url, | 315 request_context_.get(), config_url, |
| 310 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, | 316 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, |
| 311 base::Unretained(this)), | 317 base::Unretained(this)), |
| 312 false /* is_resource_request */, std::numeric_limits<int32_t>::max()))); | 318 false /* is_resource_request */, std::numeric_limits<int32_t>::max()))); |
| 313 } | 319 } |
| 314 | 320 |
| 315 void PrecacheFetcher::StartNextResourceFetch() { | 321 void PrecacheFetcher::StartNextResourceFetch() { |
| 316 while (!resource_urls_to_fetch_.empty() && pool_.IsAvailable()) { | 322 while (!resource_urls_to_fetch_.empty() && pool_.IsAvailable()) { |
| 317 const size_t max_bytes = | 323 const size_t max_bytes = |
| 318 std::min(config_->max_bytes_per_resource(), | 324 std::min(config_->max_bytes_per_resource(), |
| 319 config_->max_bytes_total() - total_response_bytes_); | 325 config_->max_bytes_total() - total_response_bytes_); |
| 326 VLOG(3) << "Fetching " << resource_urls_to_fetch_.front(); | |
| 320 pool_.Add(scoped_ptr<Fetcher>( | 327 pool_.Add(scoped_ptr<Fetcher>( |
| 321 new Fetcher(request_context_.get(), resource_urls_to_fetch_.front(), | 328 new Fetcher(request_context_.get(), resource_urls_to_fetch_.front(), |
| 322 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, | 329 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, |
| 323 base::Unretained(this)), | 330 base::Unretained(this)), |
| 324 true /* is_resource_request */, max_bytes))); | 331 true /* is_resource_request */, max_bytes))); |
| 325 | 332 |
| 326 resource_urls_to_fetch_.pop_front(); | 333 resource_urls_to_fetch_.pop_front(); |
| 327 } | 334 } |
| 328 } | 335 } |
| 329 | 336 |
| 330 void PrecacheFetcher::StartNextManifestFetch() { | 337 void PrecacheFetcher::StartNextManifestFetch() { |
| 331 if (manifest_urls_to_fetch_.empty()) | 338 if (manifest_urls_to_fetch_.empty()) |
| 332 return; | 339 return; |
| 333 | 340 |
| 334 // We only fetch one manifest at a time to keep the size of | 341 // We only fetch one manifest at a time to keep the size of |
| 335 // resource_urls_to_fetch_ as small as possible. | 342 // resource_urls_to_fetch_ as small as possible. |
| 336 DCHECK(pool_.IsAvailable()) | 343 DCHECK(pool_.IsAvailable()) |
| 337 << "There are no available parallel requests to fetch the next manifest. " | 344 << "There are no available parallel requests to fetch the next manifest. " |
| 338 "Did you forget to call Delete?"; | 345 "Did you forget to call Delete?"; |
| 346 VLOG(3) << "Fetching " << manifest_urls_to_fetch_.front(); | |
| 339 pool_.Add(scoped_ptr<Fetcher>(new Fetcher( | 347 pool_.Add(scoped_ptr<Fetcher>(new Fetcher( |
| 340 request_context_.get(), manifest_urls_to_fetch_.front(), | 348 request_context_.get(), manifest_urls_to_fetch_.front(), |
| 341 base::Bind(&PrecacheFetcher::OnManifestFetchComplete, | 349 base::Bind(&PrecacheFetcher::OnManifestFetchComplete, |
| 342 base::Unretained(this)), | 350 base::Unretained(this)), |
| 343 false /* is_resource_request */, std::numeric_limits<int32_t>::max()))); | 351 false /* is_resource_request */, std::numeric_limits<int32_t>::max()))); |
| 344 | 352 |
| 345 manifest_urls_to_fetch_.pop_front(); | 353 manifest_urls_to_fetch_.pop_front(); |
| 346 } | 354 } |
| 347 | 355 |
| 348 void PrecacheFetcher::StartNextFetch() { | 356 void PrecacheFetcher::StartNextFetch() { |
| 349 // If over the precache total size cap, then stop prefetching. | 357 // If over the precache total size cap, then stop prefetching. |
| 350 if (total_response_bytes_ > config_->max_bytes_total()) { | 358 if (total_response_bytes_ > config_->max_bytes_total()) { |
| 351 resource_urls_to_fetch_.clear(); | 359 precache_delegate_->OnDone(); |
|
bengr
2016/04/08 18:24:35
You might want to also clear the lists, else the e
twifkak
2016/04/08 19:09:05
I can't clear the lists. That's what this CL is ab
bengr
2016/04/08 21:25:48
I know that's what the CL is about. What you have
| |
| 352 manifest_urls_to_fetch_.clear(); | 360 return; |
| 353 } | 361 } |
| 354 | 362 |
| 355 StartNextResourceFetch(); | 363 StartNextResourceFetch(); |
| 356 StartNextManifestFetch(); | 364 StartNextManifestFetch(); |
| 357 | 365 |
| 358 if (pool_.IsEmpty()) { | 366 if (pool_.IsEmpty()) { |
| 359 // There are no more URLs to fetch, so end the precache cycle. | 367 // 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(); | 368 precache_delegate_->OnDone(); |
| 366 // OnDone may have deleted this PrecacheFetcher, so don't do anything after | 369 // OnDone may have deleted this PrecacheFetcher, so don't do anything after |
| 367 // it is called. | 370 // it is called. |
| 368 } | 371 } |
| 369 } | 372 } |
| 370 | 373 |
| 371 void PrecacheFetcher::OnConfigFetchComplete(const Fetcher& source) { | 374 void PrecacheFetcher::OnConfigFetchComplete(const Fetcher& source) { |
| 372 UpdateStats(source.response_bytes(), source.network_response_bytes()); | 375 UpdateStats(source.response_bytes(), source.network_response_bytes()); |
| 373 if (source.network_url_fetcher() == nullptr) { | 376 if (source.network_url_fetcher() == nullptr) { |
| 374 pool_.DeleteAll(); // Cancel any other ongoing request. | 377 pool_.DeleteAll(); // Cancel any other ongoing request. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 388 base::hash_set<std::string> unique_manifest_urls; | 391 base::hash_set<std::string> unique_manifest_urls; |
| 389 | 392 |
| 390 // Attempt to fetch manifests for starting hosts up to the maximum top sites | 393 // 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 | 394 // 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. | 395 // the fetch will fail, and that starting host will be ignored. |
| 393 int64_t rank = 0; | 396 int64_t rank = 0; |
| 394 for (const std::string& host : starting_hosts_) { | 397 for (const std::string& host : starting_hosts_) { |
| 395 ++rank; | 398 ++rank; |
| 396 if (rank > config_->top_sites_count()) | 399 if (rank > config_->top_sites_count()) |
| 397 break; | 400 break; |
| 398 unique_manifest_urls.insert(ConstructManifestURL(prefix, host)); | 401 const std::string manifest_url = ConstructManifestURL(prefix, host); |
|
bengr
2016/04/08 18:24:35
I wonder if it makes sense to have a helper functi
twifkak
2016/04/08 19:09:05
Yeah, I was on the fence about that, but your comm
| |
| 402 bool first_seen = unique_manifest_urls.insert(manifest_url).second; | |
| 403 if (first_seen) | |
| 404 manifest_urls_to_fetch_.push_back(GURL(manifest_url)); | |
| 399 } | 405 } |
| 400 | 406 |
| 401 for (const std::string& url : config_->forced_site()) | 407 for (const std::string& url : config_->forced_site()) { |
| 402 unique_manifest_urls.insert(ConstructManifestURL(prefix, url)); | 408 const std::string manifest_url = ConstructManifestURL(prefix, url); |
| 409 bool first_seen = unique_manifest_urls.insert(manifest_url).second; | |
| 410 if (first_seen) | |
| 411 manifest_urls_to_fetch_.push_back(GURL(manifest_url)); | |
| 412 } | |
| 403 | 413 |
| 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(); | 414 num_manifest_urls_to_fetch_ = manifest_urls_to_fetch_.size(); |
| 407 } | 415 } |
| 408 pool_.Delete(source); | 416 pool_.Delete(source); |
| 409 | 417 |
| 410 StartNextFetch(); | 418 StartNextFetch(); |
| 411 } | 419 } |
| 412 | 420 |
| 413 void PrecacheFetcher::OnManifestFetchComplete(const Fetcher& source) { | 421 void PrecacheFetcher::OnManifestFetchComplete(const Fetcher& source) { |
| 414 UpdateStats(source.response_bytes(), source.network_response_bytes()); | 422 UpdateStats(source.response_bytes(), source.network_response_bytes()); |
| 415 if (source.network_url_fetcher() == nullptr) { | 423 if (source.network_url_fetcher() == nullptr) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 440 StartNextFetch(); | 448 StartNextFetch(); |
| 441 } | 449 } |
| 442 | 450 |
| 443 void PrecacheFetcher::UpdateStats(int64_t response_bytes, | 451 void PrecacheFetcher::UpdateStats(int64_t response_bytes, |
| 444 int64_t network_response_bytes) { | 452 int64_t network_response_bytes) { |
| 445 total_response_bytes_ += response_bytes; | 453 total_response_bytes_ += response_bytes; |
| 446 network_response_bytes_ += network_response_bytes; | 454 network_response_bytes_ += network_response_bytes; |
| 447 } | 455 } |
| 448 | 456 |
| 449 } // namespace precache | 457 } // namespace precache |
| OLD | NEW |