| Index: components/precache/core/precache_fetcher.cc
|
| diff --git a/components/precache/core/precache_fetcher.cc b/components/precache/core/precache_fetcher.cc
|
| index e7a5a0bce807a63ca3c8913f66924d154b331601..2e1af600406a90979903c0ca672eba8a68ebd06e 100644
|
| --- a/components/precache/core/precache_fetcher.cc
|
| +++ b/components/precache/core/precache_fetcher.cc
|
| @@ -11,15 +11,19 @@
|
| #include <vector>
|
|
|
| #include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| #include "base/callback.h"
|
| #include "base/command_line.h"
|
| #include "base/compiler_specific.h"
|
| #include "base/containers/hash_tables.h"
|
| +#include "base/location.h"
|
| #include "base/logging.h"
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/memory/ref_counted.h"
|
| #include "base/metrics/histogram_macros.h"
|
| #include "components/precache/core/precache_switches.h"
|
| #include "components/precache/core/proto/precache.pb.h"
|
| +#include "components/precache/core/proto/unfinished_work.pb.h"
|
| #include "net/base/completion_callback.h"
|
| #include "net/base/escape.h"
|
| #include "net/base/io_buffer.h"
|
| @@ -257,13 +261,12 @@ void PrecacheFetcher::Fetcher::OnURLFetchComplete(
|
| }
|
|
|
| PrecacheFetcher::PrecacheFetcher(
|
| - const std::vector<std::string>& starting_hosts,
|
| net::URLRequestContextGetter* request_context,
|
| const GURL& config_url,
|
| const std::string& manifest_url_prefix,
|
| + std::unique_ptr<PrecacheUnfinishedWork> unfinished_work,
|
| PrecacheFetcher::PrecacheDelegate* precache_delegate)
|
| - : starting_hosts_(starting_hosts),
|
| - request_context_(request_context),
|
| + : request_context_(request_context),
|
| config_url_(config_url),
|
| manifest_url_prefix_(manifest_url_prefix),
|
| precache_delegate_(precache_delegate),
|
| @@ -279,10 +282,31 @@ PrecacheFetcher::PrecacheFetcher(
|
| << "Could not determine the precache config settings URL.";
|
| DCHECK_NE(std::string(), GetDefaultManifestURLPrefix())
|
| << "Could not determine the default precache manifest URL prefix.";
|
| + DCHECK(unfinished_work);
|
| +
|
| + for (const auto& manifest : unfinished_work->manifest()) {
|
| + if (manifest.has_url())
|
| + manifest_urls_to_fetch_.push_back(GURL(manifest.url()));
|
| + }
|
| + for (const auto& resource : unfinished_work->resource()) {
|
| + if (resource.has_url())
|
| + resource_urls_to_fetch_.push_back(GURL(resource.url()));
|
| + }
|
| + if (unfinished_work->has_total_bytes())
|
| + total_response_bytes_ = unfinished_work->total_bytes();
|
| + if (unfinished_work->has_network_bytes())
|
| + network_response_bytes_ = unfinished_work->network_bytes();
|
| + if (unfinished_work->has_num_manifest_urls())
|
| + num_manifest_urls_to_fetch_ = unfinished_work->num_manifest_urls();
|
| + if (unfinished_work->has_start_time())
|
| + start_time_ = base::Time::FromInternalValue(unfinished_work->start_time());
|
| +
|
| + unfinished_work_ = std::move(unfinished_work);
|
| +
|
| }
|
|
|
| PrecacheFetcher::~PrecacheFetcher() {
|
| - base::TimeDelta time_to_fetch = base::TimeTicks::Now() - start_time_;
|
| + base::TimeDelta time_to_fetch = base::Time::Now() - start_time_;
|
| UMA_HISTOGRAM_CUSTOM_TIMES("Precache.Fetch.TimeToComplete", time_to_fetch,
|
| base::TimeDelta::FromSeconds(1),
|
| base::TimeDelta::FromHours(4), 50);
|
| @@ -310,14 +334,31 @@ PrecacheFetcher::~PrecacheFetcher() {
|
| 100);
|
| }
|
|
|
| +std::unique_ptr<PrecacheUnfinishedWork> PrecacheFetcher::CancelPrecaching() {
|
| + for (const auto& manifest : manifest_urls_to_fetch_)
|
| + unfinished_work_->add_manifest()->set_url(manifest.spec());
|
| + for (const auto& resource : resource_urls_to_fetch_)
|
| + unfinished_work_->add_resource()->set_url(resource.spec());
|
| + unfinished_work_->set_total_bytes(total_response_bytes_);
|
| + unfinished_work_->set_network_bytes(network_response_bytes_);
|
| + unfinished_work_->set_num_manifest_urls(num_manifest_urls_to_fetch_);
|
| + unfinished_work_->set_start_time(start_time_.ToInternalValue());
|
| + return std::move(unfinished_work_);
|
| +}
|
| +
|
| void PrecacheFetcher::Start() {
|
| + if (unfinished_work_->has_config_settings()) {
|
| + DetermineManifests();
|
| + return;
|
| + }
|
| +
|
| GURL config_url =
|
| config_url_.is_empty() ? GetDefaultConfigURL() : config_url_;
|
|
|
| DCHECK(config_url.is_valid()) << "Config URL not valid: "
|
| << config_url.possibly_invalid_spec();
|
|
|
| - start_time_ = base::TimeTicks::Now();
|
| + start_time_ = base::Time::Now();
|
|
|
| // Fetch the precache configuration settings from the server.
|
| DCHECK(pool_.IsEmpty()) << "All parallel requests should be available";
|
| @@ -330,10 +371,12 @@ void PrecacheFetcher::Start() {
|
| }
|
|
|
| void PrecacheFetcher::StartNextResourceFetch() {
|
| + DCHECK(unfinished_work_->has_config_settings());
|
| while (!resource_urls_to_fetch_.empty() && pool_.IsAvailable()) {
|
| const size_t max_bytes =
|
| - std::min(config_->max_bytes_per_resource(),
|
| - config_->max_bytes_total() - total_response_bytes_);
|
| + std::min(unfinished_work_->config_settings().max_bytes_per_resource(),
|
| + unfinished_work_->config_settings().max_bytes_total() -
|
| + total_response_bytes_);
|
| VLOG(3) << "Fetching " << resource_urls_to_fetch_.front();
|
| pool_.Add(base::WrapUnique(
|
| new Fetcher(request_context_.get(), resource_urls_to_fetch_.front(),
|
| @@ -365,15 +408,16 @@ void PrecacheFetcher::StartNextManifestFetch() {
|
| }
|
|
|
| void PrecacheFetcher::StartNextFetch() {
|
| + DCHECK(unfinished_work_->has_config_settings());
|
| // If over the precache total size cap, then stop prefetching.
|
| - if (total_response_bytes_ > config_->max_bytes_total()) {
|
| + if (total_response_bytes_ >
|
| + unfinished_work_->config_settings().max_bytes_total()) {
|
| precache_delegate_->OnDone();
|
| return;
|
| }
|
|
|
| StartNextResourceFetch();
|
| StartNextManifestFetch();
|
| -
|
| if (pool_.IsEmpty()) {
|
| // There are no more URLs to fetch, so end the precache cycle.
|
| precache_delegate_->OnDone();
|
| @@ -389,8 +433,16 @@ void PrecacheFetcher::OnConfigFetchComplete(const Fetcher& source) {
|
| } else {
|
| // Attempt to parse the config proto. On failure, continue on with the
|
| // default configuration.
|
| - ParseProtoFromFetchResponse(*source.network_url_fetcher(), config_.get());
|
| + ParseProtoFromFetchResponse(
|
| + *source.network_url_fetcher(),
|
| + unfinished_work_->mutable_config_settings());
|
| + pool_.Delete(source);
|
| + DetermineManifests();
|
| + }
|
| +}
|
|
|
| +void PrecacheFetcher::DetermineManifests() {
|
| + DCHECK(unfinished_work_->has_config_settings());
|
| std::string prefix = manifest_url_prefix_.empty()
|
| ? GetDefaultManifestURLPrefix()
|
| : manifest_url_prefix_;
|
| @@ -403,28 +455,32 @@ void PrecacheFetcher::OnConfigFetchComplete(const Fetcher& source) {
|
|
|
| // Attempt to fetch manifests for starting hosts up to the maximum top sites
|
| // count. If a manifest does not exist for a particular starting host, then
|
| - // the fetch will fail, and that starting host will be ignored.
|
| - int64_t rank = 0;
|
| - for (const std::string& host : starting_hosts_) {
|
| - ++rank;
|
| - if (rank > config_->top_sites_count())
|
| - break;
|
| - AppendManifestURLIfNew(prefix, host, &seen_manifest_urls,
|
| - &manifest_urls_to_fetch_);
|
| - }
|
| -
|
| - for (const std::string& host : config_->forced_site())
|
| - AppendManifestURLIfNew(prefix, host, &seen_manifest_urls,
|
| - &manifest_urls_to_fetch_);
|
| + // the fetch will fail, and that starting host will be ignored. Starting
|
| + // hosts are not added if this is a continuation from a previous precache
|
| + // session.
|
| + if (manifest_urls_to_fetch_.empty() &&
|
| + resource_urls_to_fetch_.empty()) {
|
| + int64_t rank = 0;
|
| + for (const auto& host : unfinished_work_->top_host()) {
|
| + ++rank;
|
| + if (rank > unfinished_work_->config_settings().top_sites_count())
|
| + break;
|
| + AppendManifestURLIfNew(prefix, host.hostname(), &seen_manifest_urls,
|
| + &manifest_urls_to_fetch_);
|
| + }
|
|
|
| + for (const std::string& host
|
| + : unfinished_work_->config_settings().forced_site()) {
|
| + AppendManifestURLIfNew(prefix, host, &seen_manifest_urls,
|
| + &manifest_urls_to_fetch_);
|
| + }
|
| + }
|
| num_manifest_urls_to_fetch_ = manifest_urls_to_fetch_.size();
|
| - }
|
| - pool_.Delete(source);
|
| -
|
| - StartNextFetch();
|
| + StartNextFetch();
|
| }
|
|
|
| void PrecacheFetcher::OnManifestFetchComplete(const Fetcher& source) {
|
| + DCHECK(unfinished_work_->has_config_settings());
|
| UpdateStats(source.response_bytes(), source.network_response_bytes());
|
| if (source.network_url_fetcher() == nullptr) {
|
| pool_.DeleteAll(); // Cancel any other ongoing request.
|
| @@ -433,11 +489,11 @@ void PrecacheFetcher::OnManifestFetchComplete(const Fetcher& source) {
|
|
|
| if (ParseProtoFromFetchResponse(*source.network_url_fetcher(), &manifest)) {
|
| const int32_t len =
|
| - std::min(manifest.resource_size(), config_->top_resources_count());
|
| + std::min(manifest.resource_size(),
|
| + unfinished_work_->config_settings().top_resources_count());
|
| for (int i = 0; i < len; ++i) {
|
| - if (manifest.resource(i).has_url()) {
|
| + if (manifest.resource(i).has_url())
|
| resource_urls_to_fetch_.push_back(GURL(manifest.resource(i).url()));
|
| - }
|
| }
|
| }
|
| }
|
| @@ -460,4 +516,20 @@ void PrecacheFetcher::UpdateStats(int64_t response_bytes,
|
| network_response_bytes_ += network_response_bytes;
|
| }
|
|
|
| +void PrecacheFetcher::AssignWorkForTest(const std::list<GURL>& manifests,
|
| + const std::list<GURL>& resources,
|
| + size_t total_response_bytes,
|
| + size_t network_response_bytes,
|
| + size_t num_manifest_urls_to_fetch,
|
| + const base::Time& start_time) {
|
| + DCHECK(manifest_urls_to_fetch_.empty());
|
| + DCHECK(resource_urls_to_fetch_.empty());
|
| + manifest_urls_to_fetch_ = manifests;
|
| + resource_urls_to_fetch_ = resources;
|
| + total_response_bytes_ = total_response_bytes;
|
| + network_response_bytes_ = network_response_bytes;
|
| + num_manifest_urls_to_fetch_ = num_manifest_urls_to_fetch;
|
| + start_time_ = start_time;
|
| +}
|
| +
|
| } // namespace precache
|
|
|