Index: components/precache/core/precache_fetcher.cc |
diff --git a/components/precache/core/precache_fetcher.cc b/components/precache/core/precache_fetcher.cc |
index 90d05bb776b6eb6b841c69369f29a3acc5846c87..1f0d160f478081db344aaac955f8fe16c3243772 100644 |
--- a/components/precache/core/precache_fetcher.cc |
+++ b/components/precache/core/precache_fetcher.cc |
@@ -27,6 +27,7 @@ |
#include "components/precache/core/precache_database.h" |
#include "components/precache/core/precache_switches.h" |
#include "components/precache/core/proto/precache.pb.h" |
+#include "components/precache/core/proto/quota.pb.h" |
#include "components/precache/core/proto/unfinished_work.pb.h" |
#include "net/base/completion_callback.h" |
#include "net/base/escape.h" |
@@ -204,6 +205,15 @@ std::deque<ManifestHostInfo> RetrieveManifestInfo( |
return hosts_info; |
} |
+PrecacheQuota RetrieveQuotaInfo( |
+ const base::WeakPtr<PrecacheDatabase>& precache_database) { |
+ PrecacheQuota quota; |
+ if (precache_database) { |
+ quota = precache_database->GetQuota(); |
+ } |
+ return quota; |
+} |
+ |
} // namespace |
PrecacheFetcher::Fetcher::Fetcher( |
@@ -466,10 +476,11 @@ void PrecacheFetcher::StartNextResourceFetch() { |
DCHECK(unfinished_work_->has_config_settings()); |
while (!resources_to_fetch_.empty() && pool_.IsAvailable()) { |
const auto& resource = resources_to_fetch_.front(); |
- const size_t max_bytes = |
+ const size_t max_bytes = std::min( |
+ quota_.remaining(), |
std::min(unfinished_work_->config_settings().max_bytes_per_resource(), |
unfinished_work_->config_settings().max_bytes_total() - |
- unfinished_work_->total_bytes()); |
+ unfinished_work_->total_bytes())); |
VLOG(3) << "Fetching " << resource.first << " " << resource.second; |
pool_.Add(base::MakeUnique<Fetcher>( |
request_context_.get(), resource.first, resource.second, |
@@ -506,9 +517,13 @@ void PrecacheFetcher::NotifyDone( |
void PrecacheFetcher::StartNextFetch() { |
DCHECK(unfinished_work_->has_config_settings()); |
- // If over the precache total size cap, then stop prefetching. |
- if (unfinished_work_->total_bytes() > |
- unfinished_work_->config_settings().max_bytes_total()) { |
+ DCHECK(base::Time::FromInternalValue(quota_.expiry_time()) > |
+ base::Time::Now()); |
+ |
+ // If over the precache total size cap or daily quota, then stop prefetching. |
+ if ((unfinished_work_->total_bytes() > |
+ unfinished_work_->config_settings().max_bytes_total()) || |
+ quota_.remaining() == 0) { |
size_t pending_manifests_in_pool = 0; |
size_t pending_resources_in_pool = 0; |
for (const auto& element_pair : pool_.elements()) { |
@@ -622,6 +637,27 @@ void PrecacheFetcher::OnManifestInfoRetrieved( |
} |
} |
unfinished_work_->set_num_manifest_urls(top_hosts_to_fetch_.size()); |
+ |
+ PostTaskAndReplyWithResult( |
+ db_task_runner_.get(), FROM_HERE, |
+ base::Bind(&RetrieveQuotaInfo, precache_database_), |
+ base::Bind(&PrecacheFetcher::OnQuotaInfoRetrieved, AsWeakPtr())); |
+} |
+ |
+void PrecacheFetcher::OnQuotaInfoRetrieved(const PrecacheQuota& quota) { |
+ quota_ = std::move(quota); |
+ if (base::Time::FromInternalValue(quota_.expiry_time()) <= |
+ base::Time::Now()) { |
+ // This is a new day. Update daily quota, that expires by end of today. |
+ quota_.set_expiry_time( |
+ (base::Time::Now().LocalMidnight() + base::TimeDelta::FromDays(1)) |
+ .ToInternalValue()); |
+ quota_.set_remaining( |
+ unfinished_work_->config_settings().daily_quota_total()); |
+ db_task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_)); |
+ } |
StartNextFetch(); |
} |
@@ -696,6 +732,17 @@ void PrecacheFetcher::UpdateStats(int64_t response_bytes, |
unfinished_work_->total_bytes() + response_bytes); |
unfinished_work_->set_network_bytes( |
unfinished_work_->network_bytes() + network_response_bytes); |
+ |
+ if (base::Time::FromInternalValue(quota_.expiry_time()) > base::Time::Now()) { |
+ int64_t remaining = |
+ static_cast<int64_t>(quota_.remaining()) - network_response_bytes; |
+ if (remaining < 0) |
+ remaining = 0; |
+ quota_.set_remaining(static_cast<size_t>(remaining)); |
+ db_task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_)); |
+ } |
} |
} // namespace precache |