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

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

Issue 2335913002: Add daily quota for precache (Closed)
Patch Set: Addressed sclittle@ comments Created 4 years, 3 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 <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/base64.h" 12 #include "base/base64.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/callback.h" 15 #include "base/callback.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/compiler_specific.h" 17 #include "base/compiler_specific.h"
18 #include "base/containers/hash_tables.h" 18 #include "base/containers/hash_tables.h"
19 #include "base/location.h" 19 #include "base/location.h"
20 #include "base/logging.h" 20 #include "base/logging.h"
21 #include "base/memory/ptr_util.h" 21 #include "base/memory/ptr_util.h"
22 #include "base/memory/ref_counted.h" 22 #include "base/memory/ref_counted.h"
23 #include "base/metrics/histogram_macros.h" 23 #include "base/metrics/histogram_macros.h"
24 #include "base/sha1.h" 24 #include "base/sha1.h"
25 #include "base/strings/string_piece.h" 25 #include "base/strings/string_piece.h"
26 #include "base/task_runner_util.h" 26 #include "base/task_runner_util.h"
27 #include "components/precache/core/precache_database.h" 27 #include "components/precache/core/precache_database.h"
28 #include "components/precache/core/precache_switches.h" 28 #include "components/precache/core/precache_switches.h"
29 #include "components/precache/core/proto/precache.pb.h" 29 #include "components/precache/core/proto/precache.pb.h"
30 #include "components/precache/core/proto/quota.pb.h"
30 #include "components/precache/core/proto/unfinished_work.pb.h" 31 #include "components/precache/core/proto/unfinished_work.pb.h"
31 #include "net/base/completion_callback.h" 32 #include "net/base/completion_callback.h"
32 #include "net/base/escape.h" 33 #include "net/base/escape.h"
33 #include "net/base/io_buffer.h" 34 #include "net/base/io_buffer.h"
34 #include "net/base/load_flags.h" 35 #include "net/base/load_flags.h"
35 #include "net/base/net_errors.h" 36 #include "net/base/net_errors.h"
36 #include "net/base/url_util.h" 37 #include "net/base/url_util.h"
37 #include "net/http/http_response_headers.h" 38 #include "net/http/http_response_headers.h"
38 #include "net/url_request/url_fetcher_response_writer.h" 39 #include "net/url_request/url_fetcher_response_writer.h"
39 #include "net/url_request/url_request_context_getter.h" 40 #include "net/url_request/url_request_context_getter.h"
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 GetResourceURLBase64Hash(unused_urls))); 198 GetResourceURLBase64Hash(unused_urls)));
198 } else { 199 } else {
199 hosts_info.push_back( 200 hosts_info.push_back(
200 ManifestHostInfo(PrecacheReferrerHostEntry::kInvalidId, host, 201 ManifestHostInfo(PrecacheReferrerHostEntry::kInvalidId, host,
201 std::string(), std::string())); 202 std::string(), std::string()));
202 } 203 }
203 } 204 }
204 return hosts_info; 205 return hosts_info;
205 } 206 }
206 207
208 PrecacheQuota RetrieveQuotaInfo(
209 const base::WeakPtr<PrecacheDatabase>& precache_database) {
210 PrecacheQuota quota;
211 if (precache_database) {
212 quota = precache_database->GetQuota();
213 }
214 return quota;
215 }
216
217 // Returns true if the |quota| time has expired.
218 bool IsQuotaTimeExpired(const PrecacheQuota& quota,
219 const base::Time& time_now) {
220 // Quota expires by the end of the day specified in start time.
sclittle 2016/09/22 21:36:55 nit: As implemented below, I don't think this comm
Raj 2016/09/23 01:32:41 Done.
221 base::Time start_time = base::Time::FromInternalValue(quota.start_time());
222 return start_time > time_now ||
223 start_time + base::TimeDelta::FromDays(1) < time_now;
224 }
225
207 } // namespace 226 } // namespace
208 227
209 PrecacheFetcher::Fetcher::Fetcher( 228 PrecacheFetcher::Fetcher::Fetcher(
210 net::URLRequestContextGetter* request_context, 229 net::URLRequestContextGetter* request_context,
211 const GURL& url, 230 const GURL& url,
212 const std::string& referrer, 231 const std::string& referrer,
213 const base::Callback<void(const Fetcher&)>& callback, 232 const base::Callback<void(const Fetcher&)>& callback,
214 bool is_resource_request, 233 bool is_resource_request,
215 size_t max_bytes) 234 size_t max_bytes)
216 : request_context_(request_context), 235 : request_context_(request_context),
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 pool_.Add(base::MakeUnique<Fetcher>( 478 pool_.Add(base::MakeUnique<Fetcher>(
460 request_context_.get(), config_url, std::string(), 479 request_context_.get(), config_url, std::string(),
461 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, AsWeakPtr()), 480 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, AsWeakPtr()),
462 false /* is_resource_request */, std::numeric_limits<int32_t>::max())); 481 false /* is_resource_request */, std::numeric_limits<int32_t>::max()));
463 } 482 }
464 483
465 void PrecacheFetcher::StartNextResourceFetch() { 484 void PrecacheFetcher::StartNextResourceFetch() {
466 DCHECK(unfinished_work_->has_config_settings()); 485 DCHECK(unfinished_work_->has_config_settings());
467 while (!resources_to_fetch_.empty() && pool_.IsAvailable()) { 486 while (!resources_to_fetch_.empty() && pool_.IsAvailable()) {
468 const auto& resource = resources_to_fetch_.front(); 487 const auto& resource = resources_to_fetch_.front();
469 const size_t max_bytes = 488 const size_t max_bytes = std::min(
489 quota_.remaining(),
470 std::min(unfinished_work_->config_settings().max_bytes_per_resource(), 490 std::min(unfinished_work_->config_settings().max_bytes_per_resource(),
471 unfinished_work_->config_settings().max_bytes_total() - 491 unfinished_work_->config_settings().max_bytes_total() -
472 unfinished_work_->total_bytes()); 492 unfinished_work_->total_bytes()));
473 VLOG(3) << "Fetching " << resource.first << " " << resource.second; 493 VLOG(3) << "Fetching " << resource.first << " " << resource.second;
474 pool_.Add(base::MakeUnique<Fetcher>( 494 pool_.Add(base::MakeUnique<Fetcher>(
475 request_context_.get(), resource.first, resource.second, 495 request_context_.get(), resource.first, resource.second,
476 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, AsWeakPtr()), 496 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, AsWeakPtr()),
477 true /* is_resource_request */, max_bytes)); 497 true /* is_resource_request */, max_bytes));
478 498
479 resources_to_fetch_.pop_front(); 499 resources_to_fetch_.pop_front();
480 } 500 }
481 } 501 }
482 502
(...skipping 16 matching lines...) Expand all
499 size_t remaining_manifest_urls_to_fetch, 519 size_t remaining_manifest_urls_to_fetch,
500 size_t remaining_resource_urls_to_fetch) { 520 size_t remaining_resource_urls_to_fetch) {
501 RecordCompletionStatistics(*unfinished_work_, 521 RecordCompletionStatistics(*unfinished_work_,
502 remaining_manifest_urls_to_fetch, 522 remaining_manifest_urls_to_fetch,
503 remaining_resource_urls_to_fetch); 523 remaining_resource_urls_to_fetch);
504 precache_delegate_->OnDone(); 524 precache_delegate_->OnDone();
505 } 525 }
506 526
507 void PrecacheFetcher::StartNextFetch() { 527 void PrecacheFetcher::StartNextFetch() {
508 DCHECK(unfinished_work_->has_config_settings()); 528 DCHECK(unfinished_work_->has_config_settings());
509 // If over the precache total size cap, then stop prefetching. 529
510 if (unfinished_work_->total_bytes() > 530 // If over the precache total size cap or daily quota, then stop prefetching.
511 unfinished_work_->config_settings().max_bytes_total()) { 531 if ((unfinished_work_->total_bytes() >
532 unfinished_work_->config_settings().max_bytes_total()) ||
533 quota_.remaining() == 0) {
512 size_t pending_manifests_in_pool = 0; 534 size_t pending_manifests_in_pool = 0;
513 size_t pending_resources_in_pool = 0; 535 size_t pending_resources_in_pool = 0;
514 for (const auto& element_pair : pool_.elements()) { 536 for (const auto& element_pair : pool_.elements()) {
515 const Fetcher* fetcher = element_pair.first; 537 const Fetcher* fetcher = element_pair.first;
516 if (fetcher->is_resource_request()) 538 if (fetcher->is_resource_request())
517 pending_resources_in_pool++; 539 pending_resources_in_pool++;
518 else if (fetcher->url() != config_url_) 540 else if (fetcher->url() != config_url_)
519 pending_manifests_in_pool++; 541 pending_manifests_in_pool++;
520 } 542 }
521 pool_.DeleteAll(); 543 pool_.DeleteAll();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 manifest.manifest_url, "manifest", 637 manifest.manifest_url, "manifest",
616 std::to_string(manifest.manifest_id)); 638 std::to_string(manifest.manifest_id));
617 manifest.manifest_url = net::AppendOrReplaceQueryParameter( 639 manifest.manifest_url = net::AppendOrReplaceQueryParameter(
618 manifest.manifest_url, "used_resources", manifest.used_url_hash); 640 manifest.manifest_url, "used_resources", manifest.used_url_hash);
619 manifest.manifest_url = net::AppendOrReplaceQueryParameter( 641 manifest.manifest_url = net::AppendOrReplaceQueryParameter(
620 manifest.manifest_url, "unused_resources", manifest.unused_url_hash); 642 manifest.manifest_url, "unused_resources", manifest.unused_url_hash);
621 DCHECK(manifest.manifest_url.is_valid()); 643 DCHECK(manifest.manifest_url.is_valid());
622 } 644 }
623 } 645 }
624 unfinished_work_->set_num_manifest_urls(top_hosts_to_fetch_.size()); 646 unfinished_work_->set_num_manifest_urls(top_hosts_to_fetch_.size());
647
648 PostTaskAndReplyWithResult(
649 db_task_runner_.get(), FROM_HERE,
650 base::Bind(&RetrieveQuotaInfo, precache_database_),
651 base::Bind(&PrecacheFetcher::OnQuotaInfoRetrieved, AsWeakPtr()));
652 }
653
654 void PrecacheFetcher::OnQuotaInfoRetrieved(const PrecacheQuota& quota) {
655 quota_ = quota;
656 base::Time time_now = base::Time::Now();
657 if (IsQuotaTimeExpired(quota_, time_now)) {
658 // This is a new day. Update daily quota, that starts today and expires by
659 // end of today.
660 quota_.set_start_time(time_now.LocalMidnight().ToInternalValue());
661 quota_.set_remaining(
662 unfinished_work_->config_settings().daily_quota_total());
663 db_task_runner_->PostTask(
664 FROM_HERE,
665 base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_));
666 }
625 StartNextFetch(); 667 StartNextFetch();
626 } 668 }
627 669
628 ManifestHostInfo::ManifestHostInfo(int64_t manifest_id, 670 ManifestHostInfo::ManifestHostInfo(int64_t manifest_id,
629 const std::string& hostname, 671 const std::string& hostname,
630 const std::string& used_url_hash, 672 const std::string& used_url_hash,
631 const std::string& unused_url_hash) 673 const std::string& unused_url_hash)
632 : manifest_id(manifest_id), 674 : manifest_id(manifest_id),
633 hostname(hostname), 675 hostname(hostname),
634 used_url_hash(used_url_hash), 676 used_url_hash(used_url_hash),
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 source.was_cached(), source.response_bytes())); 726 source.was_cached(), source.response_bytes()));
685 727
686 pool_.Delete(source); 728 pool_.Delete(source);
687 729
688 // The resource has already been put in the cache during the fetch process, so 730 // The resource has already been put in the cache during the fetch process, so
689 // nothing more needs to be done for the resource. 731 // nothing more needs to be done for the resource.
690 StartNextFetch(); 732 StartNextFetch();
691 } 733 }
692 734
693 void PrecacheFetcher::UpdateStats(int64_t response_bytes, 735 void PrecacheFetcher::UpdateStats(int64_t response_bytes,
694 int64_t network_response_bytes) { 736 int64_t network_response_bytes) {
sclittle 2016/09/22 21:36:55 nit: Could you add DCHECKs here that |response_byt
Raj 2016/09/23 01:32:41 Done.
695 unfinished_work_->set_total_bytes( 737 unfinished_work_->set_total_bytes(
696 unfinished_work_->total_bytes() + response_bytes); 738 unfinished_work_->total_bytes() + response_bytes);
697 unfinished_work_->set_network_bytes( 739 unfinished_work_->set_network_bytes(
698 unfinished_work_->network_bytes() + network_response_bytes); 740 unfinished_work_->network_bytes() + network_response_bytes);
741
742 if (!IsQuotaTimeExpired(quota_, base::Time::Now())) {
743 int64_t remaining =
744 static_cast<int64_t>(quota_.remaining()) - network_response_bytes;
sclittle 2016/09/22 21:36:55 nit: Instead of doing all this casting from unsign
Raj 2016/09/23 01:32:41 Done.
745 if (remaining < 0)
746 remaining = 0;
747 quota_.set_remaining(static_cast<uint64_t>(remaining));
748 db_task_runner_->PostTask(
749 FROM_HERE,
750 base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_));
751 }
699 } 752 }
700 753
701 } // namespace precache 754 } // namespace precache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698