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 |