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

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

Issue 2335913002: Add daily quota for precache (Closed)
Patch Set: minor fix 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
207 } // namespace 217 } // namespace
208 218
209 PrecacheFetcher::Fetcher::Fetcher( 219 PrecacheFetcher::Fetcher::Fetcher(
210 net::URLRequestContextGetter* request_context, 220 net::URLRequestContextGetter* request_context,
211 const GURL& url, 221 const GURL& url,
212 const std::string& referrer, 222 const std::string& referrer,
213 const base::Callback<void(const Fetcher&)>& callback, 223 const base::Callback<void(const Fetcher&)>& callback,
214 bool is_resource_request, 224 bool is_resource_request,
215 size_t max_bytes) 225 size_t max_bytes)
216 : request_context_(request_context), 226 : request_context_(request_context),
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 pool_.Add(base::MakeUnique<Fetcher>( 469 pool_.Add(base::MakeUnique<Fetcher>(
460 request_context_.get(), config_url, std::string(), 470 request_context_.get(), config_url, std::string(),
461 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, AsWeakPtr()), 471 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, AsWeakPtr()),
462 false /* is_resource_request */, std::numeric_limits<int32_t>::max())); 472 false /* is_resource_request */, std::numeric_limits<int32_t>::max()));
463 } 473 }
464 474
465 void PrecacheFetcher::StartNextResourceFetch() { 475 void PrecacheFetcher::StartNextResourceFetch() {
466 DCHECK(unfinished_work_->has_config_settings()); 476 DCHECK(unfinished_work_->has_config_settings());
467 while (!resources_to_fetch_.empty() && pool_.IsAvailable()) { 477 while (!resources_to_fetch_.empty() && pool_.IsAvailable()) {
468 const auto& resource = resources_to_fetch_.front(); 478 const auto& resource = resources_to_fetch_.front();
469 const size_t max_bytes = 479 const size_t max_bytes = std::min(
480 quota_.remaining(),
470 std::min(unfinished_work_->config_settings().max_bytes_per_resource(), 481 std::min(unfinished_work_->config_settings().max_bytes_per_resource(),
471 unfinished_work_->config_settings().max_bytes_total() - 482 unfinished_work_->config_settings().max_bytes_total() -
472 unfinished_work_->total_bytes()); 483 unfinished_work_->total_bytes()));
473 VLOG(3) << "Fetching " << resource.first << " " << resource.second; 484 VLOG(3) << "Fetching " << resource.first << " " << resource.second;
474 pool_.Add(base::MakeUnique<Fetcher>( 485 pool_.Add(base::MakeUnique<Fetcher>(
475 request_context_.get(), resource.first, resource.second, 486 request_context_.get(), resource.first, resource.second,
476 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, AsWeakPtr()), 487 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, AsWeakPtr()),
477 true /* is_resource_request */, max_bytes)); 488 true /* is_resource_request */, max_bytes));
478 489
479 resources_to_fetch_.pop_front(); 490 resources_to_fetch_.pop_front();
480 } 491 }
481 } 492 }
482 493
(...skipping 16 matching lines...) Expand all
499 size_t remaining_manifest_urls_to_fetch, 510 size_t remaining_manifest_urls_to_fetch,
500 size_t remaining_resource_urls_to_fetch) { 511 size_t remaining_resource_urls_to_fetch) {
501 RecordCompletionStatistics(*unfinished_work_, 512 RecordCompletionStatistics(*unfinished_work_,
502 remaining_manifest_urls_to_fetch, 513 remaining_manifest_urls_to_fetch,
503 remaining_resource_urls_to_fetch); 514 remaining_resource_urls_to_fetch);
504 precache_delegate_->OnDone(); 515 precache_delegate_->OnDone();
505 } 516 }
506 517
507 void PrecacheFetcher::StartNextFetch() { 518 void PrecacheFetcher::StartNextFetch() {
508 DCHECK(unfinished_work_->has_config_settings()); 519 DCHECK(unfinished_work_->has_config_settings());
509 // If over the precache total size cap, then stop prefetching. 520 DCHECK(base::Time::FromInternalValue(quota_.expiry_time()) >
510 if (unfinished_work_->total_bytes() > 521 base::Time::Now());
511 unfinished_work_->config_settings().max_bytes_total()) { 522
523 // If over the precache total size cap or daily quota, then stop prefetching.
524 if ((unfinished_work_->total_bytes() >
525 unfinished_work_->config_settings().max_bytes_total()) ||
526 quota_.remaining() == 0) {
512 size_t pending_manifests_in_pool = 0; 527 size_t pending_manifests_in_pool = 0;
513 size_t pending_resources_in_pool = 0; 528 size_t pending_resources_in_pool = 0;
514 for (const auto& element_pair : pool_.elements()) { 529 for (const auto& element_pair : pool_.elements()) {
515 const Fetcher* fetcher = element_pair.first; 530 const Fetcher* fetcher = element_pair.first;
516 if (fetcher->is_resource_request()) 531 if (fetcher->is_resource_request())
517 pending_resources_in_pool++; 532 pending_resources_in_pool++;
518 else if (fetcher->url() != config_url_) 533 else if (fetcher->url() != config_url_)
519 pending_manifests_in_pool++; 534 pending_manifests_in_pool++;
520 } 535 }
521 pool_.DeleteAll(); 536 pool_.DeleteAll();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 manifest.manifest_url, "manifest", 630 manifest.manifest_url, "manifest",
616 std::to_string(manifest.manifest_id)); 631 std::to_string(manifest.manifest_id));
617 manifest.manifest_url = net::AppendOrReplaceQueryParameter( 632 manifest.manifest_url = net::AppendOrReplaceQueryParameter(
618 manifest.manifest_url, "used_resources", manifest.used_url_hash); 633 manifest.manifest_url, "used_resources", manifest.used_url_hash);
619 manifest.manifest_url = net::AppendOrReplaceQueryParameter( 634 manifest.manifest_url = net::AppendOrReplaceQueryParameter(
620 manifest.manifest_url, "unused_resources", manifest.unused_url_hash); 635 manifest.manifest_url, "unused_resources", manifest.unused_url_hash);
621 DCHECK(manifest.manifest_url.is_valid()); 636 DCHECK(manifest.manifest_url.is_valid());
622 } 637 }
623 } 638 }
624 unfinished_work_->set_num_manifest_urls(top_hosts_to_fetch_.size()); 639 unfinished_work_->set_num_manifest_urls(top_hosts_to_fetch_.size());
640
641 PostTaskAndReplyWithResult(
642 db_task_runner_.get(), FROM_HERE,
643 base::Bind(&RetrieveQuotaInfo, precache_database_),
644 base::Bind(&PrecacheFetcher::OnQuotaInfoRetrieved, AsWeakPtr()));
645 }
646
647 void PrecacheFetcher::OnQuotaInfoRetrieved(const PrecacheQuota& quota) {
648 quota_ = std::move(quota);
649 if (base::Time::FromInternalValue(quota_.expiry_time()) <=
650 base::Time::Now()) {
651 // This is a new day. Update daily quota, that expires by end of today.
652 quota_.set_expiry_time(
653 (base::Time::Now().LocalMidnight() + base::TimeDelta::FromDays(1))
654 .ToInternalValue());
655 quota_.set_remaining(
656 unfinished_work_->config_settings().daily_quota_total());
657 db_task_runner_->PostTask(
658 FROM_HERE,
659 base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_));
660 }
625 StartNextFetch(); 661 StartNextFetch();
626 } 662 }
627 663
628 ManifestHostInfo::ManifestHostInfo(int64_t manifest_id, 664 ManifestHostInfo::ManifestHostInfo(int64_t manifest_id,
629 const std::string& hostname, 665 const std::string& hostname,
630 const std::string& used_url_hash, 666 const std::string& used_url_hash,
631 const std::string& unused_url_hash) 667 const std::string& unused_url_hash)
632 : manifest_id(manifest_id), 668 : manifest_id(manifest_id),
633 hostname(hostname), 669 hostname(hostname),
634 used_url_hash(used_url_hash), 670 used_url_hash(used_url_hash),
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 // nothing more needs to be done for the resource. 725 // nothing more needs to be done for the resource.
690 StartNextFetch(); 726 StartNextFetch();
691 } 727 }
692 728
693 void PrecacheFetcher::UpdateStats(int64_t response_bytes, 729 void PrecacheFetcher::UpdateStats(int64_t response_bytes,
694 int64_t network_response_bytes) { 730 int64_t network_response_bytes) {
695 unfinished_work_->set_total_bytes( 731 unfinished_work_->set_total_bytes(
696 unfinished_work_->total_bytes() + response_bytes); 732 unfinished_work_->total_bytes() + response_bytes);
697 unfinished_work_->set_network_bytes( 733 unfinished_work_->set_network_bytes(
698 unfinished_work_->network_bytes() + network_response_bytes); 734 unfinished_work_->network_bytes() + network_response_bytes);
735
736 if (base::Time::FromInternalValue(quota_.expiry_time()) > base::Time::Now()) {
737 int64_t remaining =
738 static_cast<int64_t>(quota_.remaining()) - network_response_bytes;
739 if (remaining < 0)
740 remaining = 0;
741 quota_.set_remaining(static_cast<size_t>(remaining));
742 db_task_runner_->PostTask(
743 FROM_HERE,
744 base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_));
745 }
699 } 746 }
700 747
701 } // namespace precache 748 } // namespace precache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698